mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
kunit,rust: Add ability to skip entire test suites
Currently, KUnit provides mechanisms to skip individual test cases, but there is no way to skip an entire test suite based on runtime conditions checked during suite initialization. This limitation forces test suites to either fail or skip tests individually when certain prerequisites are not available. To address this limitation, the patch adds a 'status' field to struct kunit_suite that allows suite_init callbacks to mark the entire suite as KUNIT_SKIPPED. When a suite is marked as skipped, all test cases within that suite are bypassed without execution. The patch proposed changes to kunit_suite_has_succeeded() to Check suite status before evaluating individual test case results. Also kunit_run_tests() is updated to skip suite execution if kunit_suite's 'status' is KUNIT_SKIPPED, thats either set before suite_init or by the suite_init callback itself. kunit_init_suite() is updated to initialize the 'status' of kunit_suite to KUNIT_SUCCESS so that any skipped suite's can be restarted from debugfs. This enables test suites to perform runtime capability checks in their 'suite_init' callback and gracefully skip all tests when prerequisites are not met, rather than reporting failures or requiring each test case to perform redundant checks. In case a kunit-suite is skipped it can be re-run from the kunit's debugfs interface. Also update debugfs_print_results() to clearly log the kunit-suite as 'SKIP'. kunit_suite_has_succeeded() is also updated on which debugfs_print_results() depends to update 'kunit_suite.status' in case any of the kunit_case has failed. Finally, update KUnit Rust binding macro-rule 'kunit_unsafe_test_suite' to add and initialize the newly introduced 'kunit_suite.status'. Without this 'kunit_suite.status' field is never initialized which is an error for the Rust compiler. Link: https://patchwork.kernel.org/project/linux-kselftest/patch/20260626085811.151133-2-vaibhav@linux.ibm.com/mbox/ Reviewed-by: David Gow <david@davidgow.net> Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
@@ -285,6 +285,7 @@ struct kunit_suite {
|
||||
struct string_stream *log;
|
||||
int suite_init_err;
|
||||
bool is_init;
|
||||
enum kunit_status status;
|
||||
};
|
||||
|
||||
/* Stores an array of suites, end points one past the end */
|
||||
|
||||
+20
-8
@@ -76,18 +76,30 @@ static int debugfs_print_results(struct seq_file *seq, void *v)
|
||||
seq_puts(seq, "KTAP version 1\n");
|
||||
seq_puts(seq, "1..1\n");
|
||||
|
||||
/* Print suite header because it is not stored in the test logs. */
|
||||
seq_puts(seq, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
|
||||
seq_printf(seq, KUNIT_SUBTEST_INDENT "# Subtest: %s\n", suite->name);
|
||||
seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
|
||||
if (suite->status != KUNIT_SKIPPED) {
|
||||
/* Print suite header because it is not stored in the test logs. */
|
||||
seq_puts(seq,
|
||||
KUNIT_SUBTEST_INDENT "KTAP version 1\n");
|
||||
seq_printf(seq,
|
||||
KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
|
||||
suite->name);
|
||||
seq_printf(seq,
|
||||
KUNIT_SUBTEST_INDENT "1..%zd\n",
|
||||
kunit_suite_num_test_cases(suite));
|
||||
|
||||
kunit_suite_for_each_test_case(suite, test_case)
|
||||
debugfs_print_result(seq, test_case->log);
|
||||
kunit_suite_for_each_test_case(suite, test_case)
|
||||
debugfs_print_result(seq, test_case->log);
|
||||
}
|
||||
|
||||
debugfs_print_result(seq, suite->log);
|
||||
|
||||
seq_printf(seq, "%s %d %s\n",
|
||||
kunit_status_to_ok_not_ok(success), 1, suite->name);
|
||||
if (suite->status != KUNIT_SKIPPED)
|
||||
seq_printf(seq, "%s %d %s\n",
|
||||
kunit_status_to_ok_not_ok(success), 1, suite->name);
|
||||
else
|
||||
seq_printf(seq, "%s %d %s # SKIP %s\n",
|
||||
kunit_status_to_ok_not_ok(success), 1, suite->name,
|
||||
suite->status_comment);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+16
-1
@@ -214,12 +214,18 @@ enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
|
||||
const struct kunit_case *test_case;
|
||||
enum kunit_status status = KUNIT_SKIPPED;
|
||||
|
||||
if (suite->status == KUNIT_SKIPPED)
|
||||
return KUNIT_SKIPPED;
|
||||
|
||||
if (suite->suite_init_err)
|
||||
return KUNIT_FAILURE;
|
||||
|
||||
kunit_suite_for_each_test_case(suite, test_case) {
|
||||
if (test_case->status == KUNIT_FAILURE)
|
||||
if (test_case->status == KUNIT_FAILURE) {
|
||||
/* Update the kunit_suite status also */
|
||||
suite->status = KUNIT_FAILURE;
|
||||
return KUNIT_FAILURE;
|
||||
}
|
||||
else if (test_case->status == KUNIT_SUCCESS)
|
||||
status = KUNIT_SUCCESS;
|
||||
}
|
||||
@@ -795,12 +801,20 @@ int kunit_run_tests(struct kunit_suite *suite)
|
||||
/* Taint the kernel so we know we've run tests. */
|
||||
add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
|
||||
|
||||
if (suite->status == KUNIT_SKIPPED)
|
||||
goto suite_end;
|
||||
|
||||
if (suite->suite_init) {
|
||||
suite->suite_init_err = suite->suite_init(suite);
|
||||
if (suite->suite_init_err) {
|
||||
suite->status = KUNIT_FAILURE;
|
||||
kunit_err(suite, KUNIT_SUBTEST_INDENT
|
||||
"# failed to initialize (%d)", suite->suite_init_err);
|
||||
goto suite_end;
|
||||
|
||||
} else if (suite->status == KUNIT_SKIPPED) {
|
||||
/* Skip this kunit suite */
|
||||
goto suite_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,6 +839,7 @@ static void kunit_init_suite(struct kunit_suite *suite)
|
||||
kunit_debugfs_create_suite(suite);
|
||||
suite->status_comment[0] = '\0';
|
||||
suite->suite_init_err = 0;
|
||||
suite->status = KUNIT_SUCCESS;
|
||||
|
||||
if (suite->log)
|
||||
string_stream_clear(suite->log);
|
||||
|
||||
@@ -288,6 +288,7 @@ macro_rules! kunit_unsafe_test_suite {
|
||||
log: ::core::ptr::null_mut(),
|
||||
suite_init_err: 0,
|
||||
is_init: false,
|
||||
status: kernel::bindings::kunit_status_KUNIT_SUCCESS,
|
||||
};
|
||||
|
||||
#[used(compiler)]
|
||||
|
||||
Reference in New Issue
Block a user