diff --git a/include/test/test.h b/include/test/test.h index e5bef4759a6f88c28929e33e1fed7ea030d14829..2a75211008323a833af62bfc315e13a6ad099a1d 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -15,12 +15,16 @@ * @start: Store the starting mallinfo when doing leak test * @priv: A pointer to some other info some suites want to track * @of_root: Record of the livetree root node (used for setting up tests) + * @expect_str: Temporary string used to hold expected string value + * @actual_str: Temporary string used to hold actual string value */ struct unit_test_state { int fail_count; struct mallinfo start; void *priv; struct device_node *of_root; + char expect_str[256]; + char actual_str[256]; }; /** diff --git a/include/test/ut.h b/include/test/ut.h index c9fc9cc8395bb91b323106357cff884494b130cd..04df8ba3af319d5c2dde28e1dd979825b7ecd7a3 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -38,6 +38,43 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, const char *func, const char *cond, const char *fmt, ...) __attribute__ ((format (__printf__, 6, 7))); +/** + * ut_check_console_line() - Check the next console line against expectations + * + * This creates a string and then checks it against the next line of console + * output obtained with console_record_readline(). + * + * After the function returns, uts->expect_str holds the expected string and + * uts->actual_str holds the actual string read from the console. + * + * @uts: Test state + * @fmt: printf() format string for the error, followed by args + * @return 0 if OK, other value on error + */ +int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...) + __attribute__ ((format (__printf__, 2, 3))); + +/** + * ut_check_console_end() - Check there is no more console output + * + * After the function returns, uts->actual_str holds the actual string read + * from the console + * + * @uts: Test state + * @return 0 if OK (console has no output), other value on error + */ +int ut_check_console_end(struct unit_test_state *uts); + +/** + * ut_check_console_dump() - Check that next lines have a print_buffer() dump + * + * This only supports a byte dump. + * + * @total_bytes: Size of the expected dump in bytes` + * @return 0 if OK (looks like a dump and the length matches), other value on + * error + */ +int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); /* Assert that a condition is non-zero */ #define ut_assert(cond) \ @@ -149,6 +186,34 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, /* Assert that an operation succeeds (returns 0) */ #define ut_assertok(cond) ut_asserteq(0, cond) +/* Assert that the next console output line matches */ +#define ut_assert_nextline(fmt, args...) \ + if (ut_check_console_line(uts, fmt, ##args)) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + "console", "\nExpected '%s',\n got '%s'", \ + uts->expect_str, uts->actual_str); \ + return CMD_RET_FAILURE; \ + } \ + +/* Assert that there is no more console output */ +#define ut_assert_console_end() \ + if (ut_check_console_end(uts)) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + "console", "Expected no more output, got '%s'",\ + uts->actual_str); \ + return CMD_RET_FAILURE; \ + } \ + +/* Assert that the next lines are print_buffer() dump at an address */ +#define ut_assert_nextlines_are_dump(total_bytes) \ + if (ut_check_console_dump(uts, total_bytes)) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + "console", \ + "Expected dump of length %x bytes, got '%s'", \ + total_bytes, uts->actual_str); \ + return CMD_RET_FAILURE; \ + } \ + /** * ut_check_free() - Return the number of bytes free in the malloc() pool * diff --git a/test/ut.c b/test/ut.c index 265da4a0d89a8d05fa50e39751c32e6b52ed1119..c64f0b554d5788be57eafcc88327e12d50c1bacd 100644 --- a/test/ut.c +++ b/test/ut.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -46,3 +47,48 @@ long ut_check_delta(ulong last) return ut_check_free() - last; } +int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args); + va_end(args); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + + return strcmp(uts->expect_str, uts->actual_str); +} + +int ut_check_console_end(struct unit_test_state *uts) +{ + if (!console_record_avail()) + return 0; + + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + + return 1; +} + +int ut_check_console_dump(struct unit_test_state *uts, int total_bytes) +{ + char *str = uts->actual_str; + int upto; + + /* Handle empty dump */ + if (!total_bytes) + return 0; + + for (upto = 0; upto < total_bytes;) { + int len; + int bytes; + + len = console_record_readline(str, sizeof(uts->actual_str)); + if (str[8] != ':' || str[9] != ' ') + return 1; + + bytes = len - 8 - 2 - 3 * 16 - 4; + upto += bytes; + } + + return upto == total_bytes ? 0 : 1; +}