For tests that carry a __description tag, allow matching on both the description string and program name for convenience. Before this commit, the description string must be spelt out to filter the tests. Suggested-by: Alexei Starovoitov Signed-off-by: Kumar Kartikeya Dwivedi --- tools/testing/selftests/bpf/progs/bpf_misc.h | 4 +- tools/testing/selftests/bpf/test_loader.c | 46 ++++++++++++++++---- tools/testing/selftests/bpf/test_progs.c | 45 +++++++++++++++---- tools/testing/selftests/bpf/test_progs.h | 1 + 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h index 0904fe14ad1d..4b313374c5f1 100644 --- a/tools/testing/selftests/bpf/progs/bpf_misc.h +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h @@ -103,8 +103,8 @@ * - TEST_DATA_LEN * __retval_unpriv Same, but load program in unprivileged mode. * - * __description Text to be used instead of a program name for display - * and filtering purposes. + * __description Text to be used for display and as an additional filter + * alias, while the original program name stays matchable. * * __log_level Log level to use for the program, numeric value expected. * diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c index 338c035c3688..96ed70e01fe5 100644 --- a/tools/testing/selftests/bpf/test_loader.c +++ b/tools/testing/selftests/bpf/test_loader.c @@ -69,6 +69,7 @@ enum load_mode { struct test_subspec { char *name; + char *description; bool expect_failure; struct expected_msgs expect_msgs; struct expected_msgs expect_xlated; @@ -142,9 +143,13 @@ static void free_test_spec(struct test_spec *spec) free_msgs(&spec->priv.stdout); free(spec->priv.name); + free(spec->priv.description); free(spec->unpriv.name); + free(spec->unpriv.description); spec->priv.name = NULL; + spec->priv.description = NULL; spec->unpriv.name = NULL; + spec->unpriv.description = NULL; } /* Compiles regular expression matching pattern. @@ -659,33 +664,56 @@ static int parse_test_spec(struct test_loader *tester, if (spec->mode_mask == 0) spec->mode_mask = PRIV; - if (!description) - description = spec->prog_name; - if (spec->mode_mask & PRIV) { - spec->priv.name = strdup(description); + spec->priv.name = strdup(spec->prog_name); if (!spec->priv.name) { PRINT_FAIL("failed to allocate memory for priv.name\n"); err = -ENOMEM; goto cleanup; } + + if (description) { + spec->priv.description = strdup(description); + if (!spec->priv.description) { + PRINT_FAIL("failed to allocate memory for priv.description\n"); + err = -ENOMEM; + goto cleanup; + } + } } if (spec->mode_mask & UNPRIV) { - int descr_len = strlen(description); + int name_len = strlen(spec->prog_name); const char *suffix = " @unpriv"; + int suffix_len = strlen(suffix); char *name; - name = malloc(descr_len + strlen(suffix) + 1); + name = malloc(name_len + suffix_len + 1); if (!name) { PRINT_FAIL("failed to allocate memory for unpriv.name\n"); err = -ENOMEM; goto cleanup; } - strcpy(name, description); - strcpy(&name[descr_len], suffix); + strcpy(name, spec->prog_name); + strcpy(&name[name_len], suffix); spec->unpriv.name = name; + + if (description) { + int descr_len = strlen(description); + char *descr; + + descr = malloc(descr_len + suffix_len + 1); + if (!descr) { + PRINT_FAIL("failed to allocate memory for unpriv.description\n"); + err = -ENOMEM; + goto cleanup; + } + + strcpy(descr, description); + strcpy(&descr[descr_len], suffix); + spec->unpriv.description = descr; + } } if (spec->mode_mask & (PRIV | UNPRIV)) { @@ -1148,7 +1176,7 @@ void run_subtest(struct test_loader *tester, int links_cnt = 0; bool should_load; - if (!test__start_subtest(subspec->name)) + if (!test__start_subtest_with_desc(subspec->name, subspec->description)) return; if ((get_current_arch() & spec->arch_mask) == 0) { diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 0929f4a7bda4..7fe16b5131b1 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -308,16 +308,34 @@ static bool match_subtest(struct test_filter_set *filter, return false; } +static bool match_subtest_desc(struct test_filter_set *filter, + const char *test_name, + const char *subtest_name, + const char *subtest_desc) +{ + if (match_subtest(filter, test_name, subtest_name)) + return true; + + if (!subtest_desc || !subtest_desc[0] || + strcmp(subtest_name, subtest_desc) == 0) + return false; + + return match_subtest(filter, test_name, subtest_desc); +} + static bool should_run_subtest(struct test_selector *sel, struct test_selector *subtest_sel, int subtest_num, const char *test_name, - const char *subtest_name) + const char *subtest_name, + const char *subtest_desc) { - if (match_subtest(&sel->blacklist, test_name, subtest_name)) + if (match_subtest_desc(&sel->blacklist, test_name, + subtest_name, subtest_desc)) return false; - if (match_subtest(&sel->whitelist, test_name, subtest_name)) + if (match_subtest_desc(&sel->whitelist, test_name, + subtest_name, subtest_desc)) return true; if (!sel->whitelist.cnt && !subtest_sel->num_set) @@ -544,11 +562,12 @@ void test__end_subtest(void) env.subtest_state = NULL; } -bool test__start_subtest(const char *subtest_name) +bool test__start_subtest_with_desc(const char *subtest_name, const char *subtest_desc) { struct prog_test_def *test = env.test; struct test_state *state = env.test_state; struct subtest_state *subtest_state; + const char *subtest_display_name; size_t sub_state_size = sizeof(*subtest_state); if (env.subtest_state) @@ -574,7 +593,9 @@ bool test__start_subtest(const char *subtest_name) return false; } - subtest_state->name = strdup(subtest_name); + subtest_display_name = subtest_desc ? subtest_desc : subtest_name; + + subtest_state->name = strdup(subtest_display_name); if (!subtest_state->name) { fprintf(env.stderr_saved, "Subtest #%d: failed to copy subtest name!\n", @@ -586,14 +607,15 @@ bool test__start_subtest(const char *subtest_name) &env.subtest_selector, state->subtest_num, test->test_name, - subtest_name)) { + subtest_name, + subtest_desc)) { subtest_state->filtered = true; return false; } - subtest_state->should_tmon = match_subtest(&env.tmon_selector.whitelist, - test->test_name, - subtest_name); + subtest_state->should_tmon = match_subtest_desc(&env.tmon_selector.whitelist, + test->test_name, subtest_name, + subtest_desc); env.subtest_state = subtest_state; stdio_hijack_init(&subtest_state->log_buf, &subtest_state->log_cnt); @@ -602,6 +624,11 @@ bool test__start_subtest(const char *subtest_name) return true; } +bool test__start_subtest(const char *subtest_name) +{ + return test__start_subtest_with_desc(subtest_name, NULL); +} + void test__force_log(void) { env.test_state->force_log = true; diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index eebfc18cdcd2..1a44467f4310 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -181,6 +181,7 @@ struct msg { extern struct test_env env; void test__force_log(void); +bool test__start_subtest_with_desc(const char *name, const char *description); bool test__start_subtest(const char *name); void test__end_subtest(void); void test__skip(void); -- 2.52.0