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