261 lines
7.5 KiB
ReStructuredText
261 lines
7.5 KiB
ReStructuredText
.. SPDX-License-Identifier: GPL-2.0
|
|
|
|
===============
|
|
Getting Started
|
|
===============
|
|
|
|
Installing Dependencies
|
|
=======================
|
|
KUnit has the same dependencies as the Linux kernel. As long as you can
|
|
build the kernel, you can run KUnit.
|
|
|
|
Running tests with kunit_tool
|
|
=============================
|
|
kunit_tool is a Python script, which configures and builds a kernel, runs
|
|
tests, and formats the test results. From the kernel repository, you
|
|
can run kunit_tool:
|
|
|
|
.. code-block:: bash
|
|
|
|
./tools/testing/kunit/kunit.py run
|
|
|
|
For more information on this wrapper, see:
|
|
Documentation/dev-tools/kunit/run_wrapper.rst.
|
|
|
|
Creating a ``.kunitconfig``
|
|
---------------------------
|
|
|
|
By default, kunit_tool runs a selection of tests. However, you can specify which
|
|
unit tests to run by creating a ``.kunitconfig`` file with kernel config options
|
|
that enable only a specific set of tests and their dependencies.
|
|
The ``.kunitconfig`` file contains a list of kconfig options which are required
|
|
to run the desired targets. The ``.kunitconfig`` also contains any other test
|
|
specific config options, such as test dependencies. For example: the
|
|
``FAT_FS`` tests - ``FAT_KUNIT_TEST``, depends on
|
|
``FAT_FS``. ``FAT_FS`` can be enabled by selecting either ``MSDOS_FS``
|
|
or ``VFAT_FS``. To run ``FAT_KUNIT_TEST``, the ``.kunitconfig`` has:
|
|
|
|
.. code-block:: none
|
|
|
|
CONFIG_KUNIT=y
|
|
CONFIG_MSDOS_FS=y
|
|
CONFIG_FAT_KUNIT_TEST=y
|
|
|
|
1. A good starting point for the ``.kunitconfig`` is the KUnit default config.
|
|
You can generate it by running:
|
|
|
|
.. code-block:: bash
|
|
|
|
cd $PATH_TO_LINUX_REPO
|
|
tools/testing/kunit/kunit.py config
|
|
cat .kunit/.kunitconfig
|
|
|
|
.. note ::
|
|
``.kunitconfig`` lives in the ``--build_dir`` used by kunit.py, which is
|
|
``.kunit`` by default.
|
|
|
|
.. note ::
|
|
You may want to remove CONFIG_KUNIT_ALL_TESTS from the ``.kunitconfig`` as
|
|
it will enable a number of additional tests that you may not want.
|
|
|
|
2. You can then add any other Kconfig options, for example:
|
|
|
|
.. code-block:: none
|
|
|
|
CONFIG_LIST_KUNIT_TEST=y
|
|
|
|
Before running the tests, kunit_tool ensures that all config options
|
|
set in ``.kunitconfig`` are set in the kernel ``.config``. It will warn
|
|
you if you have not included dependencies for the options used.
|
|
|
|
.. note ::
|
|
If you change the ``.kunitconfig``, kunit.py will trigger a rebuild of the
|
|
``.config`` file. But you can edit the ``.config`` file directly or with
|
|
tools like ``make menuconfig O=.kunit``. As long as its a superset of
|
|
``.kunitconfig``, kunit.py won't overwrite your changes.
|
|
|
|
Running Tests (KUnit Wrapper)
|
|
-----------------------------
|
|
1. To make sure that everything is set up correctly, invoke the Python
|
|
wrapper from your kernel repository:
|
|
|
|
.. code-block:: bash
|
|
|
|
./tools/testing/kunit/kunit.py run
|
|
|
|
If everything worked correctly, you should see the following:
|
|
|
|
.. code-block::
|
|
|
|
Generating .config ...
|
|
Building KUnit Kernel ...
|
|
Starting KUnit Kernel ...
|
|
|
|
The tests will pass or fail.
|
|
|
|
.. note ::
|
|
Because it is building a lot of sources for the first time, the
|
|
``Building KUnit kernel`` may take a while.
|
|
|
|
Running Tests without the KUnit Wrapper
|
|
=======================================
|
|
If you do not want to use the KUnit Wrapper (for example: you want code
|
|
under test to integrate with other systems, or use a different/
|
|
unsupported architecture or configuration), KUnit can be included in
|
|
any kernel, and the results are read out and parsed manually.
|
|
|
|
.. note ::
|
|
``CONFIG_KUNIT`` should not be enabled in a production environment.
|
|
Enabling KUnit disables Kernel Address-Space Layout Randomization
|
|
(KASLR), and tests may affect the state of the kernel in ways not
|
|
suitable for production.
|
|
|
|
Configuring the Kernel
|
|
----------------------
|
|
To enable KUnit itself, you need to enable the ``CONFIG_KUNIT`` Kconfig
|
|
option (under Kernel Hacking/Kernel Testing and Coverage in
|
|
``menuconfig``). From there, you can enable any KUnit tests. They
|
|
usually have config options ending in ``_KUNIT_TEST``.
|
|
|
|
KUnit and KUnit tests can be compiled as modules. The tests in a module
|
|
will run when the module is loaded.
|
|
|
|
Running Tests (without KUnit Wrapper)
|
|
-------------------------------------
|
|
Build and run your kernel. In the kernel log, the test output is printed
|
|
out in the TAP format. This will only happen by default if KUnit/tests
|
|
are built-in. Otherwise the module will need to be loaded.
|
|
|
|
.. note ::
|
|
Some lines and/or data may get interspersed in the TAP output.
|
|
|
|
Writing Your First Test
|
|
=======================
|
|
In your kernel repository, let's add some code that we can test.
|
|
|
|
1. Create a file ``drivers/misc/example.h``, which includes:
|
|
|
|
.. code-block:: c
|
|
|
|
int misc_example_add(int left, int right);
|
|
|
|
2. Create a file ``drivers/misc/example.c``, which includes:
|
|
|
|
.. code-block:: c
|
|
|
|
#include <linux/errno.h>
|
|
|
|
#include "example.h"
|
|
|
|
int misc_example_add(int left, int right)
|
|
{
|
|
return left + right;
|
|
}
|
|
|
|
3. Add the following lines to ``drivers/misc/Kconfig``:
|
|
|
|
.. code-block:: kconfig
|
|
|
|
config MISC_EXAMPLE
|
|
bool "My example"
|
|
|
|
4. Add the following lines to ``drivers/misc/Makefile``:
|
|
|
|
.. code-block:: make
|
|
|
|
obj-$(CONFIG_MISC_EXAMPLE) += example.o
|
|
|
|
Now we are ready to write the test cases.
|
|
|
|
1. Add the below test case in ``drivers/misc/example_test.c``:
|
|
|
|
.. code-block:: c
|
|
|
|
#include <kunit/test.h>
|
|
#include "example.h"
|
|
|
|
/* Define the test cases. */
|
|
|
|
static void misc_example_add_test_basic(struct kunit *test)
|
|
{
|
|
KUNIT_EXPECT_EQ(test, 1, misc_example_add(1, 0));
|
|
KUNIT_EXPECT_EQ(test, 2, misc_example_add(1, 1));
|
|
KUNIT_EXPECT_EQ(test, 0, misc_example_add(-1, 1));
|
|
KUNIT_EXPECT_EQ(test, INT_MAX, misc_example_add(0, INT_MAX));
|
|
KUNIT_EXPECT_EQ(test, -1, misc_example_add(INT_MAX, INT_MIN));
|
|
}
|
|
|
|
static void misc_example_test_failure(struct kunit *test)
|
|
{
|
|
KUNIT_FAIL(test, "This test never passes.");
|
|
}
|
|
|
|
static struct kunit_case misc_example_test_cases[] = {
|
|
KUNIT_CASE(misc_example_add_test_basic),
|
|
KUNIT_CASE(misc_example_test_failure),
|
|
{}
|
|
};
|
|
|
|
static struct kunit_suite misc_example_test_suite = {
|
|
.name = "misc-example",
|
|
.test_cases = misc_example_test_cases,
|
|
};
|
|
kunit_test_suite(misc_example_test_suite);
|
|
|
|
2. Add the following lines to ``drivers/misc/Kconfig``:
|
|
|
|
.. code-block:: kconfig
|
|
|
|
config MISC_EXAMPLE_TEST
|
|
tristate "Test for my example" if !KUNIT_ALL_TESTS
|
|
depends on MISC_EXAMPLE && KUNIT=y
|
|
default KUNIT_ALL_TESTS
|
|
|
|
3. Add the following lines to ``drivers/misc/Makefile``:
|
|
|
|
.. code-block:: make
|
|
|
|
obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o
|
|
|
|
4. Add the following lines to ``.kunitconfig``:
|
|
|
|
.. code-block:: none
|
|
|
|
CONFIG_MISC_EXAMPLE=y
|
|
CONFIG_MISC_EXAMPLE_TEST=y
|
|
|
|
5. Run the test:
|
|
|
|
.. code-block:: bash
|
|
|
|
./tools/testing/kunit/kunit.py run
|
|
|
|
You should see the following failure:
|
|
|
|
.. code-block:: none
|
|
|
|
...
|
|
[16:08:57] [PASSED] misc-example:misc_example_add_test_basic
|
|
[16:08:57] [FAILED] misc-example:misc_example_test_failure
|
|
[16:08:57] EXPECTATION FAILED at drivers/misc/example-test.c:17
|
|
[16:08:57] This test never passes.
|
|
...
|
|
|
|
Congrats! You just wrote your first KUnit test.
|
|
|
|
Next Steps
|
|
==========
|
|
|
|
* Documentation/dev-tools/kunit/architecture.rst - KUnit architecture.
|
|
* Documentation/dev-tools/kunit/run_wrapper.rst - run kunit_tool.
|
|
* Documentation/dev-tools/kunit/run_manual.rst - run tests without kunit_tool.
|
|
* Documentation/dev-tools/kunit/usage.rst - write tests.
|
|
* Documentation/dev-tools/kunit/tips.rst - best practices with
|
|
examples.
|
|
* Documentation/dev-tools/kunit/api/index.rst - KUnit APIs
|
|
used for testing.
|
|
* Documentation/dev-tools/kunit/kunit-tool.rst - kunit_tool helper
|
|
script.
|
|
* Documentation/dev-tools/kunit/faq.rst - KUnit common questions and
|
|
answers.
|