mirror of
https://github.com/torvalds/linux.git
synced 2026-11-09 13:44:03 +01:00
selftests/bpf: Add compare_text_to_expected() helper
Some selftests generate text (such as BTF dump) and check it against an expectation committed nearby. There is no shared way to do that. prog_tests/btf_dump.c assembles an "awk ... | diff -u" pipeline and hands it to system(). Any other test wanting the same behaviour needs to reproduce both the comparison and the reporting of a mismatch. test_progs captures per-subtest output by pointing the stdout and stderr FILE * globals at a memstream. But a child process inherits descriptors, not the globals. So the "| diff -u" goes to the console instead of the subtest log and is absent from the failure report. Add a helper that compares two strings and runs diff(1) on mismatch, properly relaying the output to stdout. Add tests for the helper. Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev> Link: https://lore.kernel.org/r/20260828215207.3105313-2-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
776c86a3e7
commit
bd71904697
|
|
@ -179,3 +179,26 @@ void test_prog_tests_framework_expected_msgs(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_prog_tests_framework_compare_text(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (test__start_subtest("compare_text_match")) {
|
||||
err = compare_text_to_expected("same\n", "same\n");
|
||||
ASSERT_EQ(err, 0, "match_rc");
|
||||
test__end_subtest();
|
||||
}
|
||||
|
||||
if (test__start_subtest("compare_text_mismatch")) {
|
||||
err = compare_text_to_expected("line two\n", "line one\n");
|
||||
fflush(stdout);
|
||||
|
||||
ASSERT_EQ(err, -1, "mismatch_rc");
|
||||
ASSERT_HAS_SUBSTR(env.subtest_state->log_buf, "-line one",
|
||||
"diff_has_expected");
|
||||
ASSERT_HAS_SUBSTR(env.subtest_state->log_buf, "+line two",
|
||||
"diff_has_actual");
|
||||
test__end_subtest();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -534,3 +534,46 @@ int stack_mprotect(void)
|
|||
PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int compare_text_to_expected(const char *actual, const char *expected)
|
||||
{
|
||||
char exp_path[] = "/tmp/selftest_expected.XXXXXX";
|
||||
char act_path[] = "/tmp/selftest_actual.XXXXXX";
|
||||
char buf[512], cmd[128];
|
||||
int exp_fd, act_fd;
|
||||
FILE *p;
|
||||
|
||||
if (!strcmp(actual, expected))
|
||||
return 0;
|
||||
|
||||
exp_fd = mkstemp(exp_path);
|
||||
act_fd = mkstemp(act_path);
|
||||
if (exp_fd < 0 || act_fd < 0) {
|
||||
fprintf(stdout, "output differs, no temp file for a diff\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dprintf(exp_fd, "%s", expected);
|
||||
dprintf(act_fd, "%s", actual);
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "diff -u '%s' '%s'", exp_path, act_path);
|
||||
p = popen(cmd, "r");
|
||||
if (!p) {
|
||||
fprintf(stdout, "output differs, '%s' did not run\n", cmd);
|
||||
goto out;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), p))
|
||||
fputs(buf, stdout);
|
||||
pclose(p);
|
||||
|
||||
out:
|
||||
if (exp_fd >= 0) {
|
||||
close(exp_fd);
|
||||
unlink(exp_path);
|
||||
}
|
||||
if (act_fd >= 0) {
|
||||
close(act_fd);
|
||||
unlink(act_path);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,4 +61,7 @@ int testing_prog_flags(void);
|
|||
bool is_jit_enabled(void);
|
||||
int stack_mprotect(void);
|
||||
|
||||
/* Runs diff(1) on mismatch */
|
||||
int compare_text_to_expected(const char *actual, const char *expected);
|
||||
|
||||
#endif /* __TESTING_HELPERS_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user