/* * Copyright (c) 2018 Benjamin Marzinski, Redhat * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include #include "globals.c" #include "pgpolicies.h" struct multipath mp8, mp4, mp1, mp0, mp_null; struct path p8[8], p4[4], p1[1]; static void set_priority(struct path *pp, int *prio, int size) { int i; for (i = 0; i < size; i++) { pp[i].priority = prio[i]; } } static void set_marginal(struct path *pp, int *marginal, int size) { int i; for (i = 0; i < size; i++) { pp[i].marginal = marginal[i]; } } static void set_tgt_node_name(struct path *pp, char **tgt_node_name, int size) { int i; for (i = 0; i < size; i++) { strcpy(pp[i].tgt_node_name, tgt_node_name[i]); } } static void set_serial(struct path *pp, char **serial, int size) { int i; for (i = 0; i < size; i++) { strcpy(pp[i].serial, serial[i]); } } static int setup(void **state) { int i; for (i = 0; i < 8; i++) { sprintf(p8[i].dev, "p8_%d", i); sprintf(p8[i].dev_t, "8:%d", i); p8[i].state = PATH_UP; } for (i = 0; i < 4; i++) { sprintf(p4[i].dev, "p4_%d", i); sprintf(p4[i].dev_t, "4:%d", i); p4[i].state = PATH_UP; } sprintf(p1[0].dev, "p1_0"); sprintf(p1[0].dev_t, "4:0"); p1[0].state = PATH_UP; return 0; } static int setupX(struct multipath *mp, struct path *pp, int size) { int i; int prio[8] = {10, 10, 10, 10, 10, 10, 10, 10}; int marginal[8] = {0, 0, 0, 0, 0, 0, 0, 0}; mp->paths = vector_alloc(); if (!mp->paths) return -1; for (i = 0; i < size; i++) { if (!vector_alloc_slot(mp->paths)) return -1; vector_set_slot(mp->paths, &pp[i]); } set_priority(pp, prio, size); set_marginal(pp, marginal, size); mp->pgpolicyfn = NULL; return 0; } static int setup8(void **state) { return setupX(&mp8, p8, 8); } static int setup4(void **state) { return setupX(&mp4, p4, 4); } static int setup1(void **state) { return setupX(&mp1, p1, 1); } static int setup0(void **state) { return setupX(&mp0, NULL, 0); } static int setup_null(void **state) { return 0; } static int teardownX(struct multipath *mp) { free_pgvec(mp->pg, KEEP_PATHS); mp->pg = NULL; return 0; } static int teardown8(void **state) { return teardownX(&mp8); } static int teardown4(void **state) { return teardownX(&mp4); } static int teardown1(void **state) { return teardownX(&mp1); } static int teardown0(void **state) { return teardownX(&mp0); } static int teardown_null(void **state) { return teardownX(&mp_null); } static void verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, int *group_size, int *marginal, int size) { int i, j; struct pathgroup *pgp; assert_null(mp->paths); assert_non_null(mp->pg); assert_int_equal(VECTOR_SIZE(mp->pg), size); for (i = 0; i < size; i++) { pgp = VECTOR_SLOT(mp->pg, i); assert_non_null(pgp); assert_non_null(pgp->paths); assert_int_equal(VECTOR_SIZE(pgp->paths), group_size[i]); if (marginal) assert_int_equal(pgp->marginal, marginal[i]); else assert_int_equal(pgp->marginal, 0); for (j = 0; j < group_size[i]; j++) { int path_nr = groups[i][j]; struct path *pgp_path = VECTOR_SLOT(pgp->paths, j); struct path *pp_path = &pp[path_nr]; /* Test names instead of pointers to get a more * useful error message */ assert_string_equal(pgp_path->dev, pp_path->dev); /* This test is just a backkup in case the * something wenth wrong naming the paths */ assert_ptr_equal(pgp_path, pp_path); } } } static void test_one_group8(void **state) { int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {paths}; int group_size[] = {8}; mp8.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); } static void test_one_group4(void **state) { int paths[] = {0,1,2,3}; int *groups[] = {paths}; int group_size[] = {4}; mp4.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 1); } static void test_one_group1(void **state) { int paths[] = {0}; int *groups[] = {paths}; int group_size[] = {1}; mp1.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp1, 0), 0); verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); } static void test_one_group0(void **state) { mp0.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp0, 0), 0); verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); } static void test_one_group_null(void **state) { mp_null.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp_null, 0), 0); verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); } static void test_one_group_all_marginal8(void **state) { int paths[] = {0,1,2,3,4,5,6,7}; int marginal[] = {1,1,1,1,1,1,1,1}; int *groups[] = {paths}; int group_size[] = {8}; int group_marginal[] = {1}; set_marginal(p8, marginal, 8); mp8.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 1); } static void test_one_group_half_marginal8(void **state) { int marginal[] = {1,0,1,0,1,1,0,0}; int group0[] = {1,3,6,7}; int group1[] = {0,2,4,5}; int *groups[] = {group0, group1}; int group_size[] = {4,4}; int group_marginal[] = {0,1}; set_marginal(p8, marginal, 8); mp8.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); } static void test_one_group_ignore_marginal8(void **state) { int marginal[] = {1,0,1,0,1,1,0,0}; int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {paths}; int group_size[] = {8}; set_marginal(p8, marginal, 8); mp8.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); } static void test_one_group_one_marginal8(void **state) { int marginal[] = {0,0,0,0,0,1,0,0}; int group0[] = {0,1,2,3,4,6,7}; int group1[] = {5}; int *groups[] = {group0, group1}; int group_size[] = {7,1}; int group_marginal[] = {0,1}; set_marginal(p8, marginal, 8); mp8.pgpolicyfn = one_group; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); } static void test_one_path_per_group_same8(void **state) { int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; mp8.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_one_path_per_group_increasing8(void **state) { int prio[] = {1,2,3,4,5,6,7,8}; int paths[] = {7,6,5,4,3,2,1,0}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_one_path_per_group_decreasing8(void **state) { int prio[] = {8,7,6,5,4,3,2,1}; int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_one_path_per_group_mixed8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int paths[] = {6,0,4,2,3,5,7,1}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_one_path_per_group4(void **state) { int paths[] = {0,1,2,3}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3]}; int group_size[] = {1,1,1,1}; mp4.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 4); } static void test_one_path_per_group1(void **state) { int paths[] = {0}; int *groups[] = {paths}; int group_size[] = {1}; mp1.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp1, 0), 0); verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); } static void test_one_path_per_group0(void **state) { mp0.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp0, 0), 0); verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); } static void test_one_path_per_group_null(void **state) { mp_null.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp_null, 0), 0); verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); } static void test_one_path_per_group_mixed_all_marginal8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int marginal[] = {1,1,1,1,1,1,1,1}; int paths[] = {6,0,4,2,3,5,7,1}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; int group_marginal[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8); } static void test_one_path_per_group_mixed_half_marginal8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int marginal[] = {0,1,1,0,0,0,1,1}; int paths[] = {0,4,3,5,6,2,7,1}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; int group_marginal[] = {0,0,0,0,1,1,1,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = one_path_per_group; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8); } static void test_group_by_prio_same8(void **state) { int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {paths}; int group_size[] = {8}; mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); } static void test_group_by_prio_increasing8(void **state) { int prio[] = {1,2,3,4,5,6,7,8}; int paths[] = {7,6,5,4,3,2,1,0}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_group_by_prio_decreasing8(void **state) { int prio[] = {8,7,6,5,4,3,2,1}; int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_group_by_prio_mixed8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int group0[] = {6}; int group1[] = {0}; int group2[] = {4}; int group3[] = {2,3}; int group4[] = {5,7}; int group5[] = {1}; int *groups[] = {group0, group1, group2, group3, group4, group5}; int group_size[] = {1,1,1,2,2,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6); } static void test_group_by_prio_mixed_no_marginal8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int group0[] = {6}; int group1[] = {0}; int group2[] = {4}; int group3[] = {2,3}; int group4[] = {5,7}; int group5[] = {1}; int *groups[] = {group0, group1, group2, group3, group4, group5}; int group_size[] = {1,1,1,2,2,1}; set_priority(p8, prio, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6); } static void test_group_by_prio_2_groups8(void **state) { int prio[] = {1,2,2,1,2,1,1,2}; int group0[] = {1,2,4,7}; int group1[] = {0,3,5,6}; int *groups[] = {group0, group1}; int group_size[] = {4,4}; set_priority(p8, prio, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); } static void test_group_by_prio_mixed4(void **state) { int prio[] = {2,3,1,3}; int group0[] = {1,3}; int group1[] = {0}; int group2[] = {2}; int *groups[] = {group0, group1, group2}; int group_size[] = {2,1,1}; set_priority(p4, prio, 4); mp4.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); } static void test_group_by_prio_2_groups4(void **state) { int prio[] = {2,1,1,2}; int group0[] = {0,3}; int group1[] = {1,2}; int *groups[] = {group0, group1}; int group_size[] = {2,2}; set_priority(p4, prio, 4); mp4.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); } static void test_group_by_prio1(void **state) { int paths[] = {0}; int *groups[] = {paths}; int group_size[] = {1}; mp1.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp1, 0), 0); verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); } static void test_group_by_prio0(void **state) { mp0.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp0, 0), 0); verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); } static void test_group_by_prio_null(void **state) { mp_null.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp_null, 0), 0); verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); } static void test_group_by_prio_mixed_all_marginal8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int marginal[] = {1,1,1,1,1,1,1,1}; int group0[] = {6}; int group1[] = {0}; int group2[] = {4}; int group3[] = {2,3}; int group4[] = {5,7}; int group5[] = {1}; int *groups[] = {group0, group1, group2, group3, group4, group5}; int group_size[] = {1,1,1,2,2,1}; int group_marginal[] = {1,1,1,1,1,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 6); } static void test_group_by_prio_mixed_half_marginal8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int marginal[] = {0,0,0,1,0,1,1,1}; int group0[] = {0}; int group1[] = {4}; int group2[] = {2}; int group3[] = {1}; int group4[] = {6}; int group5[] = {3}; int group6[] = {5,7}; int *groups[] = {group0, group1, group2, group3, group4, group5, group6}; int group_size[] = {1,1,1,1,1,1,2}; int group_marginal[] = {0,0,0,0,1,1,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7); } static void test_group_by_prio_mixed_one_marginal8(void **state) { int prio[] = {7,1,3,3,5,2,8,2}; int marginal[] = {0,0,0,0,0,1,0,0}; int group0[] = {6}; int group1[] = {0}; int group2[] = {4}; int group3[] = {2,3}; int group4[] = {7}; int group5[] = {1}; int group6[] = {5}; int *groups[] = {group0, group1, group2, group3, group4, group5, group6}; int group_size[] = {1,1,1,2,1,1,1}; int group_marginal[] = {0,0,0,0,0,0,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = group_by_prio; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7); } static void test_group_by_node_name_same8(void **state) { char *node_name[] = {"a","a","a","a","a","a","a","a"}; int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {paths}; int group_size[] = {8}; set_tgt_node_name(p8, node_name, 8); mp8.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); } static void test_group_by_node_name_increasing8(void **state) { char *node_name[] = {"a","b","c","d","e","f","g","h"}; int prio[] = {1,2,3,4,5,6,7,8}; int paths[] = {7,6,5,4,3,2,1,0}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); set_tgt_node_name(p8, node_name, 8); mp8.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_group_by_node_name_3_groups8(void **state) { char *node_name[] = {"a","b","a","c","b","c","c","a"}; int prio[] = {4,1,4,1,1,1,1,4}; int group0[] = {0,2,7}; int group1[] = {3,5,6}; int group2[] = {1,4}; int *groups[] = {group0, group1, group2}; int group_size[] = {3,3,2}; set_priority(p8, prio, 8); set_tgt_node_name(p8, node_name, 8); mp8.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3); } static void test_group_by_node_name_2_groups8(void **state) { char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"}; int prio[] = {4,1,2,1,2,2,2,1}; int group0[] = {2,4,5,6}; int group1[] = {0,1,3,7}; int *groups[] = {group0, group1}; int group_size[] = {4,4}; set_priority(p8, prio, 8); set_tgt_node_name(p8, node_name, 8); mp8.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); } static void test_group_by_node_name_3_groups4(void **state) { char *node_name[] = {"a","b","c","a"}; int prio[] = {3,1,3,1}; int group0[] = {2}; int group1[] = {0,3}; int group2[] = {1}; int *groups[] = {group0, group1, group2}; int group_size[] = {1,2,1}; set_priority(p4, prio, 4); set_tgt_node_name(p4, node_name, 4); mp4.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); } static void test_group_by_node_name_2_groups4(void **state) { char *node_name[] = {"a","b","b","a"}; int prio[] = {2,1,1,2}; int group0[] = {0,3}; int group1[] = {1,2}; int *groups[] = {group0, group1}; int group_size[] = {2,2}; set_priority(p4, prio, 4); set_tgt_node_name(p4, node_name, 4); mp4.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); } static void test_group_by_node_name1(void **state) { char *node_name[] = {"a"}; int paths[] = {0}; int *groups[] = {paths}; int group_size[] = {1}; set_tgt_node_name(p1, node_name, 1); mp1.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp1,0), 0); verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); } static void test_group_by_node_name0(void **state) { mp0.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp0, 0), 0); verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); } static void test_group_by_node_name_null(void **state) { mp_null.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp_null, 0), 0); verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); } static void test_group_by_node_name_2_groups_all_marginal8(void **state) { char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"}; int prio[] = {4,1,2,1,2,2,2,1}; int marginal[] = {1,1,1,1,1,1,1,1}; int group0[] = {2,4,5,6}; int group1[] = {0,1,3,7}; int *groups[] = {group0, group1}; int group_size[] = {4,4}; int group_marginal[] = {1,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); set_tgt_node_name(p8, node_name, 8); mp8.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); } static void test_group_by_node_name_2_groups_half_marginal8(void **state) { char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"}; int prio[] = {4,1,2,1,2,2,2,1}; int marginal[] = {1,0,1,1,0,1,0,0}; int group0[] = {4,6}; int group1[] = {1,7}; int group2[] = {0,3}; int group3[] = {2,5}; int *groups[] = {group0, group1, group2, group3}; int group_size[] = {2,2,2,2}; int group_marginal[] = {0,0,1,1}; set_priority(p8, prio, 8); set_marginal(p8, marginal, 8); set_tgt_node_name(p8, node_name, 8); mp8.pgpolicyfn = group_by_node_name; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4); } static void test_group_by_serial_same8(void **state) { char *serial[] = {"1","1","1","1","1","1","1","1"}; int paths[] = {0,1,2,3,4,5,6,7}; int *groups[] = {paths}; int group_size[] = {8}; set_serial(p8, serial, 8); mp8.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); } static void test_group_by_serial_increasing8(void **state) { char *serial[] = {"1","2","3","4","5","6","7","8"}; int prio[] = {1,2,3,4,5,6,7,8}; int paths[] = {7,6,5,4,3,2,1,0}; int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], &paths[4], &paths[5], &paths[6], &paths[7]}; int group_size[] = {1,1,1,1,1,1,1,1}; set_priority(p8, prio, 8); set_serial(p8, serial, 8); mp8.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); } static void test_group_by_serial_3_groups8(void **state) { char *serial[] = {"1","2","1","3","2","3","2","1"}; int prio[] = {4,1,4,3,1,3,1,4}; int group0[] = {0,2,7}; int group1[] = {3,5}; int group2[] = {1,4,6}; int *groups[] = {group0, group1, group2}; int group_size[] = {3,2,3}; set_priority(p8, prio, 8); set_serial(p8, serial, 8); mp8.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3); } static void test_group_by_serial_2_groups8(void **state) { char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"}; int prio[] = {3,2,2,1,2,2,1,2}; int group0[] = {1,4,5,7}; int group1[] = {0,2,3,6}; int *groups[] = {group0, group1}; int group_size[] = {4,4}; set_priority(p8, prio, 8); set_serial(p8, serial, 8); mp8.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp8, 0), 0); verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); } static void test_group_by_serial_3_groups4(void **state) { char *serial[] = {"1","2","3","2"}; int prio[] = {3,1,3,1}; int group0[] = {0}; int group1[] = {2}; int group2[] = {1,3}; int *groups[] = {group0, group1, group2}; int group_size[] = {1,1,2}; set_priority(p4, prio, 4); set_serial(p4, serial, 4); mp4.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); } static void test_group_by_serial_2_groups4(void **state) { char *serial[] = {"1","2","1","2"}; int prio[] = {3,1,3,1}; int group0[] = {0,2}; int group1[] = {1,3}; int *groups[] = {group0, group1}; int group_size[] = {2,2}; set_priority(p4, prio, 4); set_serial(p4, serial, 4); mp4.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp4, 0), 0); verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); } static void test_group_by_serial1(void **state) { char *serial[1] = {"1"}; int paths[1] = {0}; int *groups[1] = {paths}; int group_size[1] = {1}; set_serial(p1, serial, 1); mp1.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp1, 0), 0); verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); } static void test_group_by_serial0(void **state) { mp0.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp0, 0), 0); verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); } static void test_group_by_serial_null(void **state) { mp_null.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp_null, 0), 0); verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); } static void test_group_by_serial_2_groups8_all_marginal8(void **state) { char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"}; int marginal[] = {1,1,1,1,1,1,1,1}; int prio[] = {3,2,2,1,2,2,1,2}; int group0[] = {1,4,5,7}; int group1[] = {0,2,3,6}; int *groups[] = {group0, group1}; int group_size[] = {4,4}; int group_marginal[] = {1,1}; set_priority(p8, prio, 8); set_serial(p8, serial, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); } static void test_group_by_serial_2_groups8_half_marginal8(void **state) { char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"}; int marginal[] = {0,0,1,1,1,1,0,0}; int prio[] = {3,2,2,1,2,2,1,2}; int group0[] = {0,6}; int group1[] = {1,7}; int group2[] = {4,5}; int group3[] = {2,3}; int *groups[] = {group0, group1, group2, group3}; int group_size[] = {2,2,2,2}; int group_marginal[] = {0,0,1,1}; set_priority(p8, prio, 8); set_serial(p8, serial, 8); set_marginal(p8, marginal, 8); mp8.pgpolicyfn = group_by_serial; assert_int_equal(group_paths(&mp8, 1), 0); verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4); } #define setup_test(name, nr) \ cmocka_unit_test_setup_teardown(name ## nr, setup ## nr, teardown ## nr) int test_pgpolicies(void) { const struct CMUnitTest tests[] = { setup_test(test_one_group, 8), setup_test(test_one_group, 4), setup_test(test_one_group, 1), setup_test(test_one_group, 0), setup_test(test_one_group, _null), setup_test(test_one_group_all_marginal, 8), setup_test(test_one_group_half_marginal, 8), setup_test(test_one_group_ignore_marginal, 8), setup_test(test_one_group_one_marginal, 8), setup_test(test_one_path_per_group_same, 8), setup_test(test_one_path_per_group_increasing, 8), setup_test(test_one_path_per_group_decreasing, 8), setup_test(test_one_path_per_group_mixed, 8), setup_test(test_one_path_per_group, 4), setup_test(test_one_path_per_group, 1), setup_test(test_one_path_per_group, 0), setup_test(test_one_path_per_group, _null), setup_test(test_one_path_per_group_mixed_all_marginal, 8), setup_test(test_one_path_per_group_mixed_half_marginal, 8), setup_test(test_group_by_prio_same, 8), setup_test(test_group_by_prio_increasing, 8), setup_test(test_group_by_prio_decreasing, 8), setup_test(test_group_by_prio_mixed, 8), setup_test(test_group_by_prio_mixed_no_marginal, 8), setup_test(test_group_by_prio_2_groups, 8), setup_test(test_group_by_prio_mixed, 4), setup_test(test_group_by_prio_2_groups, 4), setup_test(test_group_by_prio, 1), setup_test(test_group_by_prio, 0), setup_test(test_group_by_prio, _null), setup_test(test_group_by_prio_mixed_all_marginal, 8), setup_test(test_group_by_prio_mixed_half_marginal, 8), setup_test(test_group_by_prio_mixed_one_marginal, 8), setup_test(test_group_by_node_name_same, 8), setup_test(test_group_by_node_name_increasing, 8), setup_test(test_group_by_node_name_3_groups, 8), setup_test(test_group_by_node_name_2_groups, 8), setup_test(test_group_by_node_name_3_groups, 4), setup_test(test_group_by_node_name_2_groups, 4), setup_test(test_group_by_node_name, 1), setup_test(test_group_by_node_name, 0), setup_test(test_group_by_node_name, _null), setup_test(test_group_by_node_name_2_groups_all_marginal, 8), setup_test(test_group_by_node_name_2_groups_half_marginal, 8), setup_test(test_group_by_serial_same, 8), setup_test(test_group_by_serial_increasing, 8), setup_test(test_group_by_serial_3_groups, 8), setup_test(test_group_by_serial_2_groups, 8), setup_test(test_group_by_serial_3_groups, 4), setup_test(test_group_by_serial_2_groups, 4), setup_test(test_group_by_serial, 1), setup_test(test_group_by_serial, 0), setup_test(test_group_by_serial, _null), setup_test(test_group_by_serial_2_groups8_all_marginal, 8), setup_test(test_group_by_serial_2_groups8_half_marginal, 8), }; return cmocka_run_group_tests(tests, setup, NULL); } int main(void) { int ret = 0; ret += test_pgpolicies(); return ret; }