selftests/bpf: extract test_loader->expect_msgs as a data structure
authorEduard Zingerman <eddyz87@gmail.com>
Mon, 22 Jul 2024 23:38:41 +0000 (16:38 -0700)
committerAndrii Nakryiko <andrii@kernel.org>
Mon, 29 Jul 2024 22:05:06 +0000 (15:05 -0700)
Non-functional change: use a separate data structure to represented
expected messages in test_loader.
This would allow to use the same functionality for expected set of
disassembled instructions in the follow-up commit.

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20240722233844.1406874-8-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
tools/testing/selftests/bpf/test_loader.c

index 47508cf..3f84903 100644 (file)
@@ -55,11 +55,15 @@ struct expect_msg {
        regex_t regex;
 };
 
+struct expected_msgs {
+       struct expect_msg *patterns;
+       size_t cnt;
+};
+
 struct test_subspec {
        char *name;
        bool expect_failure;
-       struct expect_msg *expect_msgs;
-       size_t expect_msg_cnt;
+       struct expected_msgs expect_msgs;
        int retval;
        bool execute;
 };
@@ -96,44 +100,45 @@ void test_loader_fini(struct test_loader *tester)
        free(tester->log_buf);
 }
 
-static void free_test_spec(struct test_spec *spec)
+static void free_msgs(struct expected_msgs *msgs)
 {
        int i;
 
+       for (i = 0; i < msgs->cnt; i++)
+               if (msgs->patterns[i].regex_str)
+                       regfree(&msgs->patterns[i].regex);
+       free(msgs->patterns);
+       msgs->patterns = NULL;
+       msgs->cnt = 0;
+}
+
+static void free_test_spec(struct test_spec *spec)
+{
        /* Deallocate expect_msgs arrays. */
-       for (i = 0; i < spec->priv.expect_msg_cnt; i++)
-               if (spec->priv.expect_msgs[i].regex_str)
-                       regfree(&spec->priv.expect_msgs[i].regex);
-       for (i = 0; i < spec->unpriv.expect_msg_cnt; i++)
-               if (spec->unpriv.expect_msgs[i].regex_str)
-                       regfree(&spec->unpriv.expect_msgs[i].regex);
+       free_msgs(&spec->priv.expect_msgs);
+       free_msgs(&spec->unpriv.expect_msgs);
 
        free(spec->priv.name);
        free(spec->unpriv.name);
-       free(spec->priv.expect_msgs);
-       free(spec->unpriv.expect_msgs);
-
        spec->priv.name = NULL;
        spec->unpriv.name = NULL;
-       spec->priv.expect_msgs = NULL;
-       spec->unpriv.expect_msgs = NULL;
 }
 
-static int push_msg(const char *substr, const char *regex_str, struct test_subspec *subspec)
+static int push_msg(const char *substr, const char *regex_str, struct expected_msgs *msgs)
 {
        void *tmp;
        int regcomp_res;
        char error_msg[100];
        struct expect_msg *msg;
 
-       tmp = realloc(subspec->expect_msgs,
-                     (1 + subspec->expect_msg_cnt) * sizeof(struct expect_msg));
+       tmp = realloc(msgs->patterns,
+                     (1 + msgs->cnt) * sizeof(struct expect_msg));
        if (!tmp) {
                ASSERT_FAIL("failed to realloc memory for messages\n");
                return -ENOMEM;
        }
-       subspec->expect_msgs = tmp;
-       msg = &subspec->expect_msgs[subspec->expect_msg_cnt];
+       msgs->patterns = tmp;
+       msg = &msgs->patterns[msgs->cnt];
 
        if (substr) {
                msg->substr = substr;
@@ -150,7 +155,7 @@ static int push_msg(const char *substr, const char *regex_str, struct test_subsp
                }
        }
 
-       subspec->expect_msg_cnt += 1;
+       msgs->cnt += 1;
        return 0;
 }
 
@@ -272,25 +277,25 @@ static int parse_test_spec(struct test_loader *tester,
                        spec->mode_mask |= UNPRIV;
                } else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX)) {
                        msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX) - 1;
