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