ab09f91cce059f71b510fa0e609d69042384e179
[multipath-tools/.git] / tests / pgpolicy.c
1 /*
2  * Copyright (c) 2018 Benjamin Marzinski, Redhat
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include <stdarg.h>
22 #include <stddef.h>
23 #include <setjmp.h>
24 #include <stdlib.h>
25 #include <cmocka.h>
26
27 #include "globals.c"
28 #include "pgpolicies.h"
29
30 struct multipath mp8, mp4, mp1, mp0, mp_null;
31 struct path p8[8], p4[4], p1[1];
32
33
34 static void set_priority(struct path *pp, int *prio, int size)
35 {
36         int i;
37
38         for (i = 0; i < size; i++) {
39                 pp[i].priority = prio[i];
40         }
41 }
42
43 static void set_marginal(struct path *pp, int *marginal, int size)
44 {
45         int i;
46
47         for (i = 0; i < size; i++) {
48                 pp[i].marginal = marginal[i];
49         }
50 }
51
52 static void set_tgt_node_name(struct path *pp, char **tgt_node_name, int size)
53 {
54         int i;
55
56         for (i = 0; i < size; i++) {
57                 strcpy(pp[i].tgt_node_name, tgt_node_name[i]);
58         }
59 }
60
61 static void set_serial(struct path *pp, char **serial, int size)
62 {
63         int i;
64
65         for (i = 0; i < size; i++) {
66                 strcpy(pp[i].serial, serial[i]);
67         }
68 }
69
70 static int setup(void **state)
71 {
72         int i;
73
74         for (i = 0; i < 8; i++) {
75                 sprintf(p8[i].dev, "p8_%d", i);
76                 sprintf(p8[i].dev_t, "8:%d", i);
77                 p8[i].state = PATH_UP;
78         }
79         for (i = 0; i < 4; i++) {
80                 sprintf(p4[i].dev, "p4_%d", i);
81                 sprintf(p4[i].dev_t, "4:%d", i);
82                 p4[i].state = PATH_UP;
83         }
84         sprintf(p1[0].dev, "p1_0");
85         sprintf(p1[0].dev_t, "4:0");
86         p1[0].state = PATH_UP;
87         return 0;
88 }
89
90 static int setupX(struct multipath *mp, struct path *pp, int size)
91 {
92         int i;
93         int prio[8] = {10, 10, 10, 10, 10, 10, 10, 10};
94         int marginal[8] = {0, 0, 0, 0, 0, 0, 0, 0};
95
96         mp->paths = vector_alloc();
97         if (!mp->paths)
98                 return -1;
99         for (i = 0; i < size; i++) {
100                 if (!vector_alloc_slot(mp->paths))
101                         return -1;
102                 vector_set_slot(mp->paths, &pp[i]);
103         }
104         set_priority(pp, prio, size);
105         set_marginal(pp, marginal, size);
106         mp->pgpolicyfn = NULL;
107         return 0;
108 }
109
110 static int setup8(void **state)
111 {
112         return setupX(&mp8, p8, 8);
113 }
114
115 static int setup4(void **state)
116 {
117         return setupX(&mp4, p4, 4);
118 }
119
120 static int setup1(void **state)
121 {
122         return setupX(&mp1, p1, 1);
123 }
124
125 static int setup0(void **state)
126 {
127         return setupX(&mp0, NULL, 0);
128 }
129
130 static int setup_null(void **state)
131 {
132         return 0;
133 }
134
135 static int teardownX(struct multipath *mp)
136 {
137         free_pgvec(mp->pg, KEEP_PATHS);
138         mp->pg = NULL;
139         return 0;
140 }
141
142 static int teardown8(void **state)
143 {
144         return teardownX(&mp8);
145 }
146
147 static int teardown4(void **state)
148 {
149         return teardownX(&mp4);
150 }
151
152 static int teardown1(void **state)
153 {
154         return teardownX(&mp1);
155 }
156
157 static int teardown0(void **state)
158 {
159         return teardownX(&mp0);
160 }
161
162 static int teardown_null(void **state)
163 {
164         return teardownX(&mp_null);
165 }
166
167 static void
168 verify_pathgroups(struct multipath *mp, struct path *pp, int **groups,
169                   int *group_size, int *marginal, int size)
170 {
171         int i, j;
172         struct pathgroup *pgp;
173
174         assert_null(mp->paths);
175         assert_non_null(mp->pg);
176         assert_int_equal(VECTOR_SIZE(mp->pg), size);
177         for (i = 0; i < size; i++) {
178                 pgp = VECTOR_SLOT(mp->pg, i);
179                 assert_non_null(pgp);
180                 assert_non_null(pgp->paths);
181                 assert_int_equal(VECTOR_SIZE(pgp->paths), group_size[i]);
182                 if (marginal)
183                         assert_int_equal(pgp->marginal, marginal[i]);
184                 else
185                         assert_int_equal(pgp->marginal, 0);
186                 for (j = 0; j < group_size[i]; j++) {
187                         int path_nr = groups[i][j];
188                         struct path *pgp_path = VECTOR_SLOT(pgp->paths, j);
189                         struct path *pp_path = &pp[path_nr];
190                         /* Test names instead of pointers to get a more
191                          * useful error message */
192                         assert_string_equal(pgp_path->dev, pp_path->dev);
193                         /* This test is just a backkup in case the
194                          * something wenth wrong naming the paths */
195                         assert_ptr_equal(pgp_path, pp_path);
196                 }
197         }
198 }
199
200 static void test_one_group8(void **state)
201 {
202         int paths[] = {0,1,2,3,4,5,6,7};
203         int *groups[] = {paths};
204         int group_size[] = {8};
205
206         mp8.pgpolicyfn = one_group;
207         assert_int_equal(group_paths(&mp8), 0);
208         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
209 }
210
211 static void test_one_group4(void **state)
212 {
213         int paths[] = {0,1,2,3};
214         int *groups[] = {paths};
215         int group_size[] = {4};
216
217         mp4.pgpolicyfn = one_group;
218         assert_int_equal(group_paths(&mp4), 0);
219         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 1);
220 }
221
222 static void test_one_group1(void **state)
223 {
224         int paths[] = {0};
225         int *groups[] = {paths};
226         int group_size[] = {1};
227
228         mp1.pgpolicyfn = one_group;
229         assert_int_equal(group_paths(&mp1), 0);
230         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
231 }
232
233 static void test_one_group0(void **state)
234 {
235         mp0.pgpolicyfn = one_group;
236         assert_int_equal(group_paths(&mp0), 0);
237         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
238 }
239
240 static void test_one_group_null(void **state)
241 {
242         mp_null.pgpolicyfn = one_group;
243         assert_int_equal(group_paths(&mp_null), 0);
244         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
245 }
246
247 static void test_one_group_all_marginal8(void **state)
248 {
249         int paths[] = {0,1,2,3,4,5,6,7};
250         int marginal[] = {1,1,1,1,1,1,1,1};
251         int *groups[] = {paths};
252         int group_size[] = {8};
253         int group_marginal[] = {1};
254
255         set_marginal(p8, marginal, 8);
256         mp8.pgpolicyfn = one_group;
257         assert_int_equal(group_paths(&mp8), 0);
258         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 1);
259 }
260
261 static void test_one_group_half_marginal8(void **state)
262 {
263         int marginal[] = {1,0,1,0,1,1,0,0};
264         int group0[] = {1,3,6,7};
265         int group1[] = {0,2,4,5};
266         int *groups[] = {group0, group1};
267         int group_size[] = {4,4};
268         int group_marginal[] = {0,1};
269
270         set_marginal(p8, marginal, 8);
271         mp8.pgpolicyfn = one_group;
272         assert_int_equal(group_paths(&mp8), 0);
273         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
274 }
275
276 static void test_one_group_one_marginal8(void **state)
277 {
278         int marginal[] = {0,0,0,0,0,1,0,0};
279         int group0[] = {0,1,2,3,4,6,7};
280         int group1[] = {5};
281         int *groups[] = {group0, group1};
282         int group_size[] = {7,1};
283         int group_marginal[] = {0,1};
284
285         set_marginal(p8, marginal, 8);
286         mp8.pgpolicyfn = one_group;
287         assert_int_equal(group_paths(&mp8), 0);
288         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
289 }
290
291 static void test_one_path_per_group_same8(void **state)
292 {
293         int paths[] = {0,1,2,3,4,5,6,7};
294         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
295                           &paths[4], &paths[5], &paths[6], &paths[7]};
296         int group_size[] = {1,1,1,1,1,1,1,1};
297
298         mp8.pgpolicyfn = one_path_per_group;
299         assert_int_equal(group_paths(&mp8), 0);
300         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
301 }
302
303 static void test_one_path_per_group_increasing8(void **state)
304 {
305         int prio[] = {1,2,3,4,5,6,7,8};
306         int paths[] = {7,6,5,4,3,2,1,0};
307         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
308                           &paths[4], &paths[5], &paths[6], &paths[7]};
309         int group_size[] = {1,1,1,1,1,1,1,1};
310
311         set_priority(p8, prio, 8);
312         mp8.pgpolicyfn = one_path_per_group;
313         assert_int_equal(group_paths(&mp8), 0);
314         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
315 }
316
317 static void test_one_path_per_group_decreasing8(void **state)
318 {
319         int prio[] = {8,7,6,5,4,3,2,1};
320         int paths[] = {0,1,2,3,4,5,6,7};
321         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
322                           &paths[4], &paths[5], &paths[6], &paths[7]};
323         int group_size[] = {1,1,1,1,1,1,1,1};
324
325         set_priority(p8, prio, 8);
326         mp8.pgpolicyfn = one_path_per_group;
327         assert_int_equal(group_paths(&mp8), 0);
328         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
329 }
330
331 static void test_one_path_per_group_mixed8(void **state)
332 {
333         int prio[] = {7,1,3,3,5,2,8,2};
334         int paths[] = {6,0,4,2,3,5,7,1};
335         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
336                           &paths[4], &paths[5], &paths[6], &paths[7]};
337         int group_size[] = {1,1,1,1,1,1,1,1};
338
339         set_priority(p8, prio, 8);
340         mp8.pgpolicyfn = one_path_per_group;
341         assert_int_equal(group_paths(&mp8), 0);
342         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
343 }
344
345 static void test_one_path_per_group4(void **state)
346 {
347         int paths[] = {0,1,2,3};
348         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3]};
349         int group_size[] = {1,1,1,1};
350
351         mp4.pgpolicyfn = one_path_per_group;
352         assert_int_equal(group_paths(&mp4), 0);
353         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 4);
354 }
355
356 static void test_one_path_per_group1(void **state)
357 {
358         int paths[] = {0};
359         int *groups[] = {paths};
360         int group_size[] = {1};
361
362         mp1.pgpolicyfn = one_path_per_group;
363         assert_int_equal(group_paths(&mp1), 0);
364         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
365 }
366
367 static void test_one_path_per_group0(void **state)
368 {
369         mp0.pgpolicyfn = one_path_per_group;
370         assert_int_equal(group_paths(&mp0), 0);
371         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
372 }
373
374 static void test_one_path_per_group_null(void **state)
375 {
376         mp_null.pgpolicyfn = one_path_per_group;
377         assert_int_equal(group_paths(&mp_null), 0);
378         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
379 }
380
381 static void test_one_path_per_group_mixed_all_marginal8(void **state)
382 {
383         int prio[] = {7,1,3,3,5,2,8,2};
384         int marginal[] = {1,1,1,1,1,1,1,1};
385         int paths[] = {6,0,4,2,3,5,7,1};
386         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
387                           &paths[4], &paths[5], &paths[6], &paths[7]};
388         int group_size[] = {1,1,1,1,1,1,1,1};
389         int group_marginal[] = {1,1,1,1,1,1,1,1};
390
391         set_priority(p8, prio, 8);
392         set_marginal(p8, marginal, 8);
393         mp8.pgpolicyfn = one_path_per_group;
394         assert_int_equal(group_paths(&mp8), 0);
395         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8);
396 }
397
398 static void test_one_path_per_group_mixed_half_marginal8(void **state)
399 {
400         int prio[] = {7,1,3,3,5,2,8,2};
401         int marginal[] = {0,1,1,0,0,0,1,1};
402         int paths[] = {0,4,3,5,6,2,7,1};
403         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
404                           &paths[4], &paths[5], &paths[6], &paths[7]};
405         int group_size[] = {1,1,1,1,1,1,1,1};
406         int group_marginal[] = {0,0,0,0,1,1,1,1};
407
408         set_priority(p8, prio, 8);
409         set_marginal(p8, marginal, 8);
410         mp8.pgpolicyfn = one_path_per_group;
411         assert_int_equal(group_paths(&mp8), 0);
412         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8);
413 }
414
415 static void test_group_by_prio_same8(void **state)
416 {
417         int paths[] = {0,1,2,3,4,5,6,7};
418         int *groups[] = {paths};
419         int group_size[] = {8};
420
421         mp8.pgpolicyfn = group_by_prio;
422         assert_int_equal(group_paths(&mp8), 0);
423         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
424 }
425
426 static void test_group_by_prio_increasing8(void **state)
427 {
428         int prio[] = {1,2,3,4,5,6,7,8};
429         int paths[] = {7,6,5,4,3,2,1,0};
430         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
431                           &paths[4], &paths[5], &paths[6], &paths[7]};
432         int group_size[] = {1,1,1,1,1,1,1,1};
433
434         set_priority(p8, prio, 8);
435         mp8.pgpolicyfn = group_by_prio;
436         assert_int_equal(group_paths(&mp8), 0);
437         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
438 }
439
440 static void test_group_by_prio_decreasing8(void **state)
441 {
442         int prio[] = {8,7,6,5,4,3,2,1};
443         int paths[] = {0,1,2,3,4,5,6,7};
444         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
445                           &paths[4], &paths[5], &paths[6], &paths[7]};
446         int group_size[] = {1,1,1,1,1,1,1,1};
447
448         set_priority(p8, prio, 8);
449         mp8.pgpolicyfn = group_by_prio;
450         assert_int_equal(group_paths(&mp8), 0);
451         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
452 }
453
454 static void test_group_by_prio_mixed8(void **state)
455 {
456         int prio[] = {7,1,3,3,5,2,8,2};
457         int group0[] = {6};
458         int group1[] = {0};
459         int group2[] = {4};
460         int group3[] = {2,3};
461         int group4[] = {5,7};
462         int group5[] = {1};
463         int *groups[] = {group0, group1, group2, group3,
464                           group4, group5};
465         int group_size[] = {1,1,1,2,2,1};
466
467         set_priority(p8, prio, 8);
468         mp8.pgpolicyfn = group_by_prio;
469         assert_int_equal(group_paths(&mp8), 0);
470         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6);
471 }
472
473 static void test_group_by_prio_2_groups8(void **state)
474 {
475         int prio[] = {1,2,2,1,2,1,1,2};
476         int group0[] = {1,2,4,7};
477         int group1[] = {0,3,5,6};
478         int *groups[] = {group0, group1};
479         int group_size[] = {4,4};
480
481         set_priority(p8, prio, 8);
482         mp8.pgpolicyfn = group_by_prio;
483         assert_int_equal(group_paths(&mp8), 0);
484         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2);
485 }
486
487 static void test_group_by_prio_mixed4(void **state)
488 {
489         int prio[] = {2,3,1,3};
490         int group0[] = {1,3};
491         int group1[] = {0};
492         int group2[] = {2};
493         int *groups[] = {group0, group1, group2};
494         int group_size[] = {2,1,1};
495
496         set_priority(p4, prio, 4);
497         mp4.pgpolicyfn = group_by_prio;
498         assert_int_equal(group_paths(&mp4), 0);
499         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3);
500 }
501
502 static void test_group_by_prio_2_groups4(void **state)
503 {
504         int prio[] = {2,1,1,2};
505         int group0[] = {0,3};
506         int group1[] = {1,2};
507         int *groups[] = {group0, group1};
508         int group_size[] = {2,2};
509
510         set_priority(p4, prio, 4);
511         mp4.pgpolicyfn = group_by_prio;
512         assert_int_equal(group_paths(&mp4), 0);
513         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2);
514 }
515
516 static void test_group_by_prio1(void **state)
517 {
518         int paths[] = {0};
519         int *groups[] = {paths};
520         int group_size[] = {1};
521
522         mp1.pgpolicyfn = group_by_prio;
523         assert_int_equal(group_paths(&mp1), 0);
524         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
525 }
526
527 static void test_group_by_prio0(void **state)
528 {
529         mp0.pgpolicyfn = group_by_prio;
530         assert_int_equal(group_paths(&mp0), 0);
531         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
532 }
533
534 static void test_group_by_prio_null(void **state)
535 {
536         mp_null.pgpolicyfn = group_by_prio;
537         assert_int_equal(group_paths(&mp_null), 0);
538         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
539 }
540
541 static void test_group_by_prio_mixed_all_marginal8(void **state)
542 {
543         int prio[] = {7,1,3,3,5,2,8,2};
544         int marginal[] = {1,1,1,1,1,1,1,1};
545         int group0[] = {6};
546         int group1[] = {0};
547         int group2[] = {4};
548         int group3[] = {2,3};
549         int group4[] = {5,7};
550         int group5[] = {1};
551         int *groups[] = {group0, group1, group2, group3,
552                           group4, group5};
553         int group_size[] = {1,1,1,2,2,1};
554         int group_marginal[] = {1,1,1,1,1,1};
555
556         set_priority(p8, prio, 8);
557         set_marginal(p8, marginal, 8);
558         mp8.pgpolicyfn = group_by_prio;
559         assert_int_equal(group_paths(&mp8), 0);
560         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 6);
561 }
562
563 static void test_group_by_prio_mixed_half_marginal8(void **state)
564 {
565         int prio[] = {7,1,3,3,5,2,8,2};
566         int marginal[] = {0,0,0,1,0,1,1,1};
567         int group0[] = {0};
568         int group1[] = {4};
569         int group2[] = {2};
570         int group3[] = {1};
571         int group4[] = {6};
572         int group5[] = {3};
573         int group6[] = {5,7};
574         int *groups[] = {group0, group1, group2, group3,
575                           group4, group5, group6};
576         int group_size[] = {1,1,1,1,1,1,2};
577         int group_marginal[] = {0,0,0,0,1,1,1};
578
579         set_priority(p8, prio, 8);
580         set_marginal(p8, marginal, 8);
581         mp8.pgpolicyfn = group_by_prio;
582         assert_int_equal(group_paths(&mp8), 0);
583         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7);
584 }
585
586 static void test_group_by_prio_mixed_one_marginal8(void **state)
587 {
588         int prio[] = {7,1,3,3,5,2,8,2};
589         int marginal[] = {0,0,0,0,0,1,0,0};
590         int group0[] = {6};
591         int group1[] = {0};
592         int group2[] = {4};
593         int group3[] = {2,3};
594         int group4[] = {7};
595         int group5[] = {1};
596         int group6[] = {5};
597         int *groups[] = {group0, group1, group2, group3,
598                           group4, group5, group6};
599         int group_size[] = {1,1,1,2,1,1,1};
600         int group_marginal[] = {0,0,0,0,0,0,1};
601
602         set_priority(p8, prio, 8);
603         set_marginal(p8, marginal, 8);
604         mp8.pgpolicyfn = group_by_prio;
605         assert_int_equal(group_paths(&mp8), 0);
606         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7);
607 }
608
609 static void test_group_by_node_name_same8(void **state)
610 {
611         char *node_name[] = {"a","a","a","a","a","a","a","a"};
612         int paths[] = {0,1,2,3,4,5,6,7};
613         int *groups[] = {paths};
614         int group_size[] = {8};
615
616         set_tgt_node_name(p8, node_name, 8);
617         mp8.pgpolicyfn = group_by_node_name;
618         assert_int_equal(group_paths(&mp8), 0);
619         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
620 }
621
622 static void test_group_by_node_name_increasing8(void **state)
623 {
624         char *node_name[] = {"a","b","c","d","e","f","g","h"};
625         int prio[] = {1,2,3,4,5,6,7,8};
626         int paths[] = {7,6,5,4,3,2,1,0};
627         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
628                           &paths[4], &paths[5], &paths[6], &paths[7]};
629         int group_size[] = {1,1,1,1,1,1,1,1};
630
631         set_priority(p8, prio, 8);
632         set_tgt_node_name(p8, node_name, 8);
633         mp8.pgpolicyfn = group_by_node_name;
634         assert_int_equal(group_paths(&mp8), 0);
635         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
636 }
637
638 static void test_group_by_node_name_3_groups8(void **state)
639 {
640         char *node_name[] = {"a","b","a","c","b","c","c","a"};
641         int prio[] = {4,1,4,1,1,1,1,4};
642         int group0[] = {0,2,7};
643         int group1[] = {3,5,6};
644         int group2[] = {1,4};
645         int *groups[] = {group0, group1, group2};
646         int group_size[] = {3,3,2};
647
648         set_priority(p8, prio, 8);
649         set_tgt_node_name(p8, node_name, 8);
650         mp8.pgpolicyfn = group_by_node_name;
651         assert_int_equal(group_paths(&mp8), 0);
652         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3);
653 }
654
655 static void test_group_by_node_name_2_groups8(void **state)
656 {
657         char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"};
658         int prio[] = {4,1,2,1,2,2,2,1};
659         int group0[] = {2,4,5,6};
660         int group1[] = {0,1,3,7};
661         int *groups[] = {group0, group1};
662         int group_size[] = {4,4};
663
664         set_priority(p8, prio, 8);
665         set_tgt_node_name(p8, node_name, 8);
666         mp8.pgpolicyfn = group_by_node_name;
667         assert_int_equal(group_paths(&mp8), 0);
668         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2);
669 }
670
671 static void test_group_by_node_name_3_groups4(void **state)
672 {
673         char *node_name[] = {"a","b","c","a"};
674         int prio[] = {3,1,3,1};
675         int group0[] = {2};
676         int group1[] = {0,3};
677         int group2[] = {1};
678         int *groups[] = {group0, group1, group2};
679         int group_size[] = {1,2,1};
680
681         set_priority(p4, prio, 4);
682         set_tgt_node_name(p4, node_name, 4);
683         mp4.pgpolicyfn = group_by_node_name;
684         assert_int_equal(group_paths(&mp4), 0);
685         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3);
686 }
687
688 static void test_group_by_node_name_2_groups4(void **state)
689 {
690         char *node_name[] = {"a","b","b","a"};
691         int prio[] = {2,1,1,2};
692         int group0[] = {0,3};
693         int group1[] = {1,2};
694         int *groups[] = {group0, group1};
695         int group_size[] = {2,2};
696
697         set_priority(p4, prio, 4);
698         set_tgt_node_name(p4, node_name, 4);
699         mp4.pgpolicyfn = group_by_node_name;
700         assert_int_equal(group_paths(&mp4), 0);
701         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2);
702 }
703
704 static void test_group_by_node_name1(void **state)
705 {
706         char *node_name[] = {"a"};
707         int paths[] = {0};
708         int *groups[] = {paths};
709         int group_size[] = {1};
710
711         set_tgt_node_name(p1, node_name, 1);
712         mp1.pgpolicyfn = group_by_node_name;
713         assert_int_equal(group_paths(&mp1), 0);
714         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
715 }
716
717 static void test_group_by_node_name0(void **state)
718 {
719         mp0.pgpolicyfn = group_by_node_name;
720         assert_int_equal(group_paths(&mp0), 0);
721         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
722 }
723
724 static void test_group_by_node_name_null(void **state)
725 {
726         mp_null.pgpolicyfn = group_by_node_name;
727         assert_int_equal(group_paths(&mp_null), 0);
728         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
729 }
730
731 static void test_group_by_node_name_2_groups_all_marginal8(void **state)
732 {
733         char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"};
734         int prio[] = {4,1,2,1,2,2,2,1};
735         int marginal[] = {1,1,1,1,1,1,1,1};
736         int group0[] = {2,4,5,6};
737         int group1[] = {0,1,3,7};
738         int *groups[] = {group0, group1};
739         int group_size[] = {4,4};
740         int group_marginal[] = {1,1};
741
742         set_priority(p8, prio, 8);
743         set_marginal(p8, marginal, 8);
744         set_tgt_node_name(p8, node_name, 8);
745         mp8.pgpolicyfn = group_by_node_name;
746         assert_int_equal(group_paths(&mp8), 0);
747         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
748 }
749
750 static void test_group_by_node_name_2_groups_half_marginal8(void **state)
751 {
752         char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"};
753         int prio[] = {4,1,2,1,2,2,2,1};
754         int marginal[] = {1,0,1,1,0,1,0,0};
755         int group0[] = {4,6};
756         int group1[] = {1,7};
757         int group2[] = {0,3};
758         int group3[] = {2,5};
759         int *groups[] = {group0, group1, group2, group3};
760         int group_size[] = {2,2,2,2};
761         int group_marginal[] = {0,0,1,1};
762
763         set_priority(p8, prio, 8);
764         set_marginal(p8, marginal, 8);
765         set_tgt_node_name(p8, node_name, 8);
766         mp8.pgpolicyfn = group_by_node_name;
767         assert_int_equal(group_paths(&mp8), 0);
768         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4);
769 }
770
771 static void test_group_by_serial_same8(void **state)
772 {
773         char *serial[] = {"1","1","1","1","1","1","1","1"};
774         int paths[] = {0,1,2,3,4,5,6,7};
775         int *groups[] = {paths};
776         int group_size[] = {8};
777
778         set_serial(p8, serial, 8);
779         mp8.pgpolicyfn = group_by_serial;
780         assert_int_equal(group_paths(&mp8), 0);
781         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
782 }
783
784 static void test_group_by_serial_increasing8(void **state)
785 {
786         char *serial[] = {"1","2","3","4","5","6","7","8"};
787         int prio[] = {1,2,3,4,5,6,7,8};
788         int paths[] = {7,6,5,4,3,2,1,0};
789         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
790                           &paths[4], &paths[5], &paths[6], &paths[7]};
791         int group_size[] = {1,1,1,1,1,1,1,1};
792
793         set_priority(p8, prio, 8);
794         set_serial(p8, serial, 8);
795         mp8.pgpolicyfn = group_by_serial;
796         assert_int_equal(group_paths(&mp8), 0);
797         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
798 }
799
800 static void test_group_by_serial_3_groups8(void **state)
801 {
802         char *serial[] = {"1","2","1","3","2","3","2","1"};
803         int prio[] = {4,1,4,3,1,3,1,4};
804         int group0[] = {0,2,7};
805         int group1[] = {3,5};
806         int group2[] = {1,4,6};
807         int *groups[] = {group0, group1, group2};
808         int group_size[] = {3,2,3};
809
810         set_priority(p8, prio, 8);
811         set_serial(p8, serial, 8);
812         mp8.pgpolicyfn = group_by_serial;
813         assert_int_equal(group_paths(&mp8), 0);
814         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3);
815 }
816
817 static void test_group_by_serial_2_groups8(void **state)
818 {
819         char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"};
820         int prio[] = {3,2,2,1,2,2,1,2};
821         int group0[] = {1,4,5,7};
822         int group1[] = {0,2,3,6};
823         int *groups[] = {group0, group1};
824         int group_size[] = {4,4};
825
826         set_priority(p8, prio, 8);
827         set_serial(p8, serial, 8);
828         mp8.pgpolicyfn = group_by_serial;
829         assert_int_equal(group_paths(&mp8), 0);
830         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2);
831 }
832
833 static void test_group_by_serial_3_groups4(void **state)
834 {
835         char *serial[] = {"1","2","3","2"};
836         int prio[] = {3,1,3,1};
837         int group0[] = {0};
838         int group1[] = {2};
839         int group2[] = {1,3};
840         int *groups[] = {group0, group1, group2};
841         int group_size[] = {1,1,2};
842
843         set_priority(p4, prio, 4);
844         set_serial(p4, serial, 4);
845         mp4.pgpolicyfn = group_by_serial;
846         assert_int_equal(group_paths(&mp4), 0);
847         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3);
848 }
849
850 static void test_group_by_serial_2_groups4(void **state)
851 {
852         char *serial[] = {"1","2","1","2"};
853         int prio[] = {3,1,3,1};
854         int group0[] = {0,2};
855         int group1[] = {1,3};
856         int *groups[] = {group0, group1};
857         int group_size[] = {2,2};
858
859         set_priority(p4, prio, 4);
860         set_serial(p4, serial, 4);
861         mp4.pgpolicyfn = group_by_serial;
862         assert_int_equal(group_paths(&mp4), 0);
863         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2);
864 }
865
866 static void test_group_by_serial1(void **state)
867 {
868         char *serial[1] = {"1"};
869         int paths[1] = {0};
870         int *groups[1] = {paths};
871         int group_size[1] = {1};
872
873         set_serial(p1, serial, 1);
874         mp1.pgpolicyfn = group_by_serial;
875         assert_int_equal(group_paths(&mp1), 0);
876         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
877 }
878
879 static void test_group_by_serial0(void **state)
880 {
881         mp0.pgpolicyfn = group_by_serial;
882         assert_int_equal(group_paths(&mp0), 0);
883         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
884 }
885
886 static void test_group_by_serial_null(void **state)
887 {
888         mp_null.pgpolicyfn = group_by_serial;
889         assert_int_equal(group_paths(&mp_null), 0);
890         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
891 }
892
893 static void test_group_by_serial_2_groups8_all_marginal8(void **state)
894 {
895         char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"};
896         int marginal[] = {1,1,1,1,1,1,1,1};
897         int prio[] = {3,2,2,1,2,2,1,2};
898         int group0[] = {1,4,5,7};
899         int group1[] = {0,2,3,6};
900         int *groups[] = {group0, group1};
901         int group_size[] = {4,4};
902         int group_marginal[] = {1,1};
903
904         set_priority(p8, prio, 8);
905         set_serial(p8, serial, 8);
906         set_marginal(p8, marginal, 8);
907         mp8.pgpolicyfn = group_by_serial;
908         assert_int_equal(group_paths(&mp8), 0);
909         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
910 }
911
912 static void test_group_by_serial_2_groups8_half_marginal8(void **state)
913 {
914         char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"};
915         int marginal[] = {0,0,1,1,1,1,0,0};
916         int prio[] = {3,2,2,1,2,2,1,2};
917         int group0[] = {0,6};
918         int group1[] = {1,7};
919         int group2[] = {4,5};
920         int group3[] = {2,3};
921         int *groups[] = {group0, group1, group2, group3};
922         int group_size[] = {2,2,2,2};
923         int group_marginal[] = {0,0,1,1};
924
925         set_priority(p8, prio, 8);
926         set_serial(p8, serial, 8);
927         set_marginal(p8, marginal, 8);
928         mp8.pgpolicyfn = group_by_serial;
929         assert_int_equal(group_paths(&mp8), 0);
930         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4);
931 }
932
933 #define setup_test(name, nr) \
934 cmocka_unit_test_setup_teardown(name ## nr, setup ## nr, teardown ## nr)
935
936 int test_pgpolicies(void)
937 {
938         const struct CMUnitTest tests[] = {
939                 setup_test(test_one_group, 8),
940                 setup_test(test_one_group, 4),
941                 setup_test(test_one_group, 1),
942                 setup_test(test_one_group, 0),
943                 setup_test(test_one_group, _null),
944                 setup_test(test_one_group_all_marginal, 8),
945                 setup_test(test_one_group_half_marginal, 8),
946                 setup_test(test_one_group_one_marginal, 8),
947                 setup_test(test_one_path_per_group_same, 8),
948                 setup_test(test_one_path_per_group_increasing, 8),
949                 setup_test(test_one_path_per_group_decreasing, 8),
950                 setup_test(test_one_path_per_group_mixed, 8),
951                 setup_test(test_one_path_per_group, 4),
952                 setup_test(test_one_path_per_group, 1),
953                 setup_test(test_one_path_per_group, 0),
954                 setup_test(test_one_path_per_group, _null),
955                 setup_test(test_one_path_per_group_mixed_all_marginal, 8),
956                 setup_test(test_one_path_per_group_mixed_half_marginal, 8),
957                 setup_test(test_group_by_prio_same, 8),
958                 setup_test(test_group_by_prio_increasing, 8),
959                 setup_test(test_group_by_prio_decreasing, 8),
960                 setup_test(test_group_by_prio_mixed, 8),
961                 setup_test(test_group_by_prio_2_groups, 8),
962                 setup_test(test_group_by_prio_mixed, 4),
963                 setup_test(test_group_by_prio_2_groups, 4),
964                 setup_test(test_group_by_prio, 1),
965                 setup_test(test_group_by_prio, 0),
966                 setup_test(test_group_by_prio, _null),
967                 setup_test(test_group_by_prio_mixed_all_marginal, 8),
968                 setup_test(test_group_by_prio_mixed_half_marginal, 8),
969                 setup_test(test_group_by_prio_mixed_one_marginal, 8),
970                 setup_test(test_group_by_node_name_same, 8),
971                 setup_test(test_group_by_node_name_increasing, 8),
972                 setup_test(test_group_by_node_name_3_groups, 8),
973                 setup_test(test_group_by_node_name_2_groups, 8),
974                 setup_test(test_group_by_node_name_3_groups, 4),
975                 setup_test(test_group_by_node_name_2_groups, 4),
976                 setup_test(test_group_by_node_name, 1),
977                 setup_test(test_group_by_node_name, 0),
978                 setup_test(test_group_by_node_name, _null),
979                 setup_test(test_group_by_node_name_2_groups_all_marginal, 8),
980                 setup_test(test_group_by_node_name_2_groups_half_marginal, 8),
981                 setup_test(test_group_by_serial_same, 8),
982                 setup_test(test_group_by_serial_increasing, 8),
983                 setup_test(test_group_by_serial_3_groups, 8),
984                 setup_test(test_group_by_serial_2_groups, 8),
985                 setup_test(test_group_by_serial_3_groups, 4),
986                 setup_test(test_group_by_serial_2_groups, 4),
987                 setup_test(test_group_by_serial, 1),
988                 setup_test(test_group_by_serial, 0),
989                 setup_test(test_group_by_serial, _null),
990                 setup_test(test_group_by_serial_2_groups8_all_marginal, 8),
991                 setup_test(test_group_by_serial_2_groups8_half_marginal, 8),
992         };
993         return cmocka_run_group_tests(tests, setup, NULL);
994 }
995
996 int main(void)
997 {
998         int ret = 0;
999
1000         ret += test_pgpolicies();
1001         return ret;
1002 }