1.. SPDX-License-Identifier: GPL-2.0
2
3===============
4Getting Started
5===============
6
7Installing dependencies
8=======================
9KUnit has the same dependencies as the Linux kernel. As long as you can build
10the kernel, you can run KUnit.
11
12Running tests with the KUnit Wrapper
13====================================
14Included with KUnit is a simple Python wrapper which runs tests under User Mode
15Linux, and formats the test results.
16
17The wrapper can be run with:
18
19.. code-block:: bash
20
21	./tools/testing/kunit/kunit.py run --defconfig
22
23For more information on this wrapper (also called kunit_tool) check out the
24:doc:`kunit-tool` page.
25
26Creating a .kunitconfig
27-----------------------
28If you want to run a specific set of tests (rather than those listed in the
29KUnit defconfig), you can provide Kconfig options in the ``.kunitconfig`` file.
30This file essentially contains the regular Kernel config, with the specific
31test targets as well. The ``.kunitconfig`` should also contain any other config
32options required by the tests.
33
34A good starting point for a ``.kunitconfig`` is the KUnit defconfig:
35.. code-block:: bash
36
37	cd $PATH_TO_LINUX_REPO
38	cp arch/um/configs/kunit_defconfig .kunitconfig
39
40You can then add any other Kconfig options you wish, e.g.:
41.. code-block:: none
42
43        CONFIG_LIST_KUNIT_TEST=y
44
45:doc:`kunit_tool <kunit-tool>` will ensure that all config options set in
46``.kunitconfig`` are set in the kernel ``.config`` before running the tests.
47It'll warn you if you haven't included the dependencies of the options you're
48using.
49
50.. note::
51   Note that removing something from the ``.kunitconfig`` will not trigger a
52   rebuild of the ``.config`` file: the configuration is only updated if the
53   ``.kunitconfig`` is not a subset of ``.config``. This means that you can use
54   other tools (such as make menuconfig) to adjust other config options.
55
56
57Running the tests
58-----------------
59
60To make sure that everything is set up correctly, simply invoke the Python
61wrapper from your kernel repo:
62
63.. code-block:: bash
64
65	./tools/testing/kunit/kunit.py run
66
67.. note::
68   You may want to run ``make mrproper`` first.
69
70If everything worked correctly, you should see the following:
71
72.. code-block:: bash
73
74	Generating .config ...
75	Building KUnit Kernel ...
76	Starting KUnit Kernel ...
77
78followed by a list of tests that are run. All of them should be passing.
79
80.. note::
81	Because it is building a lot of sources for the first time, the
82	``Building KUnit kernel`` step may take a while.
83
84Running tests without the KUnit Wrapper
85=======================================
86
87If you'd rather not use the KUnit Wrapper (if, for example, you need to
88integrate with other systems, or use an architecture other than UML), KUnit can
89be included in any kernel, and the results read out and parsed manually.
90
91.. note::
92   KUnit is not designed for use in a production system, and it's possible that
93   tests may reduce the stability or security of the system.
94
95
96
97Configuring the kernel
98----------------------
99
100In order to enable KUnit itself, you simply need to enable the ``CONFIG_KUNIT``
101Kconfig option (it's under Kernel Hacking/Kernel Testing and Coverage in
102menuconfig). From there, you can enable any KUnit tests you want: they usually
103have config options ending in ``_KUNIT_TEST``.
104
105KUnit and KUnit tests can be compiled as modules: in this case the tests in a
106module will be run when the module is loaded.
107
108Running the tests
109-----------------
110
111Build and run your kernel as usual. Test output will be written to the kernel
112log in `TAP <https://testanything.org/>`_ format.
113
114.. note::
115   It's possible that there will be other lines and/or data interspersed in the
116   TAP output.
117
118
119Writing your first test
120=======================
121
122In your kernel repo let's add some code that we can test. Create a file
123``drivers/misc/example.h`` with the contents:
124
125.. code-block:: c
126
127	int misc_example_add(int left, int right);
128
129create a file ``drivers/misc/example.c``:
130
131.. code-block:: c
132
133	#include <linux/errno.h>
134
135	#include "example.h"
136
137	int misc_example_add(int left, int right)
138	{
139		return left + right;
140	}
141
142Now add the following lines to ``drivers/misc/Kconfig``:
143
144.. code-block:: kconfig
145
146	config MISC_EXAMPLE
147		bool "My example"
148
149and the following lines to ``drivers/misc/Makefile``:
150
151.. code-block:: make
152
153	obj-$(CONFIG_MISC_EXAMPLE) += example.o
154
155Now we are ready to write the test. The test will be in
156``drivers/misc/example-test.c``:
157
158.. code-block:: c
159
160	#include <kunit/test.h>
161	#include "example.h"
162
163	/* Define the test cases. */
164
165	static void misc_example_add_test_basic(struct kunit *test)
166	{
167		KUNIT_EXPECT_EQ(test, 1, misc_example_add(1, 0));
168		KUNIT_EXPECT_EQ(test, 2, misc_example_add(1, 1));
169		KUNIT_EXPECT_EQ(test, 0, misc_example_add(-1, 1));
170		KUNIT_EXPECT_EQ(test, INT_MAX, misc_example_add(0, INT_MAX));
171		KUNIT_EXPECT_EQ(test, -1, misc_example_add(INT_MAX, INT_MIN));
172	}
173
174	static void misc_example_test_failure(struct kunit *test)
175	{
176		KUNIT_FAIL(test, "This test never passes.");
177	}
178
179	static struct kunit_case misc_example_test_cases[] = {
180		KUNIT_CASE(misc_example_add_test_basic),
181		KUNIT_CASE(misc_example_test_failure),
182		{}
183	};
184
185	static struct kunit_suite misc_example_test_suite = {
186		.name = "misc-example",
187		.test_cases = misc_example_test_cases,
188	};
189	kunit_test_suite(misc_example_test_suite);
190
191Now add the following to ``drivers/misc/Kconfig``:
192
193.. code-block:: kconfig
194
195	config MISC_EXAMPLE_TEST
196		bool "Test for my example"
197		depends on MISC_EXAMPLE && KUNIT
198
199and the following to ``drivers/misc/Makefile``:
200
201.. code-block:: make
202
203	obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o
204
205Now add it to your ``.kunitconfig``:
206
207.. code-block:: none
208
209	CONFIG_MISC_EXAMPLE=y
210	CONFIG_MISC_EXAMPLE_TEST=y
211
212Now you can run the test:
213
214.. code-block:: bash
215
216	./tools/testing/kunit/kunit.py run
217
218You should see the following failure:
219
220.. code-block:: none
221
222	...
223	[16:08:57] [PASSED] misc-example:misc_example_add_test_basic
224	[16:08:57] [FAILED] misc-example:misc_example_test_failure
225	[16:08:57] EXPECTATION FAILED at drivers/misc/example-test.c:17
226	[16:08:57] 	This test never passes.
227	...
228
229Congrats! You just wrote your first KUnit test!
230
231Next Steps
232==========
233*   Check out the :doc:`usage` page for a more
234    in-depth explanation of KUnit.
235