Thread (22 messages) 22 messages, 3 authors, 2021-12-16

Re: [PATCH v2 3/7] Documentation: KUnit: Added KUnit Architecture

From: Harinder Singh <hidden>
Date: 2021-12-10 05:31:32
Also in: linux-kselftest, lkml

Hello Tim,

Thanks for your review.

See my comments below.

On Tue, Dec 7, 2021 at 10:54 PM [off-list ref] wrote:
quoted
-----Original Message-----
From: Harinder Singh <redacted>

Describe the components of KUnit and how the kernel mode parts
interact with kunit_tool.

Signed-off-by: Harinder Singh <redacted>
---
 .../dev-tools/kunit/architecture.rst          | 206 ++++++++++++++++++
 Documentation/dev-tools/kunit/index.rst       |   2 +
 .../kunit/kunit_suitememorydiagram.png        | Bin 0 -> 24174 bytes
 Documentation/dev-tools/kunit/start.rst       |   1 +
 4 files changed, 209 insertions(+)
 create mode 100644 Documentation/dev-tools/kunit/architecture.rst
 create mode 100644 Documentation/dev-tools/kunit/kunit_suitememorydiagram.png
diff --git a/Documentation/dev-tools/kunit/architecture.rst b/Documentation/dev-tools/kunit/architecture.rst
new file mode 100644
index 000000000000..bb0fb3e3ed01
--- /dev/null
+++ b/Documentation/dev-tools/kunit/architecture.rst
@@ -0,0 +1,206 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==================
+KUnit Architecture
+==================
+
+The KUnit architecture can be divided into two parts:
+
+- Kernel testing library
+- kunit_tool (Command line test harness)
+
+In-Kernel Testing Framework
+===========================
+
+The kernel testing library supports KUnit tests written in C using
+KUnit. KUnit tests are kernel code. KUnit does several things:
+
+- Organizes tests
+- Reports test results
+- Provides test utilities
+
+Test Cases
+----------
+
+The fundamental unit in KUnit is the test case. The KUnit test cases are
+grouped into KUnit suites. A KUnit test case is a function with type
+signature ``void (*)(struct kunit *test)``.
+These test case functions are wrapped in a struct called
+``struct kunit_case``. For code, see:
+https://elixir.bootlin.com/linux/latest/source/include/kunit/test.h#L145
+
+It includes:
+
+- ``run_case``: the function implementing the actual test case.
+- ``name``: the test case name.
+- ``generate_params``: the parameterized tests generator function. This
+  is optional for non-parameterized tests.
+
+Each KUnit test case gets a ``struct kunit`` context
+object passed to it that tracks a running test. The KUnit assertion
+macros and other KUnit utilities use the ``struct kunit`` context
+object. As an exception, there are two fields:
+
+- ``->priv``: The setup functions can use it to store arbitrary test
+  user data.
+
+- ``->param_value``: It contains the parameter value which can be
+  retrieved in the parameterized tests.
+
+Test Suites
+-----------
+
+A KUnit suite includes a collection of test cases. The KUnit suites
+are represented by the ``struct kunit_suite``. For example:
+
+.. code-block:: c
+
+     static struct kunit_case example_test_cases[] = {
+             KUNIT_CASE(example_test_foo),
+             KUNIT_CASE(example_test_bar),
+             KUNIT_CASE(example_test_baz),
+             {}
+     };
+
+     static struct kunit_suite example_test_suite = {
+             .name = "example",
+             .init = example_test_init,
+             .exit = example_test_exit,
+             .test_cases = example_test_cases,
+     };
+     kunit_test_suite(example_test_suite);
+
+In the above example, the test suite ``example_test_suite``, runs the
+test cases ``example_test_foo``, ``example_test_bar``, and
+``example_test_baz``. Before running the test, the ``example_test_init``
+is called and after running the test, ``example_test_exit`` is called.
+The ``kunit_test_suite(example_test_suite)`` registers the test suite
+with the KUnit test framework.
+
+Executor
+--------
+
+The KUnit executor can list and run built-in KUnit tests on boot.
+The Test suites are stored in a linker section
+called ``.kunit_test_suites``. For code, see:
+https://elixir.bootlin.com/linux/v5.12/source/include/asm-generic/vmlinux.lds.h#L918.
+The linker section consists of an array of pointers to
+``struct kunit_suite``, and is populated by the ``kunit_test_suites()``
+macro. To run all tests compiled into the kernel, the KUnit executor
+iterates over the linker section array.
+
+.. kernel-figure:: kunit_suitememorydiagram.png
+     :alt:   KUnit Suite Memory
+
+     KUnit Suite Memory Diagram
+
+On the kernel boot, the KUnit executor uses the start and end addresses
+of this section to iterate over and run all tests. For code, see:
+https://elixir.bootlin.com/linux/latest/source/lib/kunit/executor.c
+
+When built as a module, the ``kunit_test_suites()`` macro defines a
+``module_init()`` function, which runs all the tests in the compilation
+unit instead of utilizing the executor.
+
+In KUnit tests, some error classes do not affect other tests
+or parts of the kernel, each KUnit case executes in a separate thread
+context. For code, see:
+https://elixir.bootlin.com/linux/latest/source/lib/kunit/try-catch.c#L58
+
+Assertion Macros
+----------------
+
+KUnit tests verify state using expectations/assertions.
+All expectations/assertions are formatted as:
+``KUNIT_{EXPECT|ASSERT}_<op>[_MSG](kunit, property[, message])``
+
+- ``{EXPECT|ASSERT}`` determines whether the check is an assertion or an
+  expectation.
+
+     - For an expectation, if the check fails, marks the test as failed
+       and logs the failure.
+
+     - An assertion, on failure, causes the test case to terminate
+       immediately.
+
+             - Assertions call function:
+               ``void __noreturn kunit_abort(struct kunit *)``.
+
+             - ``kunit_abort`` calls function:
+               ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``.
+
+             - ``kunit_try_catch_throw`` calls function:
+               ``void complete_and_exit(struct completion *, long) __noreturn;``
+               and terminates the special thread context.
+
+- ``<op>`` denotes a check with options: ``TRUE`` (supplied property
+  has the boolean value “true”), ``EQ`` (two supplied properties are
+  equal), ``NOT_ERR_OR_NULL`` (supplied pointer is not null and does not
+  contain an “err” value).
+
+- ``[_MSG]`` prints a custom message on failure.
+
+Test Result Reporting
+---------------------
+KUnit prints test results in KTAP format. KTAP is based on TAP14, see:
+https://github.com/isaacs/testanything.github.io/blob/tap14/tap-version-14-specification.md.
+KTAP (yet to be standardized format) works with KUnit and Kselftest.
+The KUnit executor prints KTAP results to dmesg, and debugfs
+(if configured).
+
+Parameterized Tests
+-------------------
+
+Each KUnit parameterized test is associated with a collection of
+parameters. The test is invoked multiple times, once for each parameter
+value and the parameter is stored in the ``param_value`` field.
+The test case includes a ``KUNIT_CASE_PARAM()`` macro that accepts a
+generator function.
+The generator function returns the next parameter given to the
given to the -> given the
Reworded the sentence as "The generator function is passed the
previous parameter and returns the next
parameter".
quoted
+previous parameter in parameterized tests. It also provides a macro to
+generate common-case generators based on arrays.
+
+For code, see:
+https://elixir.bootlin.com/linux/v5.12/source/include/kunit/test.h#L1783
The rest looks OK, as far as I can tell.
 -- Tim
Regards,
Harinder Singh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help