[Concept,10/21] test: Add a helper to check the next line against a regex

Message ID 20251214175449.3799539-11-sjg@u-boot.org
State New
Headers
Series test: Add support for passing arguments to C unit tests |

Commit Message

Simon Glass Dec. 14, 2025, 5:54 p.m. UTC
  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(+)
  

Patch

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;