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,30 +70,66 @@ int parse_num_list(const char *s, bool **num_set, int *num_set_len) ...@@ -70,30 +70,66 @@ 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];
return -ENOMEM;
while ((next = strtok_r(state ? NULL : input, ",", &state))) { if (strcmp(test_str, test->name) == 0) {
char *subtest_str = strchr(next, '/'); free(test_str);
char *pattern = NULL; goto subtest;
int glob_chars = 0; }
}
tmp = realloc(tests, sizeof(*tests) * (cnt + 1)); tmp = realloc(set->tests, sizeof(*test) * (set->cnt + 1));
if (!tmp) if (!tmp)
goto err; return -ENOMEM;
tests = tmp;
tests[cnt].subtest_cnt = 0; set->tests = tmp;
tests[cnt].subtests = NULL; test = &set->tests[set->cnt];
test->name = test_str;
test->subtests = NULL;
test->subtest_cnt = 0;
set->cnt++;
subtest:
if (!subtest_str)
return 0;
for (i = 0; i < test->subtest_cnt; i++) {
if (strcmp(subtest_str, test->subtests[i]) == 0) {
free(subtest_str);
return 0;
}
}
ctmp = realloc(test->subtests,
sizeof(*test->subtests) * (test->subtest_cnt + 1));
if (!ctmp)
return -ENOMEM;
test->subtests = ctmp;
test->subtests[test->subtest_cnt] = subtest_str;
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) { if (is_glob_pattern) {
pattern = "%s"; pattern = "%s";
...@@ -102,60 +138,54 @@ int parse_test_list(const char *s, ...@@ -102,60 +138,54 @@ int parse_test_list(const char *s,
glob_chars = 2; glob_chars = 2;
} }
subtest_str = strchr(test_spec, '/');
if (subtest_str) { if (subtest_str) {
char **tmp_subtests = NULL;
int subtest_cnt = tests[cnt].subtest_cnt;
*subtest_str = '\0'; *subtest_str = '\0';
subtest_str += 1; 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] = ext_test_str = malloc(strlen(test_spec) + glob_chars + 1);
malloc(strlen(subtest_str) + glob_chars + 1); if (!ext_test_str)
if (!tests[cnt].subtests[subtest_cnt])
goto err; goto err;
sprintf(tests[cnt].subtests[subtest_cnt],
pattern,
subtest_str);
tests[cnt].subtest_cnt++; sprintf(ext_test_str, pattern, test_spec);
}
tests[cnt].name = malloc(strlen(next) + glob_chars + 1); if (subtest_str) {
if (!tests[cnt].name) ext_subtest_str = malloc(strlen(subtest_str) + glob_chars + 1);
if (!ext_subtest_str)
goto err; goto err;
sprintf(tests[cnt].name, pattern, next);
cnt++; sprintf(ext_subtest_str, pattern, subtest_str);
} }
tmp = realloc(set->tests, sizeof(*tests) * (cnt + set->cnt)); return do_insert_test(set, ext_test_str, ext_subtest_str);
if (!tmp)
goto err;
memcpy(tmp + set->cnt, tests, sizeof(*tests) * cnt); err:
set->tests = tmp; free(ext_test_str);
set->cnt += cnt; free(ext_subtest_str);
free(tests); return -ENOMEM;
free(input); }
return 0;
err: int parse_test_list(const char *s,
for (i = 0; i < cnt; i++) { struct test_filter_set *set,
for (j = 0; j < tests[i].subtest_cnt; j++) bool is_glob_pattern)
free(tests[i].subtests[j]); {
char *input, *state = NULL, *test_spec;
int err = 0;
input = strdup(s);
if (!input)
return -ENOMEM;
free(tests[i].name); 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