/*
* 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 <https://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <stdlib.h>
#include <cmocka.h>
#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;
}