]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Allow prog name matching for tests with __description
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Tue, 7 Apr 2026 14:56:06 +0000 (16:56 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 7 Apr 2026 19:24:29 +0000 (12:24 -0700)
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 <ast@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260407145606.3991770-1-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/bpf_misc.h
tools/testing/selftests/bpf/test_loader.c
tools/testing/selftests/bpf/test_progs.c
tools/testing/selftests/bpf/test_progs.h

index 0904fe14ad1d45aba2f2c8a9a12881a0d248685e..4b313374c5f1c63da6450c86d13537965e2ca06d 100644 (file)
  *                   - 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.
  *
index 338c035c36884c02ac57cd17110122c10b4858e4..96ed70e01fe55f8091c5ab5d235d8f38636ce0a6 100644 (file)
@@ -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) {
index 0929f4a7bda4602fbea4f9fe4cd1113e4be7418c..7fe16b5131b1a6903cf30895efeb8571bf67f350 100644 (file)
@@ -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;
index eebfc18cdcd21d2641bd42870a3364065ab290b5..1a44467f4310dfdf86685217a682b0e2ddbf46a5 100644 (file)
@@ -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);