Merge tag 'linux_kselftest-kunit-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kunit updates from Shuah Khan:

 - New parameterized test features

   KUnit parameterized tests supported two primary methods for getting
   parameters:

    - Defining custom logic within a generate_params() function.

    - Using the KUNIT_ARRAY_PARAM() and KUNIT_ARRAY_PARAM_DESC() macros
      with a pre-defined static array and passing the created
      *_gen_params() to KUNIT_CASE_PARAM().

   These methods present limitations when dealing with dynamically
   generated parameter arrays, or in scenarios where populating
   parameters sequentially via generate_params() is inefficient or
   overly complex.

   These limitations are fixed with a parameterized test method

 - Fix issues in kunit build artifacts cleanup

 - Fix parsing skipped test problem in kselftest framework

 - Enable PCI on UML without triggering WARN()

 - a few other fixes and adds support for new configs such as MIPS

* tag 'linux_kselftest-kunit-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kunit: Extend kconfig help text for KUNIT_UML_PCI
  rust: kunit: allow `cfg` on `test`s
  kunit: qemu_configs: Add MIPS configurations
  kunit: Enable PCI on UML without triggering WARN()
  Documentation: kunit: Document new parameterized test features
  kunit: Add example parameterized test with direct dynamic parameter array setup
  kunit: Add example parameterized test with shared resource management using the Resource API
  kunit: Enable direct registration of parameter arrays to a KUnit test
  kunit: Pass parameterized test context to generate_params()
  kunit: Introduce param_init/exit for parameterized test context management
  kunit: Add parent kunit for parameterized test context
  kunit: tool: Accept --raw_output=full as an alias of 'all'
  kunit: tool: Parse skipped tests from kselftest.h
  kunit: Always descend into kunit directory during build
This commit is contained in:
Linus Torvalds
2025-10-01 19:15:11 -07:00
20 changed files with 880 additions and 63 deletions
+90 -5
View 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 *)``
@@ -126,8 +128,11 @@ struct kunit_attributes {
struct kunit_case {
void (*run_case)(struct kunit *test);
const char *name;
const void* (*generate_params)(const void *prev, char *desc);
const void* (*generate_params)(struct kunit *test,
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 +223,31 @@ 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, pass parameter arrays,
* 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.
*
* Note: If you are registering a parameter array in param_init() with
* kunit_register_param_array() then you need to pass kunit_array_gen_params()
* to this as the generator function.
*/
#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
*
@@ -263,19 +293,39 @@ struct kunit_suite_set {
struct kunit_suite * const *end;
};
/* Stores the pointer to the parameter array and its metadata. */
struct kunit_params {
/*
* Reference to the parameter array for a parameterized test. This
* is NULL if a parameter array wasn't directly passed to the
* parameterized test context struct kunit via kunit_register_params_array().
*/
const void *params;
/* Reference to a function that gets the description of a parameter. */
void (*get_description)(struct kunit *test, const void *param, char *desc);
size_t num_params;
size_t elem_size;
};
/**
* struct kunit - represents a running instance of a test.
*
* @priv: for user to store arbitrary data. Commonly used to pass data
* created in the init function (see &struct kunit_suite).
* @parent: reference to the parent context of type struct kunit that can
* be used for storing shared resources.
* @params_array: for storing the parameter array.
*
* Used to store information about the current context under which the test
* is running. Most of this data is private and should only be accessed
* indirectly via public functions; the one exception is @priv which can be
* used by the test writer to store arbitrary data.
* indirectly via public functions; the exceptions are @priv, @parent and
* @params_array which can be used by the test writer to store arbitrary data,
* access the parent context, and to store the parameter array, respectively.
*/
struct kunit {
void *priv;
struct kunit *parent;
struct kunit_params params_array;
/* private: internal use only. */
const char *name; /* Read only after initialization! */
@@ -346,6 +396,8 @@ void kunit_exec_list_tests(struct kunit_suite_set *suite_set, bool include_attr)
struct kunit_suite_set kunit_merge_suite_sets(struct kunit_suite_set init_suite_set,
struct kunit_suite_set suite_set);
const void *kunit_array_gen_params(struct kunit *test, const void *prev, char *desc);
#if IS_BUILTIN(CONFIG_KUNIT)
int kunit_run_all_tests(void);
#else
@@ -1674,9 +1726,12 @@ do { \
* Define function @name_gen_params which uses @array to generate parameters.
*/
#define KUNIT_ARRAY_PARAM(name, array, get_desc) \
static const void *name##_gen_params(const void *prev, char *desc) \
static const void *name##_gen_params(struct kunit *test, \
const void *prev, char *desc) \
{ \
typeof((array)[0]) *__next = prev ? ((typeof(__next)) prev) + 1 : (array); \
if (!prev) \
kunit_register_params_array(test, array, ARRAY_SIZE(array), NULL); \
if (__next - (array) < ARRAY_SIZE((array))) { \
void (*__get_desc)(typeof(__next), char *) = get_desc; \
if (__get_desc) \
@@ -1695,9 +1750,12 @@ do { \
* Define function @name_gen_params which uses @array to generate parameters.
*/
#define KUNIT_ARRAY_PARAM_DESC(name, array, desc_member) \
static const void *name##_gen_params(const void *prev, char *desc) \
static const void *name##_gen_params(struct kunit *test, \
const void *prev, char *desc) \
{ \
typeof((array)[0]) *__next = prev ? ((typeof(__next)) prev) + 1 : (array); \
if (!prev) \
kunit_register_params_array(test, array, ARRAY_SIZE(array), NULL); \
if (__next - (array) < ARRAY_SIZE((array))) { \
strscpy(desc, __next->desc_member, KUNIT_PARAM_DESC_SIZE); \
return __next; \
@@ -1705,6 +1763,33 @@ do { \
return NULL; \
}
/**
* kunit_register_params_array() - Register parameter array for a KUnit test.
* @test: The KUnit test structure to which parameters will be added.
* @array: An array of test parameters.
* @param_count: Number of parameters.
* @get_desc: Function that generates a string description for a given parameter
* element.
*
* This macro initializes the @test's parameter array data, storing information
* including the parameter array, its count, the element size, and the parameter
* description function within `test->params_array`.
*
* Note: If using this macro in param_init(), kunit_array_gen_params()
* will then need to be manually provided as the parameter generator function to
* KUNIT_CASE_PARAM_WITH_INIT(). kunit_array_gen_params() is a KUnit
* function that uses the registered array to generate parameters
*/
#define kunit_register_params_array(test, array, param_count, get_desc) \
do { \
struct kunit *_test = (test); \
const typeof((array)[0]) * _params_ptr = &(array)[0]; \
_test->params_array.params = _params_ptr; \
_test->params_array.num_params = (param_count); \
_test->params_array.elem_size = sizeof(*_params_ptr); \
_test->params_array.get_description = (get_desc); \
} while (0)
// TODO(dlatypov@google.com): consider eventually migrating users to explicitly
// include resource.h themselves if they need it.
#include <kunit/resource.h>