brintos

brintos / linux-shallow public Read only

0
0
Text · 8.0 KiB · f335f88 Raw
197 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3==================4KUnit Architecture5==================6 7The KUnit architecture is divided into two parts:8 9- `In-Kernel Testing Framework`_10- `kunit_tool (Command-line Test Harness)`_11 12In-Kernel Testing Framework13===========================14 15The kernel testing library supports KUnit tests written in C using16KUnit. These KUnit tests are kernel code. KUnit performs the following17tasks:18 19- Organizes tests20- Reports test results21- Provides test utilities22 23Test Cases24----------25 26The test case is the fundamental unit in KUnit. KUnit test cases are organised27into suites. A KUnit test case is a function with type signature28``void (*)(struct kunit *test)``. These test case functions are wrapped in a29struct called struct kunit_case.30 31.. note:32	``generate_params`` is optional for non-parameterized tests.33 34Each KUnit test case receives a ``struct kunit`` context object that tracks a35running test. The KUnit assertion macros and other KUnit utilities use the36``struct kunit`` context object. As an exception, there are two fields:37 38- ``->priv``: The setup functions can use it to store arbitrary test39  user data.40 41- ``->param_value``: It contains the parameter value which can be42  retrieved in the parameterized tests.43 44Test Suites45-----------46 47A KUnit suite includes a collection of test cases. The KUnit suites48are represented by the ``struct kunit_suite``. For example:49 50.. code-block:: c51 52	static struct kunit_case example_test_cases[] = {53		KUNIT_CASE(example_test_foo),54		KUNIT_CASE(example_test_bar),55		KUNIT_CASE(example_test_baz),56		{}57	};58 59	static struct kunit_suite example_test_suite = {60		.name = "example",61		.init = example_test_init,62		.exit = example_test_exit,63		.test_cases = example_test_cases,64	};65	kunit_test_suite(example_test_suite);66 67In the above example, the test suite ``example_test_suite``, runs the68test cases ``example_test_foo``, ``example_test_bar``, and69``example_test_baz``. Before running the test, the ``example_test_init``70is called and after running the test, ``example_test_exit`` is called.71The ``kunit_test_suite(example_test_suite)`` registers the test suite72with the KUnit test framework.73 74Executor75--------76 77The KUnit executor can list and run built-in KUnit tests on boot.78The Test suites are stored in a linker section79called ``.kunit_test_suites``. For the code, see ``KUNIT_TABLE()`` macro80definition in81`include/asm-generic/vmlinux.lds.h <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/asm-generic/vmlinux.lds.h?h=v6.0#n950>`_.82The linker section consists of an array of pointers to83``struct kunit_suite``, and is populated by the ``kunit_test_suites()``84macro. The KUnit executor iterates over the linker section array in order to85run all the tests that are compiled into the kernel.86 87.. kernel-figure:: kunit_suitememorydiagram.svg88	:alt:	KUnit Suite Memory89 90	KUnit Suite Memory Diagram91 92On the kernel boot, the KUnit executor uses the start and end addresses93of this section to iterate over and run all tests. For the implementation of the94executor, see95`lib/kunit/executor.c <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kunit/executor.c>`_.96When built as a module, the ``kunit_test_suites()`` macro defines a97``module_init()`` function, which runs all the tests in the compilation98unit instead of utilizing the executor.99 100In KUnit tests, some error classes do not affect other tests101or parts of the kernel, each KUnit case executes in a separate thread102context. See the ``kunit_try_catch_run()`` function in103`lib/kunit/try-catch.c <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kunit/try-catch.c?h=v5.15#n58>`_.104 105Assertion Macros106----------------107 108KUnit tests verify state using expectations/assertions.109All expectations/assertions are formatted as:110``KUNIT_{EXPECT|ASSERT}_<op>[_MSG](kunit, property[, message])``111 112- ``{EXPECT|ASSERT}`` determines whether the check is an assertion or an113  expectation.114  In the event of a failure, the testing flow differs as follows:115 116	- For expectations, the test is marked as failed and the failure is logged.117 118	- Failing assertions, on the other hand, result in the test case being119	  terminated immediately.120 121		- Assertions call the function:122		  ``void __noreturn __kunit_abort(struct kunit *)``.123 124		- ``__kunit_abort`` calls the function:125		  ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``.126 127		- ``kunit_try_catch_throw`` calls the function:128		  ``void kthread_complete_and_exit(struct completion *, long) __noreturn;``129		  and terminates the special thread context.130 131- ``<op>`` denotes a check with options: ``TRUE`` (supplied property132  has the boolean value "true"), ``EQ`` (two supplied properties are133  equal), ``NOT_ERR_OR_NULL`` (supplied pointer is not null and does not134  contain an "err" value).135 136- ``[_MSG]`` prints a custom message on failure.137 138Test Result Reporting139---------------------140KUnit prints the test results in KTAP format. KTAP is based on TAP14, see141Documentation/dev-tools/ktap.rst.142KTAP works with KUnit and Kselftest. The KUnit executor prints KTAP results to143dmesg, and debugfs (if configured).144 145Parameterized Tests146-------------------147 148Each KUnit parameterized test is associated with a collection of149parameters. The test is invoked multiple times, once for each parameter150value and the parameter is stored in the ``param_value`` field.151The test case includes a KUNIT_CASE_PARAM() macro that accepts a152generator function. The generator function is passed the previous parameter153and returns the next parameter. It also includes a macro for generating154array-based common-case generators.155 156kunit_tool (Command-line Test Harness)157======================================158 159``kunit_tool`` is a Python script, found in ``tools/testing/kunit/kunit.py``. It160is used to configure, build, execute, parse test results and run all of the161previous commands in correct order (i.e., configure, build, execute and parse).162You have two options for running KUnit tests: either build the kernel with KUnit163enabled and manually parse the results (see164Documentation/dev-tools/kunit/run_manual.rst) or use ``kunit_tool``165(see Documentation/dev-tools/kunit/run_wrapper.rst).166 167- ``configure`` command generates the kernel ``.config`` from a168  ``.kunitconfig`` file (and any architecture-specific options).169  The Python scripts available in ``qemu_configs`` folder170  (for example, ``tools/testing/kunit/qemu configs/powerpc.py``) contains171  additional configuration options for specific architectures.172  It parses both the existing ``.config`` and the ``.kunitconfig`` files173  to ensure that ``.config`` is a superset of ``.kunitconfig``.174  If not, it will combine the two and run ``make olddefconfig`` to regenerate175  the ``.config`` file. It then checks to see if ``.config`` has become a superset.176  This verifies that all the Kconfig dependencies are correctly specified in the177  file ``.kunitconfig``. The ``kunit_config.py`` script contains the code for parsing178  Kconfigs. The code which runs ``make olddefconfig`` is part of the179  ``kunit_kernel.py`` script. You can invoke this command through:180  ``./tools/testing/kunit/kunit.py config`` and181  generate a ``.config`` file.182- ``build`` runs ``make`` on the kernel tree with required options183  (depends on the architecture and some options, for example: build_dir)184  and reports any errors.185  To build a KUnit kernel from the current ``.config``, you can use the186  ``build`` argument: ``./tools/testing/kunit/kunit.py build``.187- ``exec`` command executes kernel results either directly (using188  User-mode Linux configuration), or through an emulator such189  as QEMU. It reads results from the log using standard190  output (stdout), and passes them to ``parse`` to be parsed.191  If you already have built a kernel with built-in KUnit tests,192  you can run the kernel and display the test results with the ``exec``193  argument: ``./tools/testing/kunit/kunit.py exec``.194- ``parse`` extracts the KTAP output from a kernel log, parses195  the test results, and prints a summary. For failed tests, any196  diagnostic output will be included.197