Commit 64f01e93 authored by Eduard Zingerman's avatar Eduard Zingerman Committed by Andrii Nakryiko

selftests/bpf: extract test_loader->expect_msgs as a data structure

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