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