linux-kselftest.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Harinder Singh <sharinder@google.com>
To: davidgow@google.com, brendanhiggins@google.com, shuah@kernel.org,
	corbet@lwn.net
Cc: linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	tim.bird@sony.com, elver@google.com,
	Harinder Singh <sharinder@google.com>
Subject: [PATCH v5 3/7] Documentation: KUnit: Added KUnit Architecture
Date: Fri, 17 Dec 2021 04:37:12 +0000	[thread overview]
Message-ID: <20211217043716.794289-4-sharinder@google.com> (raw)
In-Reply-To: <20211217043716.794289-1-sharinder@google.com>

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

Signed-off-by: Harinder Singh <sharinder@google.com>
---
 .../dev-tools/kunit/architecture.rst          | 204 ++++++++++++++++++
 Documentation/dev-tools/kunit/index.rst       |   2 +
 Documentation/dev-tools/kunit/start.rst       |   1 +
 3 files changed, 207 insertions(+)
 create mode 100644 Documentation/dev-tools/kunit/architecture.rst

diff --git a/Documentation/dev-tools/kunit/architecture.rst b/Documentation/dev-tools/kunit/architecture.rst
new file mode 100644
index 000000000000..aa2cea821e25
--- /dev/null
+++ b/Documentation/dev-tools/kunit/architecture.rst
@@ -0,0 +1,204 @@
+.. 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:
+
+.. kernel-doc:: include/kunit/test.h
+	:identifiers: kunit_case
+
+.. note:
+	``generate_params`` 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://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/asm-generic/vmlinux.lds.h?h=v5.15#n945.
+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.svg
+	: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://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/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://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kunit/try-catch.c?h=v5.15#n58
+
+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 is passed the previous parameter and returns the next
+parameter. It also provides a macro to generate common-case generators based on
+arrays.
+
+For code, see:
+
+.. kernel-doc:: include/kunit/test.h
+	:identifiers: KUNIT_ARRAY_PARAM
+
+
+kunit_tool (Command Line Test Harness)
+======================================
+
+kunit_tool is a Python script ``(tools/testing/kunit/kunit.py)``
+that can be used to configure, build, exec, parse and run (runs other
+commands in order) test results. You can either run KUnit tests using
+kunit_tool or can include KUnit in kernel and parse manually.
+
+- ``configure`` command generates the kernel ``.config`` from a
+  ``.kunitconfig`` file (and any architecture-specific options).
+  For some architectures, additional config options are specified in the
+  ``qemu_config`` Python script
+  (For example: ``tools/testing/kunit/qemu_configs/powerpc.py``).
+  It parses both the existing ``.config`` and the ``.kunitconfig`` files
+  and ensures that ``.config`` is a superset of ``.kunitconfig``.
+  If this is not the case, it will combine the two and run
+  ``make olddefconfig`` to regenerate the ``.config`` file. It then
+  verifies that ``.config`` is now a superset. This checks if all
+  Kconfig dependencies are correctly specified in ``.kunitconfig``.
+  ``kunit_config.py`` includes the parsing Kconfigs code. The code which
+  runs ``make olddefconfig`` is a part of ``kunit_kernel.py``. You can
+  invoke this command via: ``./tools/testing/kunit/kunit.py config`` and
+  generate a ``.config`` file.
+- ``build`` runs ``make`` on the kernel tree with required options
+  (depends on the architecture and some options, for example: build_dir)
+  and reports any errors.
+  To build a KUnit kernel from the current ``.config``, you can use the
+  ``build`` argument: ``./tools/testing/kunit/kunit.py build``.
+- ``exec`` command executes kernel results either directly (using
+  User-mode Linux configuration), or via an emulator such
+  as QEMU. It reads results from the log via standard
+  output (stdout), and passes them to ``parse`` to be parsed.
+  If you already have built a kernel with built-in KUnit tests,
+  you can run the kernel and display the test results with the ``exec``
+  argument: ``./tools/testing/kunit/kunit.py exec``.
+- ``parse`` extracts the KTAP output from a kernel log, parses
+  the test results, and prints a summary. For failed tests, any
+  diagnostic output will be included.
diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-tools/kunit/index.rst
index 55d2444b0745..50d3ef9359dd 100644
--- a/Documentation/dev-tools/kunit/index.rst
+++ b/Documentation/dev-tools/kunit/index.rst
@@ -9,6 +9,7 @@ KUnit - Linux Kernel Unit Testing
 	:caption: Contents:
 
 	start
+	architecture
 	usage
 	kunit-tool
 	api/index
@@ -96,6 +97,7 @@ How do I use it?
 ================
 
 *   Documentation/dev-tools/kunit/start.rst - for KUnit new users.
+*   Documentation/dev-tools/kunit/architecture.rst - KUnit architecture.
 *   Documentation/dev-tools/kunit/usage.rst - KUnit features.
 *   Documentation/dev-tools/kunit/tips.rst - best practices with
     examples.
diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst
index 55f8df1abd40..5dd2c88fa2bd 100644
--- a/Documentation/dev-tools/kunit/start.rst
+++ b/Documentation/dev-tools/kunit/start.rst
@@ -240,6 +240,7 @@ Congrats! You just wrote your first KUnit test.
 Next Steps
 ==========
 
+*   Documentation/dev-tools/kunit/architecture.rst - KUnit architecture.
 *   Documentation/dev-tools/kunit/usage.rst - KUnit features.
 *   Documentation/dev-tools/kunit/tips.rst - best practices with
     examples.
-- 
2.34.1.173.g76aa8bc2d0-goog


  parent reply	other threads:[~2021-12-17  4:38 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-17  4:37 [PATCH v5 0/7] Documentation: KUnit: Rework KUnit documentation Harinder Singh
2021-12-17  4:37 ` [PATCH v5 1/7] Documentation: KUnit: Rewrite main page Harinder Singh
2021-12-17  4:37 ` [PATCH v5 2/7] Documentation: KUnit: Rewrite getting started Harinder Singh
2021-12-17  4:37 ` Harinder Singh [this message]
2021-12-17  4:37 ` [PATCH v5 4/7] Documentation: kunit: Reorganize documentation related to running tests Harinder Singh
2021-12-17  4:37 ` [PATCH v5 5/7] Documentation: KUnit: Rework writing page to focus on writing tests Harinder Singh
2021-12-17  4:37 ` [PATCH v5 6/7] Documentation: KUnit: Restyle Test Style and Nomenclature page Harinder Singh
2021-12-17  4:37 ` [PATCH v5 7/7] Documentation: KUnit: Restyled Frequently Asked Questions Harinder Singh
2021-12-17  4:51 ` [PATCH v5 0/7] Documentation: KUnit: Rework KUnit documentation Harinder Singh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211217043716.794289-4-sharinder@google.com \
    --to=sharinder@google.com \
    --cc=brendanhiggins@google.com \
    --cc=corbet@lwn.net \
    --cc=davidgow@google.com \
    --cc=elver@google.com \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=tim.bird@sony.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).