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