From: Simon Glass <simon.glass@canonical.com> Add a new ut_assert_nextline_regex() macro and ut_check_console_line_regex() helper to check console output against a regex pattern. This is useful when the exact output varies (e.g., file paths or line numbers in error messages). Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- doc/develop/tests_writing.rst | 3 +++ include/test/ut.h | 29 +++++++++++++++++++++++++++++ test/ut.c | 21 +++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/doc/develop/tests_writing.rst b/doc/develop/tests_writing.rst index 43756989d43..41612a9e21b 100644 --- a/doc/develop/tests_writing.rst +++ b/doc/develop/tests_writing.rst @@ -451,6 +451,9 @@ ut_assert_nextlinen(fmt, args...) Assert that the next console output line matches up to the format string length +ut_assert_nextline_regex(pattern) + Assert that the next console output line matches a regex pattern + ut_assert_nextline_empty() Assert that the next console output line is empty diff --git a/include/test/ut.h b/include/test/ut.h index a2b42cdf414..7098c9be7d6 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -87,6 +87,20 @@ int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...) int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...) __attribute__ ((format (__printf__, 2, 3))); +/** + * ut_check_console_line_regex() - Check the next console line against a regex + * + * This checks the next line of console output against a regex pattern. + * + * After the function returns, uts->expect_str holds the regex pattern and + * uts->actual_str holds the actual string read from the console. + * + * @uts: Test state + * @regex: Regular expression pattern to match against + * Return: 0 if OK, other value on error + */ +int ut_check_console_line_regex(struct unit_test_state *uts, const char *regex); + /** * ut_check_skipline() - Check that the next console line exists and skip it * @@ -412,6 +426,21 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) +/* Assert that the next console output line matches a regex pattern */ +#define ut_assert_nextline_regex(pattern) ({ \ + int __ret = 0; \ + \ + if (ut_check_console_line_regex(uts, pattern)) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + "console regex", \ + "\nExpected regex '%s',\n got '%s'", \ + uts->expect_str, uts->actual_str); \ + if (!uts->soft_fail) \ + return CMD_RET_FAILURE; \ + } \ + __ret; \ +}) + /* Assert that there is a 'next' console output line, and skip it */ #define ut_assert_skipline() ({ \ int __ret = 0; \ diff --git a/test/ut.c b/test/ut.c index 94b09364687..aed59cae0b9 100644 --- a/test/ut.c +++ b/test/ut.c @@ -150,6 +150,27 @@ int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...) strlen(uts->expect_str)); } +int ut_check_console_line_regex(struct unit_test_state *uts, const char *regex) +{ + char err[UT_REGEX_ERR_SIZE]; + int len; + int ret; + + len = strlcpy(uts->expect_str, regex, sizeof(uts->expect_str)); + if (len >= sizeof(uts->expect_str)) { + ut_fail(uts, __FILE__, __LINE__, __func__, + "unit_test_state->expect_str too small"); + return -EOVERFLOW; + } + ret = readline_check(uts); + if (ret == -ENOENT) + return 1; + + ret = ut_check_regex(regex, uts->actual_str, err); + + return ret; +} + int ut_check_skipline(struct unit_test_state *uts) { int ret; -- 2.43.0