mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04:00
Merge tag 'linux-kselftest-kunit-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull KUnit updates from Shuah Khan:
"This KUnit update for Linux 5.15-rc1 adds new features and tests:
Tool:
- support for '--kernel_args' to allow setting module params
- support for '--raw_output' option to show just the kunit output
during make
Tests:
- new KUnit tests for checksums and timestamps
- Print test statistics on failure
- Integrates UBSAN into the KUnit testing framework. It fails KUnit
tests whenever it reports undefined behavior"
* tag 'linux-kselftest-kunit-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
kunit: Print test statistics on failure
kunit: tool: make --raw_output support only showing kunit output
kunit: tool: add --kernel_args to allow setting module params
kunit: ubsan integration
fat: Add KUnit tests for checksums and timestamps
This commit is contained in:
109
lib/kunit/test.c
109
lib/kunit/test.c
@@ -10,6 +10,7 @@
|
||||
#include <kunit/test-bug.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -51,6 +52,51 @@ void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...)
|
||||
EXPORT_SYMBOL_GPL(__kunit_fail_current_test);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* KUnit statistic mode:
|
||||
* 0 - disabled
|
||||
* 1 - only when there is more than one subtest
|
||||
* 2 - enabled
|
||||
*/
|
||||
static int kunit_stats_enabled = 1;
|
||||
module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);
|
||||
MODULE_PARM_DESC(stats_enabled,
|
||||
"Print test stats: never (0), only for multiple subtests (1), or always (2)");
|
||||
|
||||
struct kunit_result_stats {
|
||||
unsigned long passed;
|
||||
unsigned long skipped;
|
||||
unsigned long failed;
|
||||
unsigned long total;
|
||||
};
|
||||
|
||||
static bool kunit_should_print_stats(struct kunit_result_stats stats)
|
||||
{
|
||||
if (kunit_stats_enabled == 0)
|
||||
return false;
|
||||
|
||||
if (kunit_stats_enabled == 2)
|
||||
return true;
|
||||
|
||||
return (stats.total > 1);
|
||||
}
|
||||
|
||||
static void kunit_print_test_stats(struct kunit *test,
|
||||
struct kunit_result_stats stats)
|
||||
{
|
||||
if (!kunit_should_print_stats(stats))
|
||||
return;
|
||||
|
||||
kunit_log(KERN_INFO, test,
|
||||
KUNIT_SUBTEST_INDENT
|
||||
"# %s: pass:%lu fail:%lu skip:%lu total:%lu",
|
||||
test->name,
|
||||
stats.passed,
|
||||
stats.failed,
|
||||
stats.skipped,
|
||||
stats.total);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append formatted message to log, size of which is limited to
|
||||
* KUNIT_LOG_SIZE bytes (including null terminating byte).
|
||||
@@ -393,15 +439,69 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
|
||||
test_case->status = KUNIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void kunit_print_suite_stats(struct kunit_suite *suite,
|
||||
struct kunit_result_stats suite_stats,
|
||||
struct kunit_result_stats param_stats)
|
||||
{
|
||||
if (kunit_should_print_stats(suite_stats)) {
|
||||
kunit_log(KERN_INFO, suite,
|
||||
"# %s: pass:%lu fail:%lu skip:%lu total:%lu",
|
||||
suite->name,
|
||||
suite_stats.passed,
|
||||
suite_stats.failed,
|
||||
suite_stats.skipped,
|
||||
suite_stats.total);
|
||||
}
|
||||
|
||||
if (kunit_should_print_stats(param_stats)) {
|
||||
kunit_log(KERN_INFO, suite,
|
||||
"# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
|
||||
param_stats.passed,
|
||||
param_stats.failed,
|
||||
param_stats.skipped,
|
||||
param_stats.total);
|
||||
}
|
||||
}
|
||||
|
||||
static void kunit_update_stats(struct kunit_result_stats *stats,
|
||||
enum kunit_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case KUNIT_SUCCESS:
|
||||
stats->passed++;
|
||||
break;
|
||||
case KUNIT_SKIPPED:
|
||||
stats->skipped++;
|
||||
break;
|
||||
case KUNIT_FAILURE:
|
||||
stats->failed++;
|
||||
break;
|
||||
}
|
||||
|
||||
stats->total++;
|
||||
}
|
||||
|
||||
static void kunit_accumulate_stats(struct kunit_result_stats *total,
|
||||
struct kunit_result_stats add)
|
||||
{
|
||||
total->passed += add.passed;
|
||||
total->skipped += add.skipped;
|
||||
total->failed += add.failed;
|
||||
total->total += add.total;
|
||||
}
|
||||
|
||||
int kunit_run_tests(struct kunit_suite *suite)
|
||||
{
|
||||
char param_desc[KUNIT_PARAM_DESC_SIZE];
|
||||
struct kunit_case *test_case;
|
||||
struct kunit_result_stats suite_stats = { 0 };
|
||||
struct kunit_result_stats total_stats = { 0 };
|
||||
|
||||
kunit_print_subtest_start(suite);
|
||||
|
||||
kunit_suite_for_each_test_case(suite, test_case) {
|
||||
struct kunit test = { .param_value = NULL, .param_index = 0 };
|
||||
struct kunit_result_stats param_stats = { 0 };
|
||||
test_case->status = KUNIT_SKIPPED;
|
||||
|
||||
if (test_case->generate_params) {
|
||||
@@ -431,14 +531,23 @@ int kunit_run_tests(struct kunit_suite *suite)
|
||||
test.param_value = test_case->generate_params(test.param_value, param_desc);
|
||||
test.param_index++;
|
||||
}
|
||||
|
||||
kunit_update_stats(¶m_stats, test.status);
|
||||
|
||||
} while (test.param_value);
|
||||
|
||||
kunit_print_test_stats(&test, param_stats);
|
||||
|
||||
kunit_print_ok_not_ok(&test, true, test_case->status,
|
||||
kunit_test_case_num(suite, test_case),
|
||||
test_case->name,
|
||||
test.status_comment);
|
||||
|
||||
kunit_update_stats(&suite_stats, test_case->status);
|
||||
kunit_accumulate_stats(&total_stats, param_stats);
|
||||
}
|
||||
|
||||
kunit_print_suite_stats(suite, suite_stats, total_stats);
|
||||
kunit_print_subtest_end(suite);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <kunit/test-bug.h>
|
||||
|
||||
#include "ubsan.h"
|
||||
|
||||
@@ -141,6 +142,8 @@ static void ubsan_prologue(struct source_location *loc, const char *reason)
|
||||
"========================================\n");
|
||||
pr_err("UBSAN: %s in %s:%d:%d\n", reason, loc->file_name,
|
||||
loc->line & LINE_MASK, loc->column & COLUMN_MASK);
|
||||
|
||||
kunit_fail_current_test("%s in %s", reason, loc->file_name);
|
||||
}
|
||||
|
||||
static void ubsan_epilogue(void)
|
||||
|
||||
Reference in New Issue
Block a user