Skip to content

Commit 2414235

Browse files
Marie Zhussupovashuahkh
authored andcommitted
kunit: Introduce param_init/exit for parameterized test context management
Add (*param_init) and (*param_exit) function pointers to `struct kunit_case`. Users will be able to set them via the new KUNIT_CASE_PARAM_WITH_INIT() macro. param_init/exit will be invoked by kunit_run_tests() once before and once after the parameterized test, respectively. They will receive the `struct kunit` that holds the parameterized test context; facilitating init and exit for shared state. This patch also sets param_init/exit to None in rust/kernel/kunit.rs. Link: https://lore.kernel.org/r/20250826091341.1427123-3-davidgow@google.com Reviewed-by: Rae Moar <rmoar@google.com> Reviewed-by: David Gow <davidgow@google.com> Signed-off-by: Marie Zhussupova <marievic@google.com> Signed-off-by: David Gow <davidgow@google.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent 4b59300 commit 2414235

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

include/kunit/test.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ struct kunit_attributes {
9292
* @name: the name of the test case.
9393
* @generate_params: the generator function for parameterized tests.
9494
* @attr: the attributes associated with the test
95+
* @param_init: The init function to run before a parameterized test.
96+
* @param_exit: The exit function to run after a parameterized test.
9597
*
9698
* A test case is a function with the signature,
9799
* ``void (*)(struct kunit *)``
@@ -128,6 +130,8 @@ struct kunit_case {
128130
const char *name;
129131
const void* (*generate_params)(const void *prev, char *desc);
130132
struct kunit_attributes attr;
133+
int (*param_init)(struct kunit *test);
134+
void (*param_exit)(struct kunit *test);
131135

132136
/* private: internal use only. */
133137
enum kunit_status status;
@@ -218,6 +222,27 @@ static inline char *kunit_status_to_ok_not_ok(enum kunit_status status)
218222
.generate_params = gen_params, \
219223
.attr = attributes, .module_name = KBUILD_MODNAME}
220224

225+
/**
226+
* KUNIT_CASE_PARAM_WITH_INIT - Define a parameterized KUnit test case with custom
227+
* param_init() and param_exit() functions.
228+
* @test_name: The function implementing the test case.
229+
* @gen_params: The function to generate parameters for the test case.
230+
* @init: A reference to the param_init() function to run before a parameterized test.
231+
* @exit: A reference to the param_exit() function to run after a parameterized test.
232+
*
233+
* Provides the option to register param_init() and param_exit() functions.
234+
* param_init/exit will be passed the parameterized test context and run once
235+
* before and once after the parameterized test. The init function can be used
236+
* to add resources to share between parameter runs, and any other setup logic.
237+
* The exit function can be used to clean up resources that were not managed by
238+
* the parameterized test, and any other teardown logic.
239+
*/
240+
#define KUNIT_CASE_PARAM_WITH_INIT(test_name, gen_params, init, exit) \
241+
{ .run_case = test_name, .name = #test_name, \
242+
.generate_params = gen_params, \
243+
.param_init = init, .param_exit = exit, \
244+
.module_name = KBUILD_MODNAME}
245+
221246
/**
222247
* struct kunit_suite - describes a related collection of &struct kunit_case
223248
*

lib/kunit/test.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,20 @@ static void kunit_accumulate_stats(struct kunit_result_stats *total,
641641
total->total += add.total;
642642
}
643643

644+
static void kunit_init_parent_param_test(struct kunit_case *test_case, struct kunit *test)
645+
{
646+
if (test_case->param_init) {
647+
int err = test_case->param_init(test);
648+
649+
if (err) {
650+
kunit_err(test_case, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
651+
"# failed to initialize parent parameter test (%d)", err);
652+
test->status = KUNIT_FAILURE;
653+
test_case->status = KUNIT_FAILURE;
654+
}
655+
}
656+
}
657+
644658
int kunit_run_tests(struct kunit_suite *suite)
645659
{
646660
char param_desc[KUNIT_PARAM_DESC_SIZE];
@@ -678,6 +692,11 @@ int kunit_run_tests(struct kunit_suite *suite)
678692
kunit_run_case_catch_errors(suite, test_case, &test);
679693
kunit_update_stats(&param_stats, test.status);
680694
} else {
695+
kunit_init_parent_param_test(test_case, &test);
696+
if (test_case->status == KUNIT_FAILURE) {
697+
kunit_update_stats(&param_stats, test.status);
698+
goto test_case_end;
699+
}
681700
/* Get initial param. */
682701
param_desc[0] = '\0';
683702
/* TODO: Make generate_params try-catch */
@@ -714,10 +733,16 @@ int kunit_run_tests(struct kunit_suite *suite)
714733
param_desc[0] = '\0';
715734
curr_param = test_case->generate_params(curr_param, param_desc);
716735
}
736+
/*
737+
* TODO: Put into a try catch. Since we don't need suite->exit
738+
* for it we can't reuse kunit_try_run_cleanup for this yet.
739+
*/
740+
if (test_case->param_exit)
741+
test_case->param_exit(&test);
717742
/* TODO: Put this kunit_cleanup into a try-catch. */
718743
kunit_cleanup(&test);
719744
}
720-
745+
test_case_end:
721746
kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE);
722747

723748
kunit_print_test_stats(&test, param_stats);

rust/kernel/kunit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ pub const fn kunit_case(
210210
status: kernel::bindings::kunit_status_KUNIT_SUCCESS,
211211
module_name: core::ptr::null_mut(),
212212
log: core::ptr::null_mut(),
213+
param_init: None,
214+
param_exit: None,
213215
}
214216
}
215217

@@ -229,6 +231,8 @@ pub const fn kunit_case_null() -> kernel::bindings::kunit_case {
229231
status: kernel::bindings::kunit_status_KUNIT_SUCCESS,
230232
module_name: core::ptr::null_mut(),
231233
log: core::ptr::null_mut(),
234+
param_init: None,
235+
param_exit: None,
232236
}
233237
}
234238

0 commit comments

Comments
 (0)