| 1 | |
| 2 |
|
| 3 | ===============
|
| 4 | Getting Started
|
| 5 | ===============
|
| 6 |
|
| 7 | This page contains an overview of the kunit_tool and KUnit framework,
|
| 8 | teaching how to run existing tests and then how to write a simple test case,
|
| 9 | and covers common problems users face when using KUnit for the first time.
|
| 10 |
|
| 11 | Installing Dependencies
|
| 12 | =======================
|
| 13 | KUnit has the same dependencies as the Linux kernel. As long as you can
|
| 14 | build the kernel, you can run KUnit.
|
| 15 |
|
| 16 | Running tests with kunit_tool
|
| 17 | =============================
|
| 18 | kunit_tool is a Python script, which configures and builds a kernel, runs
|
| 19 | tests, and formats the test results. From the kernel repository, you
|
| 20 | can run kunit_tool:
|
| 21 |
|
| 22 | .. code-block:: bash
|
| 23 |
|
| 24 | ./tools/testing/kunit/kunit.py run
|
| 25 |
|
| 26 | .. note ::
|
| 27 | You may see the following error:
|
| 28 | "The source tree is not clean, please run 'make ARCH=um mrproper'"
|
| 29 |
|
| 30 | This happens because internally kunit.py specifies ``.kunit``
|
| 31 | (default option) as the build directory in the command ``make O=output/dir``
|
| 32 | through the argument ``--build_dir``. Hence, before starting an
|
| 33 | out-of-tree build, the source tree must be clean.
|
| 34 |
|
| 35 | There is also the same caveat mentioned in the "Build directory for
|
| 36 | the kernel" section of the :doc:`admin-guide </admin-guide/README>`,
|
| 37 | that is, its use, it must be used for all invocations of ``make``.
|
| 38 | The good news is that it can indeed be solved by running
|
| 39 | ``make ARCH=um mrproper``, just be aware that this will delete the
|
| 40 | current configuration and all generated files.
|
| 41 |
|
| 42 | If everything worked correctly, you should see the following:
|
| 43 |
|
| 44 | .. code-block::
|
| 45 |
|
| 46 | Configuring KUnit Kernel ...
|
| 47 | Building KUnit Kernel ...
|
| 48 | Starting KUnit Kernel ...
|
| 49 |
|
| 50 | The tests will pass or fail.
|
| 51 |
|
| 52 | .. note ::
|
| 53 | Because it is building a lot of sources for the first time,
|
| 54 | the ``Building KUnit Kernel`` step may take a while.
|
| 55 |
|
| 56 | For detailed information on this wrapper, see:
|
| 57 | Documentation/dev-tools/kunit/run_wrapper.rst.
|
| 58 |
|
| 59 | Selecting which tests to run
|
| 60 | ----------------------------
|
| 61 |
|
| 62 | By default, kunit_tool runs all tests reachable with minimal configuration,
|
| 63 | that is, using default values for most of the kconfig options. However,
|
| 64 | you can select which tests to run by:
|
| 65 |
|
| 66 | - `Customizing Kconfig`_ used to compile the kernel, or
|
| 67 | - `Filtering tests by name`_ to select specifically which compiled tests to run.
|
| 68 |
|
| 69 | Customizing Kconfig
|
| 70 | ~~~~~~~~~~~~~~~~~~~
|
| 71 | A good starting point for the ``.kunitconfig`` is the KUnit default config.
|
| 72 | If you didn't run ``kunit.py run`` yet, you can generate it by running:
|
| 73 |
|
| 74 | .. code-block:: bash
|
| 75 |
|
| 76 | cd $PATH_TO_LINUX_REPO
|
| 77 | tools/testing/kunit/kunit.py config
|
| 78 | cat .kunit/.kunitconfig
|
| 79 |
|
| 80 | .. note ::
|
| 81 | ``.kunitconfig`` lives in the ``--build_dir`` used by kunit.py, which is
|
| 82 | ``.kunit`` by default.
|
| 83 |
|
| 84 | Before running the tests, kunit_tool ensures that all config options
|
| 85 | set in ``.kunitconfig`` are set in the kernel ``.config``. It will warn
|
| 86 | you if you have not included dependencies for the options used.
|
| 87 |
|
| 88 | There are many ways to customize the configurations:
|
| 89 |
|
| 90 | a. Edit ``.kunit/.kunitconfig``. The file should contain the list of kconfig
|
| 91 | options required to run the desired tests, including their dependencies.
|
| 92 | You may want to remove CONFIG_KUNIT_ALL_TESTS from the ``.kunitconfig`` as
|
| 93 | it will enable a number of additional tests that you may not want.
|
| 94 | If you need to run on an architecture other than UML see :ref:`kunit-on-qemu`.
|
| 95 |
|
| 96 | b. Enable additional kconfig options on top of ``.kunit/.kunitconfig``.
|
| 97 | For example, to include the kernel's linked-list test you can run::
|
| 98 |
|
| 99 | ./tools/testing/kunit/kunit.py run \
|
| 100 | --kconfig_add CONFIG_LIST_KUNIT_TEST=y
|
| 101 |
|
| 102 | c. Provide the path of one or more .kunitconfig files from the tree.
|
| 103 | For example, to run only ``FAT_FS`` and ``EXT4`` tests you can run::
|
| 104 |
|
| 105 | ./tools/testing/kunit/kunit.py run \
|
| 106 | --kunitconfig ./fs/fat/.kunitconfig \
|
| 107 | --kunitconfig ./fs/ext4/.kunitconfig
|
| 108 |
|
| 109 | d. If you change the ``.kunitconfig``, kunit.py will trigger a rebuild of the
|
| 110 | ``.config`` file. But you can edit the ``.config`` file directly or with
|
| 111 | tools like ``make menuconfig O=.kunit``. As long as its a superset of
|
| 112 | ``.kunitconfig``, kunit.py won't overwrite your changes.
|
| 113 |
|
| 114 |
|
| 115 | .. note ::
|
| 116 |
|
| 117 | To save a .kunitconfig after finding a satisfactory configuration::
|
| 118 |
|
| 119 | make savedefconfig O=.kunit
|
| 120 | cp .kunit/defconfig .kunit/.kunitconfig
|
| 121 |
|
| 122 | Filtering tests by name
|
| 123 | ~~~~~~~~~~~~~~~~~~~~~~~
|
| 124 | If you want to be more specific than Kconfig can provide, it is also possible
|
| 125 | to select which tests to execute at boot-time by passing a glob filter
|
| 126 | (read instructions regarding the pattern in the manpage :manpage:`glob(7)`).
|
| 127 | If there is a ``"."`` (period) in the filter, it will be interpreted as a
|
| 128 | separator between the name of the test suite and the test case,
|
| 129 | otherwise, it will be interpreted as the name of the test suite.
|
| 130 | For example, let's assume we are using the default config:
|
| 131 |
|
| 132 | a. inform the name of a test suite, like ``"kunit_executor_test"``,
|
| 133 | to run every test case it contains::
|
| 134 |
|
| 135 | ./tools/testing/kunit/kunit.py run "kunit_executor_test"
|
| 136 |
|
| 137 | b. inform the name of a test case prefixed by its test suite,
|
| 138 | like ``"example.example_simple_test"``, to run specifically that test case::
|
| 139 |
|
| 140 | ./tools/testing/kunit/kunit.py run "example.example_simple_test"
|
| 141 |
|
| 142 | c. use wildcard characters (``*?[``) to run any test case that matches the pattern,
|
| 143 | like ``"*.*64*"`` to run test cases containing ``"64"`` in the name inside
|
| 144 | any test suite::
|
| 145 |
|
| 146 | ./tools/testing/kunit/kunit.py run "*.*64*"
|
| 147 |
|
| 148 | Running Tests without the KUnit Wrapper
|
| 149 | =======================================
|
| 150 | If you do not want to use the KUnit Wrapper (for example: you want code
|
| 151 | under test to integrate with other systems, or use a different/
|
| 152 | unsupported architecture or configuration), KUnit can be included in
|
| 153 | any kernel, and the results are read out and parsed manually.
|
| 154 |
|
| 155 | .. note ::
|
| 156 | ``CONFIG_KUNIT`` should not be enabled in a production environment.
|
| 157 | Enabling KUnit disables Kernel Address-Space Layout Randomization
|
| 158 | (KASLR), and tests may affect the state of the kernel in ways not
|
| 159 | suitable for production.
|
| 160 |
|
| 161 | Configuring the Kernel
|
| 162 | ----------------------
|
| 163 | To enable KUnit itself, you need to enable the ``CONFIG_KUNIT`` Kconfig
|
| 164 | option (under Kernel Hacking/Kernel Testing and Coverage in
|
| 165 | ``menuconfig``). From there, you can enable any KUnit tests. They
|
| 166 | usually have config options ending in ``_KUNIT_TEST``.
|
| 167 |
|
| 168 | KUnit and KUnit tests can be compiled as modules. The tests in a module
|
| 169 | will run when the module is loaded.
|
| 170 |
|
| 171 | Running Tests (without KUnit Wrapper)
|
| 172 | -------------------------------------
|
| 173 | Build and run your kernel. In the kernel log, the test output is printed
|
| 174 | out in the TAP format. This will only happen by default if KUnit/tests
|
| 175 | are built-in. Otherwise the module will need to be loaded.
|
| 176 |
|
| 177 | .. note ::
|
| 178 | Some lines and/or data may get interspersed in the TAP output.
|
| 179 |
|
| 180 | Writing Your First Test
|
| 181 | =======================
|
| 182 | In your kernel repository, let's add some code that we can test.
|
| 183 |
|
| 184 | 1. Create a file ``drivers/misc/example.h``, which includes:
|
| 185 |
|
| 186 | .. code-block:: c
|
| 187 |
|
| 188 | int misc_example_add(int left, int right);
|
| 189 |
|
| 190 | 2. Create a file ``drivers/misc/example.c``, which includes:
|
| 191 |
|
| 192 | .. code-block:: c
|
| 193 |
|
| 194 | #include <linux/errno.h>
|
| 195 |
|
| 196 | #include "example.h"
|
| 197 |
|
| 198 | int misc_example_add(int left, int right)
|
| 199 | {
|
| 200 | return left + right;
|
| 201 | }
|
| 202 |
|
| 203 | 3. Add the following lines to ``drivers/misc/Kconfig``:
|
| 204 |
|
| 205 | .. code-block:: kconfig
|
| 206 |
|
| 207 | config MISC_EXAMPLE
|
| 208 | bool "My example"
|
| 209 |
|
| 210 | 4. Add the following lines to ``drivers/misc/Makefile``:
|
| 211 |
|
| 212 | .. code-block:: make
|
| 213 |
|
| 214 | obj-$(CONFIG_MISC_EXAMPLE) += example.o
|
| 215 |
|
| 216 | Now we are ready to write the test cases.
|
| 217 |
|
| 218 | 1. Add the below test case in ``drivers/misc/example_test.c``:
|
| 219 |
|
| 220 | .. code-block:: c
|
| 221 |
|
| 222 | #include <kunit/test.h>
|
| 223 | #include "example.h"
|
| 224 |
|
| 225 | /* Define the test cases. */
|
| 226 |
|
| 227 | static void misc_example_add_test_basic(struct kunit *test)
|
| 228 | {
|
| 229 | KUNIT_EXPECT_EQ(test, 1, misc_example_add(1, 0));
|
| 230 | KUNIT_EXPECT_EQ(test, 2, misc_example_add(1, 1));
|
| 231 | KUNIT_EXPECT_EQ(test, 0, misc_example_add(-1, 1));
|
| 232 | KUNIT_EXPECT_EQ(test, INT_MAX, misc_example_add(0, INT_MAX));
|
| 233 | KUNIT_EXPECT_EQ(test, -1, misc_example_add(INT_MAX, INT_MIN));
|
| 234 | }
|
| 235 |
|
| 236 | static void misc_example_test_failure(struct kunit *test)
|
| 237 | {
|
| 238 | KUNIT_FAIL(test, "This test never passes.");
|
| 239 | }
|
| 240 |
|
| 241 | static struct kunit_case misc_example_test_cases[] = {
|
| 242 | KUNIT_CASE(misc_example_add_test_basic),
|
| 243 | KUNIT_CASE(misc_example_test_failure),
|
| 244 | {}
|
| 245 | };
|
| 246 |
|
| 247 | static struct kunit_suite misc_example_test_suite = {
|
| 248 | .name = "misc-example",
|
| 249 | .test_cases = misc_example_test_cases,
|
| 250 | };
|
| 251 | kunit_test_suite(misc_example_test_suite);
|
| 252 |
|
| 253 | MODULE_LICENSE("GPL");
|
| 254 |
|
| 255 | 2. Add the following lines to ``drivers/misc/Kconfig``:
|
| 256 |
|
| 257 | .. code-block:: kconfig
|
| 258 |
|
| 259 | config MISC_EXAMPLE_TEST
|
| 260 | tristate "Test for my example" if !KUNIT_ALL_TESTS
|
| 261 | depends on MISC_EXAMPLE && KUNIT
|
| 262 | default KUNIT_ALL_TESTS
|
| 263 |
|
| 264 | Note: If your test does not support being built as a loadable module (which is
|
| 265 | discouraged), replace tristate by bool, and depend on KUNIT=y instead of KUNIT.
|
| 266 |
|
| 267 | 3. Add the following lines to ``drivers/misc/Makefile``:
|
| 268 |
|
| 269 | .. code-block:: make
|
| 270 |
|
| 271 | obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o
|
| 272 |
|
| 273 | 4. Add the following lines to ``.kunit/.kunitconfig``:
|
| 274 |
|
| 275 | .. code-block:: none
|
| 276 |
|
| 277 | CONFIG_MISC_EXAMPLE=y
|
| 278 | CONFIG_MISC_EXAMPLE_TEST=y
|
| 279 |
|
| 280 | 5. Run the test:
|
| 281 |
|
| 282 | .. code-block:: bash
|
| 283 |
|
| 284 | ./tools/testing/kunit/kunit.py run
|
| 285 |
|
| 286 | You should see the following failure:
|
| 287 |
|
| 288 | .. code-block:: none
|
| 289 |
|
| 290 | ...
|
| 291 | [16:08:57] [PASSED] misc-example:misc_example_add_test_basic
|
| 292 | [16:08:57] [FAILED] misc-example:misc_example_test_failure
|
| 293 | [16:08:57] EXPECTATION FAILED at drivers/misc/example-test.c:17
|
| 294 | [16:08:57] This test never passes.
|
| 295 | ...
|
| 296 |
|
| 297 | Congrats! You just wrote your first KUnit test.
|
| 298 |
|
| 299 | Next Steps
|
| 300 | ==========
|
| 301 |
|
| 302 | If you're interested in using some of the more advanced features of kunit.py,
|
| 303 | take a look at Documentation/dev-tools/kunit/run_wrapper.rst
|
| 304 |
|
| 305 | If you'd like to run tests without using kunit.py, check out
|
| 306 | Documentation/dev-tools/kunit/run_manual.rst
|
| 307 |
|
| 308 | For more information on writing KUnit tests (including some common techniques
|
| 309 | for testing different things), see Documentation/dev-tools/kunit/usage.rst
|