02c7efa436
Commit ddbd60c779b4 ("kunit: use --build_dir=.kunit as default") changed the default --build_dir, which had the side effect of making `.kunitconfig` move to `.kunit/.kunitconfig`. However, the first few lines of kunit/start.rst never got updated, oops. Fix this by telling people to run kunit.py first, which will automatically generate the .kunit directory and .kunitconfig file, and then edit the file manually as desired. Reported-by: Yifan Yuan <alpc_metic@live.com> Signed-off-by: Daniel Latypov <dlatypov@google.com> Reviewed-by: David Gow <davidgow@google.com> Reviewed-by: Brendan Higgins <brendanhiggins@google.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
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.
|