]> www.infradead.org Git - users/hch/misc.git/commitdiff
kunit: Introduce param_init/exit for parameterized test context management
authorMarie Zhussupova <marievic@google.com>
Tue, 26 Aug 2025 09:13:32 +0000 (17:13 +0800)
committerShuah Khan <skhan@linuxfoundation.org>
Wed, 27 Aug 2025 05:36:03 +0000 (23:36 -0600)
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>
include/kunit/test.h
lib/kunit/test.c
rust/kernel/kunit.rs

index 9766403afd564ecdea9354b691434466aa40728c..fc8fd55b2dfbd186ac309b7709c86ace710ed417 100644 (file)
@@ -92,6 +92,8 @@ struct kunit_attributes {
  * @name:     the name of the test case.
  * @generate_params: the generator function for parameterized tests.
  * @attr:     the attributes associated with the test
+ * @param_init: The init function to run before a parameterized test.
+ * @param_exit: The exit function to run after a parameterized test.
  *
  * A test case is a function with the signature,
  * ``void (*)(struct kunit *)``
@@ -128,6 +130,8 @@ struct kunit_case {
        const char *name;
        const void* (*generate_params)(const void *prev, char *desc);
        struct kunit_attributes attr;
+       int (*param_init)(struct kunit *test);
+       void (*param_exit)(struct kunit *test);
 
        /* private: internal use only. */
        enum kunit_status status;
@@ -218,6 +222,27 @@ static inline char *kunit_status_to_ok_not_ok(enum kunit_status status)
                  .generate_params = gen_params,                                \
                  .attr = attributes, .module_name = KBUILD_MODNAME}
 
+/**
+ * KUNIT_CASE_PARAM_WITH_INIT - Define a parameterized KUnit test case with custom
+ * param_init() and param_exit() functions.
+ * @test_name: The function implementing the test case.
+ * @gen_params: The function to generate parameters for the test case.
+ * @init: A reference to the param_init() function to run before a parameterized test.
+ * @exit: A reference to the param_exit() function to run after a parameterized test.
+ *
+ * Provides the option to register param_init() and param_exit() functions.
+ * param_init/exit will be passed the parameterized test context and run once
+ * before and once after the parameterized test. The init function can be used
+ * to add resources to share between parameter runs, and any other setup logic.
+ * The exit function can be used to clean up resources that were not managed by
+ * the parameterized test, and any other teardown logic.
+ */
+#define KUNIT_CASE_PARAM_WITH_INIT(test_name, gen_params, init, exit)          \
+               { .run_case = test_name, .name = #test_name,                    \
+                 .generate_params = gen_params,                                \
+                 .param_init = init, .param_exit = exit,                       \
+                 .module_name = KBUILD_MODNAME}
+
 /**
  * struct kunit_suite - describes a related collection of &struct kunit_case
  *
index 587b5c51db589387d027a416f42027cd211202ae..0fe61dec5a9680cd7c8a0b9106fabaae8f291813 100644 (file)
@@ -641,6 +641,20 @@ static void kunit_accumulate_stats(struct kunit_result_stats *total,
        total->total += add.total;
 }
 
+static void kunit_init_parent_param_test(struct kunit_case *test_case, struct kunit *test)
+{
+       if (test_case->param_init) {
+               int err = test_case->param_init(test);
+
+               if (err) {
+                       kunit_err(test_case, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
+                               "# failed to initialize parent parameter test (%d)", err);
+                       test->status = KUNIT_FAILURE;
+                       test_case->status = KUNIT_FAILURE;
+               }
+       }
+}
+
 int kunit_run_tests(struct kunit_suite *suite)
 {
        char param_desc[KUNIT_PARAM_DESC_SIZE];
@@ -678,6 +692,11 @@ int kunit_run_tests(struct kunit_suite *suite)
                        kunit_run_case_catch_errors(suite, test_case, &test);
                        kunit_update_stats(&param_stats, test.status);
                } else {
+                       kunit_init_parent_param_test(test_case, &test);
+                       if (test_case->status == KUNIT_FAILURE) {
+                               kunit_update_stats(&param_stats, test.status);
+                               goto test_case_end;
+                       }
                        /* Get initial param. */
                        param_desc[0] = '\0';
                        /* TODO: Make generate_params try-catch */
@@ -714,10 +733,16 @@ int kunit_run_tests(struct kunit_suite *suite)
                                param_desc[0] = '\0';
                                curr_param = test_case->generate_params(curr_param, param_desc);
                        }
+                       /*
+                        * TODO: Put into a try catch. Since we don't need suite->exit
+                        * for it we can't reuse kunit_try_run_cleanup for this yet.
+                        */
+                       if (test_case->param_exit)
+                               test_case->param_exit(&test);
                        /* TODO: Put this kunit_cleanup into a try-catch. */
                        kunit_cleanup(&test);
                }
-
+test_case_end:
                kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE);
 
                kunit_print_test_stats(&test, param_stats);
index 41efd87595d6ea1c537f6a15cda2dd931a130bcc..b1c97f8029c7d0ac25ff4a587a8138d1e797e88a 100644 (file)
@@ -210,6 +210,8 @@ pub const fn kunit_case(
         status: kernel::bindings::kunit_status_KUNIT_SUCCESS,
         module_name: core::ptr::null_mut(),
         log: core::ptr::null_mut(),
+        param_init: None,
+        param_exit: None,
     }
 }
 
@@ -229,6 +231,8 @@ pub const fn kunit_case_null() -> kernel::bindings::kunit_case {
         status: kernel::bindings::kunit_status_KUNIT_SUCCESS,
         module_name: core::ptr::null_mut(),
         log: core::ptr::null_mut(),
+        param_init: None,
+        param_exit: None,
     }
 }