18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci=============== 48c2ecf20Sopenharmony_ciGetting Started 58c2ecf20Sopenharmony_ci=============== 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciInstalling dependencies 88c2ecf20Sopenharmony_ci======================= 98c2ecf20Sopenharmony_ciKUnit has the same dependencies as the Linux kernel. As long as you can build 108c2ecf20Sopenharmony_cithe kernel, you can run KUnit. 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ciRunning tests with the KUnit Wrapper 138c2ecf20Sopenharmony_ci==================================== 148c2ecf20Sopenharmony_ciIncluded with KUnit is a simple Python wrapper which runs tests under User Mode 158c2ecf20Sopenharmony_ciLinux, and formats the test results. 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciThe wrapper can be run with: 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci.. code-block:: bash 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci ./tools/testing/kunit/kunit.py run 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciFor more information on this wrapper (also called kunit_tool) check out the 248c2ecf20Sopenharmony_ci:doc:`kunit-tool` page. 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ciCreating a .kunitconfig 278c2ecf20Sopenharmony_ci----------------------- 288c2ecf20Sopenharmony_ciIf you want to run a specific set of tests (rather than those listed in the 298c2ecf20Sopenharmony_ciKUnit defconfig), you can provide Kconfig options in the ``.kunitconfig`` file. 308c2ecf20Sopenharmony_ciThis file essentially contains the regular Kernel config, with the specific 318c2ecf20Sopenharmony_citest targets as well. The ``.kunitconfig`` should also contain any other config 328c2ecf20Sopenharmony_cioptions required by the tests. 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ciA good starting point for a ``.kunitconfig`` is the KUnit defconfig: 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci.. code-block:: bash 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci cd $PATH_TO_LINUX_REPO 398c2ecf20Sopenharmony_ci cp arch/um/configs/kunit_defconfig .kunitconfig 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ciYou can then add any other Kconfig options you wish, e.g.: 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci.. code-block:: none 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci CONFIG_LIST_KUNIT_TEST=y 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci:doc:`kunit_tool <kunit-tool>` will ensure that all config options set in 488c2ecf20Sopenharmony_ci``.kunitconfig`` are set in the kernel ``.config`` before running the tests. 498c2ecf20Sopenharmony_ciIt'll warn you if you haven't included the dependencies of the options you're 508c2ecf20Sopenharmony_ciusing. 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci.. note:: 538c2ecf20Sopenharmony_ci Note that removing something from the ``.kunitconfig`` will not trigger a 548c2ecf20Sopenharmony_ci rebuild of the ``.config`` file: the configuration is only updated if the 558c2ecf20Sopenharmony_ci ``.kunitconfig`` is not a subset of ``.config``. This means that you can use 568c2ecf20Sopenharmony_ci other tools (such as make menuconfig) to adjust other config options. 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ciRunning the tests (KUnit Wrapper) 608c2ecf20Sopenharmony_ci--------------------------------- 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ciTo make sure that everything is set up correctly, simply invoke the Python 638c2ecf20Sopenharmony_ciwrapper from your kernel repo: 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci.. code-block:: bash 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci ./tools/testing/kunit/kunit.py run 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci.. note:: 708c2ecf20Sopenharmony_ci You may want to run ``make mrproper`` first. 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciIf everything worked correctly, you should see the following: 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci.. code-block:: bash 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci Generating .config ... 778c2ecf20Sopenharmony_ci Building KUnit Kernel ... 788c2ecf20Sopenharmony_ci Starting KUnit Kernel ... 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cifollowed by a list of tests that are run. All of them should be passing. 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci.. note:: 838c2ecf20Sopenharmony_ci Because it is building a lot of sources for the first time, the 848c2ecf20Sopenharmony_ci ``Building KUnit kernel`` step may take a while. 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciRunning tests without the KUnit Wrapper 878c2ecf20Sopenharmony_ci======================================= 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ciIf you'd rather not use the KUnit Wrapper (if, for example, you need to 908c2ecf20Sopenharmony_ciintegrate with other systems, or use an architecture other than UML), KUnit can 918c2ecf20Sopenharmony_cibe included in any kernel, and the results read out and parsed manually. 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci.. note:: 948c2ecf20Sopenharmony_ci KUnit is not designed for use in a production system, and it's possible that 958c2ecf20Sopenharmony_ci tests may reduce the stability or security of the system. 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ciConfiguring the kernel 1008c2ecf20Sopenharmony_ci---------------------- 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ciIn order to enable KUnit itself, you simply need to enable the ``CONFIG_KUNIT`` 1038c2ecf20Sopenharmony_ciKconfig option (it's under Kernel Hacking/Kernel Testing and Coverage in 1048c2ecf20Sopenharmony_cimenuconfig). From there, you can enable any KUnit tests you want: they usually 1058c2ecf20Sopenharmony_cihave config options ending in ``_KUNIT_TEST``. 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ciKUnit and KUnit tests can be compiled as modules: in this case the tests in a 1088c2ecf20Sopenharmony_cimodule will be run when the module is loaded. 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ciRunning the tests (w/o KUnit Wrapper) 1128c2ecf20Sopenharmony_ci------------------------------------- 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ciBuild and run your kernel as usual. Test output will be written to the kernel 1158c2ecf20Sopenharmony_cilog in `TAP <https://testanything.org/>`_ format. 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci.. note:: 1188c2ecf20Sopenharmony_ci It's possible that there will be other lines and/or data interspersed in the 1198c2ecf20Sopenharmony_ci TAP output. 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ciWriting your first test 1238c2ecf20Sopenharmony_ci======================= 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ciIn your kernel repo let's add some code that we can test. Create a file 1268c2ecf20Sopenharmony_ci``drivers/misc/example.h`` with the contents: 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci.. code-block:: c 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci int misc_example_add(int left, int right); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cicreate a file ``drivers/misc/example.c``: 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci.. code-block:: c 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci #include <linux/errno.h> 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci #include "example.h" 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci int misc_example_add(int left, int right) 1418c2ecf20Sopenharmony_ci { 1428c2ecf20Sopenharmony_ci return left + right; 1438c2ecf20Sopenharmony_ci } 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ciNow add the following lines to ``drivers/misc/Kconfig``: 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci.. code-block:: kconfig 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci config MISC_EXAMPLE 1508c2ecf20Sopenharmony_ci bool "My example" 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ciand the following lines to ``drivers/misc/Makefile``: 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci.. code-block:: make 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci obj-$(CONFIG_MISC_EXAMPLE) += example.o 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ciNow we are ready to write the test. The test will be in 1598c2ecf20Sopenharmony_ci``drivers/misc/example-test.c``: 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci.. code-block:: c 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci #include <kunit/test.h> 1648c2ecf20Sopenharmony_ci #include "example.h" 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci /* Define the test cases. */ 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci static void misc_example_add_test_basic(struct kunit *test) 1698c2ecf20Sopenharmony_ci { 1708c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, 1, misc_example_add(1, 0)); 1718c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, 2, misc_example_add(1, 1)); 1728c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, 0, misc_example_add(-1, 1)); 1738c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, INT_MAX, misc_example_add(0, INT_MAX)); 1748c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, -1, misc_example_add(INT_MAX, INT_MIN)); 1758c2ecf20Sopenharmony_ci } 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci static void misc_example_test_failure(struct kunit *test) 1788c2ecf20Sopenharmony_ci { 1798c2ecf20Sopenharmony_ci KUNIT_FAIL(test, "This test never passes."); 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci static struct kunit_case misc_example_test_cases[] = { 1838c2ecf20Sopenharmony_ci KUNIT_CASE(misc_example_add_test_basic), 1848c2ecf20Sopenharmony_ci KUNIT_CASE(misc_example_test_failure), 1858c2ecf20Sopenharmony_ci {} 1868c2ecf20Sopenharmony_ci }; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci static struct kunit_suite misc_example_test_suite = { 1898c2ecf20Sopenharmony_ci .name = "misc-example", 1908c2ecf20Sopenharmony_ci .test_cases = misc_example_test_cases, 1918c2ecf20Sopenharmony_ci }; 1928c2ecf20Sopenharmony_ci kunit_test_suite(misc_example_test_suite); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciNow add the following to ``drivers/misc/Kconfig``: 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci.. code-block:: kconfig 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci config MISC_EXAMPLE_TEST 1998c2ecf20Sopenharmony_ci bool "Test for my example" 2008c2ecf20Sopenharmony_ci depends on MISC_EXAMPLE && KUNIT=y 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ciand the following to ``drivers/misc/Makefile``: 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci.. code-block:: make 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ciNow add it to your ``.kunitconfig``: 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci.. code-block:: none 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci CONFIG_MISC_EXAMPLE=y 2138c2ecf20Sopenharmony_ci CONFIG_MISC_EXAMPLE_TEST=y 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ciNow you can run the test: 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci.. code-block:: bash 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci ./tools/testing/kunit/kunit.py run 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciYou should see the following failure: 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci.. code-block:: none 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci ... 2268c2ecf20Sopenharmony_ci [16:08:57] [PASSED] misc-example:misc_example_add_test_basic 2278c2ecf20Sopenharmony_ci [16:08:57] [FAILED] misc-example:misc_example_test_failure 2288c2ecf20Sopenharmony_ci [16:08:57] EXPECTATION FAILED at drivers/misc/example-test.c:17 2298c2ecf20Sopenharmony_ci [16:08:57] This test never passes. 2308c2ecf20Sopenharmony_ci ... 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciCongrats! You just wrote your first KUnit test! 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ciNext Steps 2358c2ecf20Sopenharmony_ci========== 2368c2ecf20Sopenharmony_ci* Check out the :doc:`usage` page for a more 2378c2ecf20Sopenharmony_ci in-depth explanation of KUnit. 238