From 20631e154c78f4140fffe111f5c79464fae3c38c Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 28 Aug 2023 11:41:07 +0100 Subject: kunit: string-stream: Add kunit_alloc_string_stream() Add function kunit_alloc_string_stream() to do a resource-managed allocation of a string stream, and corresponding kunit_free_string_stream() to free the resource-managed stream. This is preparing for decoupling the string_stream implementation from struct kunit, to reduce the amount of code churn when that happens. Currently: - kunit_alloc_string_stream() only calls alloc_string_stream(). - kunit_free_string_stream() takes a struct kunit* which isn't used yet. Callers of the old alloc_string_stream() and string_stream_destroy() are all requesting a managed allocation so have been changed to use the new functions. alloc_string_stream() has been temporarily made static because its current behavior has been replaced with kunit_alloc_string_stream(). Signed-off-by: Richard Fitzgerald Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/kunit/test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/kunit/test.c') diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 421f13981412..30807694c459 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -308,7 +308,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc, kunit_set_failure(test); - stream = alloc_string_stream(test, GFP_KERNEL); + stream = kunit_alloc_string_stream(test, GFP_KERNEL); if (IS_ERR(stream)) { WARN(true, "Could not allocate stream to print failed assertion in %s:%d\n", @@ -322,7 +322,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc, kunit_print_string_stream(test, stream); - string_stream_destroy(stream); + kunit_free_string_stream(test, stream); } void __noreturn __kunit_abort(struct kunit *test) -- cgit From a3fdf784780ccb0008d630e8722d1389c49c7499 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 28 Aug 2023 11:41:08 +0100 Subject: kunit: string-stream: Decouple string_stream from kunit Re-work string_stream so that it is not tied to a struct kunit. This is to allow using it for the log of struct kunit_suite. Instead of resource-managing individual allocations the whole string_stream can be resource-managed, if required. alloc_string_stream() now allocates a string stream that is not resource-managed. string_stream_destroy() now works on an unmanaged string_stream allocated by alloc_string_stream() and frees the entire string_stream (previously it only freed the fragments). string_stream_clear() has been made public for callers that want to free the fragments without destroying the string_stream. For resource-managed allocations use kunit_alloc_string_stream() and kunit_free_string_stream(). In addition to this, string_stream_get_string() now returns an unmanaged buffer that the caller must kfree(). Signed-off-by: Richard Fitzgerald Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/kunit/test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/kunit/test.c') diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 30807694c459..bd1ef86fcd71 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -296,7 +296,7 @@ static void kunit_print_string_stream(struct kunit *test, kunit_err(test, "\n"); } else { kunit_err(test, "%s", buf); - kunit_kfree(test, buf); + kfree(buf); } } -- cgit From 05e2006ce493cb6fb5e5b4b8317f82754dfa2b1e Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 28 Aug 2023 11:41:10 +0100 Subject: kunit: Use string_stream for test log Replace the fixed-size log buffer with a string_stream so that the log can grow as lines are added. The existing kunit log tests have been updated for using a string_stream as the log. No new test have been added because there are already tests for the underlying string_stream. As the log tests now depend on string_stream functions they cannot build when kunit-test is a module. They have been surrounded by a #if to replace them with skipping version when the test is build as a module. Though this isn't pretty, it avoids moving code to another file while that code is also being changed. Signed-off-by: Richard Fitzgerald Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/kunit/test.c | 44 +++++--------------------------------------- 1 file changed, 5 insertions(+), 39 deletions(-) (limited to 'lib/kunit/test.c') diff --git a/lib/kunit/test.c b/lib/kunit/test.c index bd1ef86fcd71..651cbda9f250 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -109,51 +109,17 @@ static void kunit_print_test_stats(struct kunit *test, stats.total); } -/** - * kunit_log_newline() - Add newline to the end of log if one is not - * already present. - * @log: The log to add the newline to. - */ -static void kunit_log_newline(char *log) -{ - int log_len, len_left; - - log_len = strlen(log); - len_left = KUNIT_LOG_SIZE - log_len - 1; - - if (log_len > 0 && log[log_len - 1] != '\n') - strncat(log, "\n", len_left); -} - -/* - * Append formatted message to log, size of which is limited to - * KUNIT_LOG_SIZE bytes (including null terminating byte). - */ -void kunit_log_append(char *log, const char *fmt, ...) +/* Append formatted message to log. */ +void kunit_log_append(struct string_stream *log, const char *fmt, ...) { va_list args; - int len, log_len, len_left; if (!log) return; - log_len = strlen(log); - len_left = KUNIT_LOG_SIZE - log_len - 1; - if (len_left <= 0) - return; - - /* Evaluate length of line to add to log */ va_start(args, fmt); - len = vsnprintf(NULL, 0, fmt, args) + 1; + string_stream_vadd(log, fmt, args); va_end(args); - - /* Print formatted line to the log */ - va_start(args, fmt); - vsnprintf(log + log_len, min(len, len_left), fmt, args); - va_end(args); - - /* Add newline to end of log if not already present. */ - kunit_log_newline(log); } EXPORT_SYMBOL_GPL(kunit_log_append); @@ -359,14 +325,14 @@ void __kunit_do_failed_assertion(struct kunit *test, } EXPORT_SYMBOL_GPL(__kunit_do_failed_assertion); -void kunit_init_test(struct kunit *test, const char *name, char *log) +void kunit_init_test(struct kunit *test, const char *name, struct string_stream *log) { spin_lock_init(&test->lock); INIT_LIST_HEAD(&test->resources); test->name = name; test->log = log; if (test->log) - test->log[0] = '\0'; + string_stream_clear(log); test->status = KUNIT_SUCCESS; test->status_comment[0] = '\0'; } -- cgit From ee5f8cc2770b2f0f7cfefb5bf7534e2859e39485 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 31 Aug 2023 23:48:47 +0200 Subject: kunit: Reset test status on each param iteration If we skip one parametrized test case then test status remains SKIP for all subsequent test params leading to wrong reports: $ ./tools/testing/kunit/kunit.py run \ --kunitconfig ./lib/kunit/.kunitconfig *.example_params* --raw_output \ [ ] Starting KUnit Kernel (1/1)... KTAP version 1 1..1 # example: initializing suite KTAP version 1 # Subtest: example # module: kunit_example_test 1..1 KTAP version 1 # Subtest: example_params_test # example_params_test: initializing # example_params_test: cleaning up ok 1 example value 3 # SKIP unsupported param value 3 # example_params_test: initializing # example_params_test: cleaning up ok 2 example value 2 # SKIP unsupported param value 3 # example_params_test: initializing # example_params_test: cleaning up ok 3 example value 1 # SKIP unsupported param value 3 # example_params_test: initializing # example_params_test: cleaning up ok 4 example value 0 # SKIP unsupported param value 0 # example_params_test: pass:0 fail:0 skip:4 total:4 ok 1 example_params_test # SKIP unsupported param value 0 # example: exiting suite ok 1 example # SKIP Reset test status and status comment after each param iteration to avoid using stale results. Signed-off-by: Michal Wajdeczko Cc: David Gow Cc: Rae Moar Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/kunit/test.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/kunit/test.c') diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 651cbda9f250..f2eb71f1a66c 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -614,12 +614,14 @@ int kunit_run_tests(struct kunit_suite *suite) param_desc, test.status_comment); + kunit_update_stats(¶m_stats, test.status); + /* Get next param. */ param_desc[0] = '\0'; test.param_value = test_case->generate_params(test.param_value, param_desc); test.param_index++; - - kunit_update_stats(¶m_stats, test.status); + test.status = KUNIT_SUCCESS; + test.status_comment[0] = '\0'; } } -- cgit