-                       err = push_msg(msg, NULL, &spec->priv);
+                       err = push_msg(msg, NULL, &spec->priv.expect_msgs);
                        if (err)
                                goto cleanup;
                        spec->mode_mask |= PRIV;
                } else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV)) {
                        msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX_UNPRIV) - 1;
-                       err = push_msg(msg, NULL, &spec->unpriv);
+                       err = push_msg(msg, NULL, &spec->unpriv.expect_msgs);
                        if (err)
                                goto cleanup;
                        spec->mode_mask |= UNPRIV;
                } else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX)) {
                        msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX) - 1;
-                       err = push_msg(NULL, msg, &spec->priv);
+                       err = push_msg(NULL, msg, &spec->priv.expect_msgs);
                        if (err)
                                goto cleanup;
                        spec->mode_mask |= PRIV;
                } else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX_UNPRIV)) {
                        msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX_UNPRIV) - 1;
-                       err = push_msg(NULL, msg, &spec->unpriv);
+                       err = push_msg(NULL, msg, &spec->unpriv.expect_msgs);
                        if (err)
                                goto cleanup;
                        spec->mode_mask |= UNPRIV;
@@ -387,11 +392,12 @@ static int parse_test_spec(struct test_loader *tester,
                        spec->unpriv.execute = spec->priv.execute;
                }
 
-               if (!spec->unpriv.expect_msgs) {
-                       for (i = 0; i < spec->priv.expect_msg_cnt; i++) {
-                               struct expect_msg *msg = &spec->priv.expect_msgs[i];
+               if (spec->unpriv.expect_msgs.cnt == 0) {
+                       for (i = 0; i < spec->priv.expect_msgs.cnt; i++) {
+                               struct expect_msg *msg = &spec->priv.expect_msgs.patterns[i];
 
-                               err = push_msg(msg->substr, msg->regex_str, &spec->unpriv);
+                               err = push_msg(msg->substr, msg->regex_str,
+                                              &spec->unpriv.expect_msgs);
                                if (err)
                                        goto cleanup;
                        }
@@ -443,18 +449,14 @@ static void emit_verifier_log(const char *log_buf, bool force)
        fprintf(stdout, "VERIFIER LOG:\n=============\n%s=============\n", log_buf);
 }
 
-static void validate_case(struct test_loader *tester,
-                         struct test_subspec *subspec,
-                         struct bpf_object *obj,
-                         struct bpf_program *prog,
-                         int load_err)
+static void validate_msgs(char *log_buf, struct expected_msgs *msgs)
 {
        regmatch_t reg_match[1];
-       const char *log = tester->log_buf;
+       const char *log = log_buf;
        int i, j, err;
 
-       for (i = 0; i < subspec->expect_msg_cnt; i++) {
-               struct expect_msg *msg = &subspec->expect_msgs[i];
+       for (i = 0; i < msgs->cnt; i++) {
+               struct expect_msg *msg = &msgs->patterns[i];
                const char *match = NULL;
 
                if (msg->substr) {
@@ -471,9 +473,9 @@ static void validate_case(struct test_loader *tester,
 
                if (!ASSERT_OK_PTR(match, "expect_msg")) {
                        if (env.verbosity == VERBOSE_NONE)
-                               emit_verifier_log(tester->log_buf, true /*force*/);
+                               emit_verifier_log(log_buf, true /*force*/);
                        for (j = 0; j <= i; j++) {
-                               msg = &subspec->expect_msgs[j];
+                               msg = &msgs->patterns[j];
                                fprintf(stderr, "%s %s: '%s'\n",
                                        j < i ? "MATCHED " : "EXPECTED",
                                        msg->substr ? "SUBSTR" : " REGEX",
@@ -692,9 +694,8 @@ void run_subtest(struct test_loader *tester,
                        goto tobj_cleanup;
                }
        }
-
        emit_verifier_log(tester->log_buf, false /*force*/);
-       validate_case(tester, subspec, tobj, tprog, err);
+       validate_msgs(tester->log_buf, &subspec->expect_msgs);
 
        if (should_do_test_run(spec, subspec)) {
                /* For some reason test_verifier executes programs