Linux-libre 5.7.5-gnu
[librecmc/linux-libre.git] / Documentation / dev-tools / kunit / start.rst
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ===============
4 Getting Started
5 ===============
6
7 Installing dependencies
8 =======================
9 KUnit has the same dependencies as the Linux kernel. As long as you can build
10 the kernel, you can run KUnit.
11
12 Running tests with the KUnit Wrapper
13 ====================================
14 Included with KUnit is a simple Python wrapper which runs tests under User Mode
15 Linux, and formats the test results.
16
17 The wrapper can be run with:
18
19 .. code-block:: bash
20
21         ./tools/testing/kunit/kunit.py run --defconfig
22
23 For more information on this wrapper (also called kunit_tool) check out the
24 :doc:`kunit-tool` page.
25
26 Creating a .kunitconfig
27 -----------------------
28 If you want to run a specific set of tests (rather than those listed in the
29 KUnit defconfig), you can provide Kconfig options in the ``.kunitconfig`` file.
30 This file essentially contains the regular Kernel config, with the specific
31 test targets as well. The ``.kunitconfig`` should also contain any other config
32 options required by the tests.
33
34 A 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
40 You 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.
47 It'll warn you if you haven't included the dependencies of the options you're
48 using.
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
57 Running the tests
58 -----------------
59
60 To make sure that everything is set up correctly, simply invoke the Python
61 wrapper 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
70 If 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
78 followed 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
84 Running tests without the KUnit Wrapper
85 =======================================
86
87 If you'd rather not use the KUnit Wrapper (if, for example, you need to
88 integrate with other systems, or use an architecture other than UML), KUnit can
89 be 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
97 Configuring the kernel
98 ----------------------
99
100 In order to enable KUnit itself, you simply need to enable the ``CONFIG_KUNIT``
101 Kconfig option (it's under Kernel Hacking/Kernel Testing and Coverage in
102 menuconfig). From there, you can enable any KUnit tests you want: they usually
103 have config options ending in ``_KUNIT_TEST``.
104
105 KUnit and KUnit tests can be compiled as modules: in this case the tests in a
106 module will be run when the module is loaded.
107
108 Running the tests
109 -----------------
110
111 Build and run your kernel as usual. Test output will be written to the kernel
112 log 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
119 Writing your first test
120 =======================
121
122 In 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
129 create 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
142 Now add the following lines to ``drivers/misc/Kconfig``:
143
144 .. code-block:: kconfig
145
146         config MISC_EXAMPLE
147                 bool "My example"
148
149 and the following lines to ``drivers/misc/Makefile``:
150
151 .. code-block:: make
152
153         obj-$(CONFIG_MISC_EXAMPLE) += example.o
154
155 Now 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
191 Now 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
199 and the following to ``drivers/misc/Makefile``:
200
201 .. code-block:: make
202
203         obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o
204
205 Now add it to your ``.kunitconfig``:
206
207 .. code-block:: none
208
209         CONFIG_MISC_EXAMPLE=y
210         CONFIG_MISC_EXAMPLE_TEST=y
211
212 Now you can run the test:
213
214 .. code-block:: bash
215
216         ./tools/testing/kunit/kunit.py run
217
218 You 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
229 Congrats! You just wrote your first KUnit test!
230
231 Next Steps
232 ==========
233 *   Check out the :doc:`usage` page for a more
234     in-depth explanation of KUnit.