libmultipath: add marginal_pathgroups config option
[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), 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), 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), 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), 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), 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, 1), 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, 1), 0);
273         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
274 }
275
276 static void test_one_group_ignore_marginal8(void **state)
277 {
278         int marginal[] = {1,0,1,0,1,1,0,0};
279         int paths[] = {0,1,2,3,4,5,6,7};
280         int *groups[] = {paths};
281         int group_size[] = {8};
282
283         set_marginal(p8, marginal, 8);
284         mp8.pgpolicyfn = one_group;
285         assert_int_equal(group_paths(&mp8, 0), 0);
286         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
287 }
288
289 static void test_one_group_one_marginal8(void **state)
290 {
291         int marginal[] = {0,0,0,0,0,1,0,0};
292         int group0[] = {0,1,2,3,4,6,7};
293         int group1[] = {5};
294         int *groups[] = {group0, group1};
295         int group_size[] = {7,1};
296         int group_marginal[] = {0,1};
297
298         set_marginal(p8, marginal, 8);
299         mp8.pgpolicyfn = one_group;
300         assert_int_equal(group_paths(&mp8, 1), 0);
301         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
302 }
303
304 static void test_one_path_per_group_same8(void **state)
305 {
306         int paths[] = {0,1,2,3,4,5,6,7};
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         mp8.pgpolicyfn = one_path_per_group;
312         assert_int_equal(group_paths(&mp8, 0), 0);
313         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
314 }
315
316 static void test_one_path_per_group_increasing8(void **state)
317 {
318         int prio[] = {1,2,3,4,5,6,7,8};
319         int paths[] = {7,6,5,4,3,2,1,0};
320         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
321                           &paths[4], &paths[5], &paths[6], &paths[7]};
322         int group_size[] = {1,1,1,1,1,1,1,1};
323
324         set_priority(p8, prio, 8);
325         mp8.pgpolicyfn = one_path_per_group;
326         assert_int_equal(group_paths(&mp8, 0), 0);
327         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
328 }
329
330 static void test_one_path_per_group_decreasing8(void **state)
331 {
332         int prio[] = {8,7,6,5,4,3,2,1};
333         int paths[] = {0,1,2,3,4,5,6,7};
334         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
335                           &paths[4], &paths[5], &paths[6], &paths[7]};
336         int group_size[] = {1,1,1,1,1,1,1,1};
337
338         set_priority(p8, prio, 8);
339         mp8.pgpolicyfn = one_path_per_group;
340         assert_int_equal(group_paths(&mp8, 0), 0);
341         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
342 }
343
344 static void test_one_path_per_group_mixed8(void **state)
345 {
346         int prio[] = {7,1,3,3,5,2,8,2};
347         int paths[] = {6,0,4,2,3,5,7,1};
348         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
349                           &paths[4], &paths[5], &paths[6], &paths[7]};
350         int group_size[] = {1,1,1,1,1,1,1,1};
351
352         set_priority(p8, prio, 8);
353         mp8.pgpolicyfn = one_path_per_group;
354         assert_int_equal(group_paths(&mp8, 0), 0);
355         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
356 }
357
358 static void test_one_path_per_group4(void **state)
359 {
360         int paths[] = {0,1,2,3};
361         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3]};
362         int group_size[] = {1,1,1,1};
363
364         mp4.pgpolicyfn = one_path_per_group;
365         assert_int_equal(group_paths(&mp4, 0), 0);
366         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 4);
367 }
368
369 static void test_one_path_per_group1(void **state)
370 {
371         int paths[] = {0};
372         int *groups[] = {paths};
373         int group_size[] = {1};
374
375         mp1.pgpolicyfn = one_path_per_group;
376         assert_int_equal(group_paths(&mp1, 0), 0);
377         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
378 }
379
380 static void test_one_path_per_group0(void **state)
381 {
382         mp0.pgpolicyfn = one_path_per_group;
383         assert_int_equal(group_paths(&mp0, 0), 0);
384         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
385 }
386
387 static void test_one_path_per_group_null(void **state)
388 {
389         mp_null.pgpolicyfn = one_path_per_group;
390         assert_int_equal(group_paths(&mp_null, 0), 0);
391         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
392 }
393
394 static void test_one_path_per_group_mixed_all_marginal8(void **state)
395 {
396         int prio[] = {7,1,3,3,5,2,8,2};
397         int marginal[] = {1,1,1,1,1,1,1,1};
398         int paths[] = {6,0,4,2,3,5,7,1};
399         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
400                           &paths[4], &paths[5], &paths[6], &paths[7]};
401         int group_size[] = {1,1,1,1,1,1,1,1};
402         int group_marginal[] = {1,1,1,1,1,1,1,1};
403
404         set_priority(p8, prio, 8);
405         set_marginal(p8, marginal, 8);
406         mp8.pgpolicyfn = one_path_per_group;
407         assert_int_equal(group_paths(&mp8, 1), 0);
408         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8);
409 }
410
411 static void test_one_path_per_group_mixed_half_marginal8(void **state)
412 {
413         int prio[] = {7,1,3,3,5,2,8,2};
414         int marginal[] = {0,1,1,0,0,0,1,1};
415         int paths[] = {0,4,3,5,6,2,7,1};
416         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
417                           &paths[4], &paths[5], &paths[6], &paths[7]};
418         int group_size[] = {1,1,1,1,1,1,1,1};
419         int group_marginal[] = {0,0,0,0,1,1,1,1};
420
421         set_priority(p8, prio, 8);
422         set_marginal(p8, marginal, 8);
423         mp8.pgpolicyfn = one_path_per_group;
424         assert_int_equal(group_paths(&mp8, 1), 0);
425         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8);
426 }
427
428 static void test_group_by_prio_same8(void **state)
429 {
430         int paths[] = {0,1,2,3,4,5,6,7};
431         int *groups[] = {paths};
432         int group_size[] = {8};
433
434         mp8.pgpolicyfn = group_by_prio;
435         assert_int_equal(group_paths(&mp8, 0), 0);
436         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
437 }
438
439 static void test_group_by_prio_increasing8(void **state)
440 {
441         int prio[] = {1,2,3,4,5,6,7,8};
442         int paths[] = {7,6,5,4,3,2,1,0};
443         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
444                           &paths[4], &paths[5], &paths[6], &paths[7]};
445         int group_size[] = {1,1,1,1,1,1,1,1};
446
447         set_priority(p8, prio, 8);
448         mp8.pgpolicyfn = group_by_prio;
449         assert_int_equal(group_paths(&mp8, 0), 0);
450         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
451 }
452
453 static void test_group_by_prio_decreasing8(void **state)
454 {
455         int prio[] = {8,7,6,5,4,3,2,1};
456         int paths[] = {0,1,2,3,4,5,6,7};
457         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
458                           &paths[4], &paths[5], &paths[6], &paths[7]};
459         int group_size[] = {1,1,1,1,1,1,1,1};
460
461         set_priority(p8, prio, 8);
462         mp8.pgpolicyfn = group_by_prio;
463         assert_int_equal(group_paths(&mp8, 0), 0);
464         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
465 }
466
467 static void test_group_by_prio_mixed8(void **state)
468 {
469         int prio[] = {7,1,3,3,5,2,8,2};
470         int group0[] = {6};
471         int group1[] = {0};
472         int group2[] = {4};
473         int group3[] = {2,3};
474         int group4[] = {5,7};
475         int group5[] = {1};
476         int *groups[] = {group0, group1, group2, group3,
477                           group4, group5};
478         int group_size[] = {1,1,1,2,2,1};
479
480         set_priority(p8, prio, 8);
481         mp8.pgpolicyfn = group_by_prio;
482         assert_int_equal(group_paths(&mp8, 0), 0);
483         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6);
484 }
485
486 static void test_group_by_prio_mixed_no_marginal8(void **state)
487 {
488         int prio[] = {7,1,3,3,5,2,8,2};
489         int group0[] = {6};
490         int group1[] = {0};
491         int group2[] = {4};
492         int group3[] = {2,3};
493         int group4[] = {5,7};
494         int group5[] = {1};
495         int *groups[] = {group0, group1, group2, group3,
496                           group4, group5};
497         int group_size[] = {1,1,1,2,2,1};
498
499         set_priority(p8, prio, 8);
500         mp8.pgpolicyfn = group_by_prio;
501         assert_int_equal(group_paths(&mp8, 1), 0);
502         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6);
503 }
504
505 static void test_group_by_prio_2_groups8(void **state)
506 {
507         int prio[] = {1,2,2,1,2,1,1,2};
508         int group0[] = {1,2,4,7};
509         int group1[] = {0,3,5,6};
510         int *groups[] = {group0, group1};
511         int group_size[] = {4,4};
512
513         set_priority(p8, prio, 8);
514         mp8.pgpolicyfn = group_by_prio;
515         assert_int_equal(group_paths(&mp8, 0), 0);
516         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2);
517 }
518
519 static void test_group_by_prio_mixed4(void **state)
520 {
521         int prio[] = {2,3,1,3};
522         int group0[] = {1,3};
523         int group1[] = {0};
524         int group2[] = {2};
525         int *groups[] = {group0, group1, group2};
526         int group_size[] = {2,1,1};
527
528         set_priority(p4, prio, 4);
529         mp4.pgpolicyfn = group_by_prio;
530         assert_int_equal(group_paths(&mp4, 0), 0);
531         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3);
532 }
533
534 static void test_group_by_prio_2_groups4(void **state)
535 {
536         int prio[] = {2,1,1,2};
537         int group0[] = {0,3};
538         int group1[] = {1,2};
539         int *groups[] = {group0, group1};
540         int group_size[] = {2,2};
541
542         set_priority(p4, prio, 4);
543         mp4.pgpolicyfn = group_by_prio;
544         assert_int_equal(group_paths(&mp4, 0), 0);
545         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2);
546 }
547
548 static void test_group_by_prio1(void **state)
549 {
550         int paths[] = {0};
551         int *groups[] = {paths};
552         int group_size[] = {1};
553
554         mp1.pgpolicyfn = group_by_prio;
555         assert_int_equal(group_paths(&mp1, 0), 0);
556         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
557 }
558
559 static void test_group_by_prio0(void **state)
560 {
561         mp0.pgpolicyfn = group_by_prio;
562         assert_int_equal(group_paths(&mp0, 0), 0);
563         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
564 }
565
566 static void test_group_by_prio_null(void **state)
567 {
568         mp_null.pgpolicyfn = group_by_prio;
569         assert_int_equal(group_paths(&mp_null, 0), 0);
570         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
571 }
572
573 static void test_group_by_prio_mixed_all_marginal8(void **state)
574 {
575         int prio[] = {7,1,3,3,5,2,8,2};
576         int marginal[] = {1,1,1,1,1,1,1,1};
577         int group0[] = {6};
578         int group1[] = {0};
579         int group2[] = {4};
580         int group3[] = {2,3};
581         int group4[] = {5,7};
582         int group5[] = {1};
583         int *groups[] = {group0, group1, group2, group3,
584                           group4, group5};
585         int group_size[] = {1,1,1,2,2,1};
586         int group_marginal[] = {1,1,1,1,1,1};
587
588         set_priority(p8, prio, 8);
589         set_marginal(p8, marginal, 8);
590         mp8.pgpolicyfn = group_by_prio;
591         assert_int_equal(group_paths(&mp8, 1), 0);
592         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 6);
593 }
594
595 static void test_group_by_prio_mixed_half_marginal8(void **state)
596 {
597         int prio[] = {7,1,3,3,5,2,8,2};
598         int marginal[] = {0,0,0,1,0,1,1,1};
599         int group0[] = {0};
600         int group1[] = {4};
601         int group2[] = {2};
602         int group3[] = {1};
603         int group4[] = {6};
604         int group5[] = {3};
605         int group6[] = {5,7};
606         int *groups[] = {group0, group1, group2, group3,
607                           group4, group5, group6};
608         int group_size[] = {1,1,1,1,1,1,2};
609         int group_marginal[] = {0,0,0,0,1,1,1};
610
611         set_priority(p8, prio, 8);
612         set_marginal(p8, marginal, 8);
613         mp8.pgpolicyfn = group_by_prio;
614         assert_int_equal(group_paths(&mp8, 1), 0);
615         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7);
616 }
617
618 static void test_group_by_prio_mixed_one_marginal8(void **state)
619 {
620         int prio[] = {7,1,3,3,5,2,8,2};
621         int marginal[] = {0,0,0,0,0,1,0,0};
622         int group0[] = {6};
623         int group1[] = {0};
624         int group2[] = {4};
625         int group3[] = {2,3};
626         int group4[] = {7};
627         int group5[] = {1};
628         int group6[] = {5};
629         int *groups[] = {group0, group1, group2, group3,
630                           group4, group5, group6};
631         int group_size[] = {1,1,1,2,1,1,1};
632         int group_marginal[] = {0,0,0,0,0,0,1};
633
634         set_priority(p8, prio, 8);
635         set_marginal(p8, marginal, 8);
636         mp8.pgpolicyfn = group_by_prio;
637         assert_int_equal(group_paths(&mp8, 1), 0);
638         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7);
639 }
640
641 static void test_group_by_node_name_same8(void **state)
642 {
643         char *node_name[] = {"a","a","a","a","a","a","a","a"};
644         int paths[] = {0,1,2,3,4,5,6,7};
645         int *groups[] = {paths};
646         int group_size[] = {8};
647
648         set_tgt_node_name(p8, node_name, 8);
649         mp8.pgpolicyfn = group_by_node_name;
650         assert_int_equal(group_paths(&mp8, 0), 0);
651         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
652 }
653
654 static void test_group_by_node_name_increasing8(void **state)
655 {
656         char *node_name[] = {"a","b","c","d","e","f","g","h"};
657         int prio[] = {1,2,3,4,5,6,7,8};
658         int paths[] = {7,6,5,4,3,2,1,0};
659         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
660                           &paths[4], &paths[5], &paths[6], &paths[7]};
661         int group_size[] = {1,1,1,1,1,1,1,1};
662
663         set_priority(p8, prio, 8);
664         set_tgt_node_name(p8, node_name, 8);
665         mp8.pgpolicyfn = group_by_node_name;
666         assert_int_equal(group_paths(&mp8, 0), 0);
667         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
668 }
669
670 static void test_group_by_node_name_3_groups8(void **state)
671 {
672         char *node_name[] = {"a","b","a","c","b","c","c","a"};
673         int prio[] = {4,1,4,1,1,1,1,4};
674         int group0[] = {0,2,7};
675         int group1[] = {3,5,6};
676         int group2[] = {1,4};
677         int *groups[] = {group0, group1, group2};
678         int group_size[] = {3,3,2};
679
680         set_priority(p8, prio, 8);
681         set_tgt_node_name(p8, node_name, 8);
682         mp8.pgpolicyfn = group_by_node_name;
683         assert_int_equal(group_paths(&mp8, 0), 0);
684         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3);
685 }
686
687 static void test_group_by_node_name_2_groups8(void **state)
688 {
689         char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"};
690         int prio[] = {4,1,2,1,2,2,2,1};
691         int group0[] = {2,4,5,6};
692         int group1[] = {0,1,3,7};
693         int *groups[] = {group0, group1};
694         int group_size[] = {4,4};
695
696         set_priority(p8, prio, 8);
697         set_tgt_node_name(p8, node_name, 8);
698         mp8.pgpolicyfn = group_by_node_name;
699         assert_int_equal(group_paths(&mp8, 0), 0);
700         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2);
701 }
702
703 static void test_group_by_node_name_3_groups4(void **state)
704 {
705         char *node_name[] = {"a","b","c","a"};
706         int prio[] = {3,1,3,1};
707         int group0[] = {2};
708         int group1[] = {0,3};
709         int group2[] = {1};
710         int *groups[] = {group0, group1, group2};
711         int group_size[] = {1,2,1};
712
713         set_priority(p4, prio, 4);
714         set_tgt_node_name(p4, node_name, 4);
715         mp4.pgpolicyfn = group_by_node_name;
716         assert_int_equal(group_paths(&mp4, 0), 0);
717         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3);
718 }
719
720 static void test_group_by_node_name_2_groups4(void **state)
721 {
722         char *node_name[] = {"a","b","b","a"};
723         int prio[] = {2,1,1,2};
724         int group0[] = {0,3};
725         int group1[] = {1,2};
726         int *groups[] = {group0, group1};
727         int group_size[] = {2,2};
728
729         set_priority(p4, prio, 4);
730         set_tgt_node_name(p4, node_name, 4);
731         mp4.pgpolicyfn = group_by_node_name;
732         assert_int_equal(group_paths(&mp4, 0), 0);
733         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2);
734 }
735
736 static void test_group_by_node_name1(void **state)
737 {
738         char *node_name[] = {"a"};
739         int paths[] = {0};
740         int *groups[] = {paths};
741         int group_size[] = {1};
742
743         set_tgt_node_name(p1, node_name, 1);
744         mp1.pgpolicyfn = group_by_node_name;
745         assert_int_equal(group_paths(&mp1,0), 0);
746         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
747 }
748
749 static void test_group_by_node_name0(void **state)
750 {
751         mp0.pgpolicyfn = group_by_node_name;
752         assert_int_equal(group_paths(&mp0, 0), 0);
753         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
754 }
755
756 static void test_group_by_node_name_null(void **state)
757 {
758         mp_null.pgpolicyfn = group_by_node_name;
759         assert_int_equal(group_paths(&mp_null, 0), 0);
760         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
761 }
762
763 static void test_group_by_node_name_2_groups_all_marginal8(void **state)
764 {
765         char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"};
766         int prio[] = {4,1,2,1,2,2,2,1};
767         int marginal[] = {1,1,1,1,1,1,1,1};
768         int group0[] = {2,4,5,6};
769         int group1[] = {0,1,3,7};
770         int *groups[] = {group0, group1};
771         int group_size[] = {4,4};
772         int group_marginal[] = {1,1};
773
774         set_priority(p8, prio, 8);
775         set_marginal(p8, marginal, 8);
776         set_tgt_node_name(p8, node_name, 8);
777         mp8.pgpolicyfn = group_by_node_name;
778         assert_int_equal(group_paths(&mp8, 1), 0);
779         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
780 }
781
782 static void test_group_by_node_name_2_groups_half_marginal8(void **state)
783 {
784         char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"};
785         int prio[] = {4,1,2,1,2,2,2,1};
786         int marginal[] = {1,0,1,1,0,1,0,0};
787         int group0[] = {4,6};
788         int group1[] = {1,7};
789         int group2[] = {0,3};
790         int group3[] = {2,5};
791         int *groups[] = {group0, group1, group2, group3};
792         int group_size[] = {2,2,2,2};
793         int group_marginal[] = {0,0,1,1};
794
795         set_priority(p8, prio, 8);
796         set_marginal(p8, marginal, 8);
797         set_tgt_node_name(p8, node_name, 8);
798         mp8.pgpolicyfn = group_by_node_name;
799         assert_int_equal(group_paths(&mp8, 1), 0);
800         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4);
801 }
802
803 static void test_group_by_serial_same8(void **state)
804 {
805         char *serial[] = {"1","1","1","1","1","1","1","1"};
806         int paths[] = {0,1,2,3,4,5,6,7};
807         int *groups[] = {paths};
808         int group_size[] = {8};
809
810         set_serial(p8, serial, 8);
811         mp8.pgpolicyfn = group_by_serial;
812         assert_int_equal(group_paths(&mp8, 0), 0);
813         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1);
814 }
815
816 static void test_group_by_serial_increasing8(void **state)
817 {
818         char *serial[] = {"1","2","3","4","5","6","7","8"};
819         int prio[] = {1,2,3,4,5,6,7,8};
820         int paths[] = {7,6,5,4,3,2,1,0};
821         int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3],
822                           &paths[4], &paths[5], &paths[6], &paths[7]};
823         int group_size[] = {1,1,1,1,1,1,1,1};
824
825         set_priority(p8, prio, 8);
826         set_serial(p8, serial, 8);
827         mp8.pgpolicyfn = group_by_serial;
828         assert_int_equal(group_paths(&mp8, 0), 0);
829         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8);
830 }
831
832 static void test_group_by_serial_3_groups8(void **state)
833 {
834         char *serial[] = {"1","2","1","3","2","3","2","1"};
835         int prio[] = {4,1,4,3,1,3,1,4};
836         int group0[] = {0,2,7};
837         int group1[] = {3,5};
838         int group2[] = {1,4,6};
839         int *groups[] = {group0, group1, group2};
840         int group_size[] = {3,2,3};
841
842         set_priority(p8, prio, 8);
843         set_serial(p8, serial, 8);
844         mp8.pgpolicyfn = group_by_serial;
845         assert_int_equal(group_paths(&mp8, 0), 0);
846         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3);
847 }
848
849 static void test_group_by_serial_2_groups8(void **state)
850 {
851         char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"};
852         int prio[] = {3,2,2,1,2,2,1,2};
853         int group0[] = {1,4,5,7};
854         int group1[] = {0,2,3,6};
855         int *groups[] = {group0, group1};
856         int group_size[] = {4,4};
857
858         set_priority(p8, prio, 8);
859         set_serial(p8, serial, 8);
860         mp8.pgpolicyfn = group_by_serial;
861         assert_int_equal(group_paths(&mp8, 0), 0);
862         verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2);
863 }
864
865 static void test_group_by_serial_3_groups4(void **state)
866 {
867         char *serial[] = {"1","2","3","2"};
868         int prio[] = {3,1,3,1};
869         int group0[] = {0};
870         int group1[] = {2};
871         int group2[] = {1,3};
872         int *groups[] = {group0, group1, group2};
873         int group_size[] = {1,1,2};
874
875         set_priority(p4, prio, 4);
876         set_serial(p4, serial, 4);
877         mp4.pgpolicyfn = group_by_serial;
878         assert_int_equal(group_paths(&mp4, 0), 0);
879         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3);
880 }
881
882 static void test_group_by_serial_2_groups4(void **state)
883 {
884         char *serial[] = {"1","2","1","2"};
885         int prio[] = {3,1,3,1};
886         int group0[] = {0,2};
887         int group1[] = {1,3};
888         int *groups[] = {group0, group1};
889         int group_size[] = {2,2};
890
891         set_priority(p4, prio, 4);
892         set_serial(p4, serial, 4);
893         mp4.pgpolicyfn = group_by_serial;
894         assert_int_equal(group_paths(&mp4, 0), 0);
895         verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2);
896 }
897
898 static void test_group_by_serial1(void **state)
899 {
900         char *serial[1] = {"1"};
901         int paths[1] = {0};
902         int *groups[1] = {paths};
903         int group_size[1] = {1};
904
905         set_serial(p1, serial, 1);
906         mp1.pgpolicyfn = group_by_serial;
907         assert_int_equal(group_paths(&mp1, 0), 0);
908         verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1);
909 }
910
911 static void test_group_by_serial0(void **state)
912 {
913         mp0.pgpolicyfn = group_by_serial;
914         assert_int_equal(group_paths(&mp0, 0), 0);
915         verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0);
916 }
917
918 static void test_group_by_serial_null(void **state)
919 {
920         mp_null.pgpolicyfn = group_by_serial;
921         assert_int_equal(group_paths(&mp_null, 0), 0);
922         verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0);
923 }
924
925 static void test_group_by_serial_2_groups8_all_marginal8(void **state)
926 {
927         char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"};
928         int marginal[] = {1,1,1,1,1,1,1,1};
929         int prio[] = {3,2,2,1,2,2,1,2};
930         int group0[] = {1,4,5,7};
931         int group1[] = {0,2,3,6};
932         int *groups[] = {group0, group1};
933         int group_size[] = {4,4};
934         int group_marginal[] = {1,1};
935
936         set_priority(p8, prio, 8);
937         set_serial(p8, serial, 8);
938         set_marginal(p8, marginal, 8);
939         mp8.pgpolicyfn = group_by_serial;
940         assert_int_equal(group_paths(&mp8, 1), 0);
941         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2);
942 }
943
944 static void test_group_by_serial_2_groups8_half_marginal8(void **state)
945 {
946         char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"};
947         int marginal[] = {0,0,1,1,1,1,0,0};
948         int prio[] = {3,2,2,1,2,2,1,2};
949         int group0[] = {0,6};
950         int group1[] = {1,7};
951         int group2[] = {4,5};
952         int group3[] = {2,3};
953         int *groups[] = {group0, group1, group2, group3};
954         int group_size[] = {2,2,2,2};
955         int group_marginal[] = {0,0,1,1};
956
957         set_priority(p8, prio, 8);
958         set_serial(p8, serial, 8);
959         set_marginal(p8, marginal, 8);
960         mp8.pgpolicyfn = group_by_serial;
961         assert_int_equal(group_paths(&mp8, 1), 0);
962         verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4);
963 }
964
965 #define setup_test(name, nr) \
966 cmocka_unit_test_setup_teardown(name ## nr, setup ## nr, teardown ## nr)
967
968 int test_pgpolicies(void)
969 {
970         const struct CMUnitTest tests[] = {
971                 setup_test(test_one_group, 8),
972                 setup_test(test_one_group, 4),
973                 setup_test(test_one_group, 1),
974                 setup_test(test_one_group, 0),
975                 setup_test(test_one_group, _null),
976                 setup_test(test_one_group_all_marginal, 8),
977                 setup_test(test_one_group_half_marginal, 8),
978                 setup_test(test_one_group_ignore_marginal, 8),
979                 setup_test(test_one_group_one_marginal, 8),
980                 setup_test(test_one_path_per_group_same, 8),
981                 setup_test(test_one_path_per_group_increasing, 8),
982                 setup_test(test_one_path_per_group_decreasing, 8),
983                 setup_test(test_one_path_per_group_mixed, 8),
984                 setup_test(test_one_path_per_group, 4),
985                 setup_test(test_one_path_per_group, 1),
986                 setup_test(test_one_path_per_group, 0),
987                 setup_test(test_one_path_per_group, _null),
988                 setup_test(test_one_path_per_group_mixed_all_marginal, 8),
989                 setup_test(test_one_path_per_group_mixed_half_marginal, 8),
990                 setup_test(test_group_by_prio_same, 8),
991                 setup_test(test_group_by_prio_increasing, 8),
992                 setup_test(test_group_by_prio_decreasing, 8),
993                 setup_test(test_group_by_prio_mixed, 8),
994                 setup_test(test_group_by_prio_mixed_no_marginal, 8),
995                 setup_test(test_group_by_prio_2_groups, 8),
996                 setup_test(test_group_by_prio_mixed, 4),
997                 setup_test(test_group_by_prio_2_groups, 4),
998                 setup_test(test_group_by_prio, 1),
999                 setup_test(test_group_by_prio, 0),
1000                 setup_test(test_group_by_prio, _null),
1001                 setup_test(test_group_by_prio_mixed_all_marginal, 8),
1002                 setup_test(test_group_by_prio_mixed_half_marginal, 8),
1003                 setup_test(test_group_by_prio_mixed_one_marginal, 8),
1004                 setup_test(test_group_by_node_name_same, 8),
1005                 setup_test(test_group_by_node_name_increasing, 8),
1006                 setup_test(test_group_by_node_name_3_groups, 8),
1007                 setup_test(test_group_by_node_name_2_groups, 8),
1008                 setup_test(test_group_by_node_name_3_groups, 4),
1009                 setup_test(test_group_by_node_name_2_groups, 4),
1010                 setup_test(test_group_by_node_name, 1),
1011                 setup_test(test_group_by_node_name, 0),
1012                 setup_test(test_group_by_node_name, _null),
1013                 setup_test(test_group_by_node_name_2_groups_all_marginal, 8),
1014                 setup_test(test_group_by_node_name_2_groups_half_marginal, 8),
1015                 setup_test(test_group_by_serial_same, 8),
1016                 setup_test(test_group_by_serial_increasing, 8),
1017                 setup_test(test_group_by_serial_3_groups, 8),
1018                 setup_test(test_group_by_serial_2_groups, 8),
1019                 setup_test(test_group_by_serial_3_groups, 4),
1020                 setup_test(test_group_by_serial_2_groups, 4),
1021                 setup_test(test_group_by_serial, 1),
1022                 setup_test(test_group_by_serial, 0),
1023                 setup_test(test_group_by_serial, _null),
1024                 setup_test(test_group_by_serial_2_groups8_all_marginal, 8),
1025                 setup_test(test_group_by_serial_2_groups8_half_marginal, 8),
1026         };
1027         return cmocka_run_group_tests(tests, setup, NULL);
1028 }
1029
1030 int main(void)
1031 {
1032         int ret = 0;
1033
1034         ret += test_pgpolicies();
1035         return ret;
1036 }