On Mon, Jun 17, 2024 at 7:15 AM Cupertino Miranda <cupertino.miranda@xxxxxxxxxx> wrote: > > Add support for __regex and __regex_unpriv macros to check the test > execution output against a regular expression. This is similar to __msg > and __msg_unpriv, however those expect do substring matching. > > Signed-off-by: Cupertino Miranda <cupertino.miranda@xxxxxxxxxx> > Acked-by: Eduard Zingerman <eddyz87@xxxxxxxxx> > Cc: jose.marchesi@xxxxxxxxxx > Cc: david.faust@xxxxxxxxxx > Cc: Yonghong Song <yonghong.song@xxxxxxxxx> > Cc: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> > --- > tools/testing/selftests/bpf/progs/bpf_misc.h | 11 +- > tools/testing/selftests/bpf/test_loader.c | 117 ++++++++++++++----- > 2 files changed, 98 insertions(+), 30 deletions(-) > [...] > -static int push_msg(const char *msg, struct test_subspec *subspec) > +static int push_msg(const char *substr, const char *regex_str, struct test_subspec *subspec) > { > void *tmp; > + int regcomp_res; > + char error_msg[100]; > + struct expect_msg *msg; > > - tmp = realloc(subspec->expect_msgs, (1 + subspec->expect_msg_cnt) * sizeof(void *)); > + tmp = realloc(subspec->expect_msgs, > + (1 + subspec->expect_msg_cnt) * sizeof(struct expect_msg)); > if (!tmp) { > ASSERT_FAIL("failed to realloc memory for messages\n"); > return -ENOMEM; > } > subspec->expect_msgs = tmp; > - subspec->expect_msgs[subspec->expect_msg_cnt++] = msg; > + msg = &subspec->expect_msgs[subspec->expect_msg_cnt]; > + subspec->expect_msg_cnt += 1; we should update expect_msg_cnt only on success, otherwise we can run regfree() on an instance that actually failed to regcomp(). I moved this down while applying. > + > + if (substr) { > + msg->substr = substr; > + msg->regex_str = NULL; [...] > + err = regexec(&msg->regex, > + tester->log_buf + tester->next_match_pos, > + 1, reg_match, 0); > + if (err == 0) { > + match = tester->log_buf + tester->next_match_pos > + + reg_match[0].rm_so; > + tester->next_match_pos += reg_match[0].rm_eo; > + } else > + match = NULL; {} should be balanced for if/else, fixed it up as well > + } > > - match = strstr(tester->log_buf + tester->next_match_pos, expect_msg); > if (!ASSERT_OK_PTR(match, "expect_msg")) { > - /* if we are in verbose mode, we've already emitted log */ > if (env.verbosity == VERBOSE_NONE) > emit_verifier_log(tester->log_buf, true /*force*/); > - for (j = 0; j < i; j++) > - fprintf(stderr, > - "MATCHED MSG: '%s'\n", subspec->expect_msgs[j]); > - fprintf(stderr, "EXPECTED MSG: '%s'\n", expect_msg); > + for (j = 0; j <= i; j++) { > + msg = &subspec->expect_msgs[j]; > + fprintf(stderr, "%s %s: '%s'\n", > + j < i ? "MATCHED " : "EXPECTED", > + msg->substr ? "SUBSTR" : " REGEX", > + msg->substr ?: msg->regex_str); > + } > return; > } > - > - tester->next_match_pos = match - tester->log_buf + strlen(expect_msg); > } > } > > -- > 2.39.2 >