Commit 0a5c0de8 authored by Stephen Veiss's avatar Stephen Veiss Committed by Andrii Nakryiko

selftests/bpf: Extract insert_test from parse_test_list

Split the logic to insert new tests into test filter sets out from
parse_test_list.

Fix the subtest insertion logic to reuse an existing top-level test
filter, which prevents the creation of duplicate top-level test filters
each with a single subtest.
Signed-off-by: default avatarStephen Veiss <sveiss@meta.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20230427225333.3506052-2-sveiss@meta.com
parent c39028b3
...@@ -96,6 +96,19 @@ static void test_parse_test_list(void) ...@@ -96,6 +96,19 @@ static void test_parse_test_list(void)
goto error; goto error;
ASSERT_OK(strcmp("*bpf_cookie*", set.tests[0].name), "test name"); ASSERT_OK(strcmp("*bpf_cookie*", set.tests[0].name), "test name");
ASSERT_OK(strcmp("*trace*", set.tests[0].subtests[0]), "subtest name"); ASSERT_OK(strcmp("*trace*", set.tests[0].subtests[0]), "subtest name");
free_test_filter_set(&set);
ASSERT_OK(parse_test_list("t/subtest1,t/subtest2", &set, true),
"parsing");
if (!ASSERT_EQ(set.cnt, 1, "count of test filters"))
goto error;
if (!ASSERT_OK_PTR(set.tests, "test filters initialized"))
goto error;
if (!ASSERT_EQ(set.tests[0].subtest_cnt, 2, "subtest filters count"))
goto error;
ASSERT_OK(strcmp("t", set.tests[0].name), "test name");
ASSERT_OK(strcmp("subtest1", set.tests[0].subtests[0]), "subtest name");
ASSERT_OK(strcmp("subtest2", set.tests[0].subtests[1]), "subtest name");
error: error:
free_test_filter_set(&set); free_test_filter_set(&set);
} }
......
...@@ -70,92 +70,122 @@ int parse_num_list(const char *s, bool **num_set, int *num_set_len) ...@@ -70,92 +70,122 @@ int parse_num_list(const char *s, bool **num_set, int *num_set_len)
return 0; return 0;
} }
int parse_test_list(const char *s, static int do_insert_test(struct test_filter_set *set,
struct test_filter_set *set, char *test_str,
bool is_glob_pattern) char *subtest_str)
{ {
char *input, *state = NULL, *next; struct test_filter *tmp, *test;
struct test_filter *tmp, *tests = NULL; char **ctmp;
int i, j, cnt = 0; int i;
input = strdup(s); for (i = 0; i < set->cnt; i++) {
if (!input) test = &set->tests[i];
if (strcmp(test_str, test->name) == 0) {
free(test_str);
goto subtest;
}
}
tmp = realloc(set->tests, sizeof(*test) * (set->cnt + 1));
if (!tmp)
return -ENOMEM; return -ENOMEM;
while ((next = strtok_r(state ? NULL : input, ",", &state))) { set->tests = tmp;
char *subtest_str = strchr(next, '/'); test = &set->tests[set->cnt];
char *pattern = NULL;
int glob_chars = 0;
tmp = realloc(tests, sizeof(*tests) * (cnt + 1)); test->name = test_str;
if (!tmp) test->subtests = NULL;
goto err; test->subtest_cnt = 0;
tests = tmp;
tests[cnt].subtest_cnt = 0; set->cnt++;
tests[cnt].subtests = NULL;
if (is_glob_pattern) { subtest:
pattern = "%s"; if (!subtest_str)
} else { return 0;
pattern = "*%s*";
glob_chars = 2;
}
if (subtest_str) { for (i = 0; i < test->subtest_cnt; i++) {
char **tmp_subtests = NULL; if (strcmp(subtest_str, test->subtests[i]) == 0) {
int subtest_cnt = tests[cnt].subtest_cnt; free(subtest_str);
return 0;
*subtest_str = '\0';
subtest_str += 1;
tmp_subtests = realloc(tests[cnt].subtests,
sizeof(*tmp_subtests) *
(subtest_cnt + 1));
if (!tmp_subtests)
goto err;
tests[cnt].subtests = tmp_subtests;
tests[cnt].subtests[subtest_cnt] =
malloc(strlen(subtest_str) + glob_chars + 1);
if (!tests[cnt].subtests[subtest_cnt])
goto err;
sprintf(tests[cnt].subtests[subtest_cnt],
pattern,
subtest_str);
tests[cnt].subtest_cnt++;
} }
}
tests[cnt].name = malloc(strlen(next) + glob_chars + 1); ctmp = realloc(test->subtests,
if (!tests[cnt].name) sizeof(*test->subtests) * (test->subtest_cnt + 1));
goto err; if (!ctmp)
sprintf(tests[cnt].name, pattern, next); return -ENOMEM;
test->subtests = ctmp;
test->subtests[test->subtest_cnt] = subtest_str;
cnt++; test->subtest_cnt++;
return 0;
}
static int insert_test(struct test_filter_set *set,
char *test_spec,
bool is_glob_pattern)
{
char *pattern, *subtest_str, *ext_test_str, *ext_subtest_str = NULL;
int glob_chars = 0;
if (is_glob_pattern) {
pattern = "%s";
} else {
pattern = "*%s*";
glob_chars = 2;
} }
tmp = realloc(set->tests, sizeof(*tests) * (cnt + set->cnt)); subtest_str = strchr(test_spec, '/');
if (!tmp) if (subtest_str) {
*subtest_str = '\0';
subtest_str += 1;
}
ext_test_str = malloc(strlen(test_spec) + glob_chars + 1);
if (!ext_test_str)
goto err; goto err;
memcpy(tmp + set->cnt, tests, sizeof(*tests) * cnt); sprintf(ext_test_str, pattern, test_spec);
set->tests = tmp;
set->cnt += cnt;
free(tests); if (subtest_str) {
free(input); ext_subtest_str = malloc(strlen(subtest_str) + glob_chars + 1);
return 0; if (!ext_subtest_str)
goto err;
sprintf(ext_subtest_str, pattern, subtest_str);
}
return do_insert_test(set, ext_test_str, ext_subtest_str);
err: err:
for (i = 0; i < cnt; i++) { free(ext_test_str);
for (j = 0; j < tests[i].subtest_cnt; j++) free(ext_subtest_str);
free(tests[i].subtests[j]);
return -ENOMEM;
}
free(tests[i].name); int parse_test_list(const char *s,
struct test_filter_set *set,
bool is_glob_pattern)
{
char *input, *state = NULL, *test_spec;
int err = 0;
input = strdup(s);
if (!input)
return -ENOMEM;
while ((test_spec = strtok_r(state ? NULL : input, ",", &state))) {
err = insert_test(set, test_spec, is_glob_pattern);
if (err)
break;
} }
free(tests);
free(input); free(input);
return -ENOMEM; return err;
} }
__u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info) __u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment