1.. SPDX-License-Identifier: GPL-2.0 2 3============================ 4Tips For Running KUnit Tests 5============================ 6 7Using ``kunit.py run`` ("kunit tool") 8===================================== 9 10Running from any directory 11-------------------------- 12 13It can be handy to create a bash function like: 14 15.. code-block:: bash 16 17 function run_kunit() { 18 ( cd "$(git rev-parse --show-toplevel)" && ./tools/testing/kunit/kunit.py run $@ ) 19 } 20 21.. note:: 22 Early versions of ``kunit.py`` (before 5.6) didn't work unless run from 23 the kernel root, hence the use of a subshell and ``cd``. 24 25Running a subset of tests 26------------------------- 27 28``kunit.py run`` accepts an optional glob argument to filter tests. Currently 29this only matches against suite names, but this may change in the future. 30 31Say that we wanted to run the sysctl tests, we could do so via: 32 33.. code-block:: bash 34 35 $ echo -e 'CONFIG_KUNIT=y\nCONFIG_KUNIT_ALL_TESTS=y' > .kunit/.kunitconfig 36 $ ./tools/testing/kunit/kunit.py run 'sysctl*' 37 38We're paying the cost of building more tests than we need this way, but it's 39easier than fiddling with ``.kunitconfig`` files or commenting out 40``kunit_suite``'s. 41 42However, if we wanted to define a set of tests in a less ad hoc way, the next 43tip is useful. 44 45Defining a set of tests 46----------------------- 47 48``kunit.py run`` (along with ``build``, and ``config``) supports a 49``--kunitconfig`` flag. So if you have a set of tests that you want to run on a 50regular basis (especially if they have other dependencies), you can create a 51specific ``.kunitconfig`` for them. 52 53E.g. kunit has one for its tests: 54 55.. code-block:: bash 56 57 $ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit/.kunitconfig 58 59Alternatively, if you're following the convention of naming your 60file ``.kunitconfig``, you can just pass in the dir, e.g. 61 62.. code-block:: bash 63 64 $ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit 65 66.. note:: 67 This is a relatively new feature (5.12+) so we don't have any 68 conventions yet about on what files should be checked in versus just 69 kept around locally. It's up to you and your maintainer to decide if a 70 config is useful enough to submit (and therefore have to maintain). 71 72.. note:: 73 Having ``.kunitconfig`` fragments in a parent and child directory is 74 iffy. There's discussion about adding an "import" statement in these 75 files to make it possible to have a top-level config run tests from all 76 child directories. But that would mean ``.kunitconfig`` files are no 77 longer just simple .config fragments. 78 79 One alternative would be to have kunit tool recursively combine configs 80 automagically, but tests could theoretically depend on incompatible 81 options, so handling that would be tricky. 82 83Setting kernel commandline parameters 84------------------------------------- 85 86You can use ``--kernel_args`` to pass arbitrary kernel arguments, e.g. 87 88.. code-block:: bash 89 90 $ ./tools/testing/kunit/kunit.py run --kernel_args=param=42 --kernel_args=param2=false 91 92 93Generating code coverage reports under UML 94------------------------------------------ 95 96.. note:: 97 TODO(brendanhiggins@google.com): There are various issues with UML and 98 versions of gcc 7 and up. You're likely to run into missing ``.gcda`` 99 files or compile errors. 100 101This is different from the "normal" way of getting coverage information that is 102documented in Documentation/dev-tools/gcov.rst. 103 104Instead of enabling ``CONFIG_GCOV_KERNEL=y``, we can set these options: 105 106.. code-block:: none 107 108 CONFIG_DEBUG_KERNEL=y 109 CONFIG_DEBUG_INFO=y 110 CONFIG_GCOV=y 111 112 113Putting it together into a copy-pastable sequence of commands: 114 115.. code-block:: bash 116 117 # Append coverage options to the current config 118 $ echo -e "CONFIG_DEBUG_KERNEL=y\nCONFIG_DEBUG_INFO=y\nCONFIG_GCOV=y" >> .kunit/.kunitconfig 119 $ ./tools/testing/kunit/kunit.py run 120 # Extract the coverage information from the build dir (.kunit/) 121 $ lcov -t "my_kunit_tests" -o coverage.info -c -d .kunit/ 122 123 # From here on, it's the same process as with CONFIG_GCOV_KERNEL=y 124 # E.g. can generate an HTML report in a tmp dir like so: 125 $ genhtml -o /tmp/coverage_html coverage.info 126 127 128If your installed version of gcc doesn't work, you can tweak the steps: 129 130.. code-block:: bash 131 132 $ ./tools/testing/kunit/kunit.py run --make_options=CC=/usr/bin/gcc-6 133 $ lcov -t "my_kunit_tests" -o coverage.info -c -d .kunit/ --gcov-tool=/usr/bin/gcov-6 134 135 136Running tests manually 137====================== 138 139Running tests without using ``kunit.py run`` is also an important use case. 140Currently it's your only option if you want to test on architectures other than 141UML. 142 143As running the tests under UML is fairly straightforward (configure and compile 144the kernel, run the ``./linux`` binary), this section will focus on testing 145non-UML architectures. 146 147 148Running built-in tests 149---------------------- 150 151When setting tests to ``=y``, the tests will run as part of boot and print 152results to dmesg in TAP format. So you just need to add your tests to your 153``.config``, build and boot your kernel as normal. 154 155So if we compiled our kernel with: 156 157.. code-block:: none 158 159 CONFIG_KUNIT=y 160 CONFIG_KUNIT_EXAMPLE_TEST=y 161 162Then we'd see output like this in dmesg signaling the test ran and passed: 163 164.. code-block:: none 165 166 TAP version 14 167 1..1 168 # Subtest: example 169 1..1 170 # example_simple_test: initializing 171 ok 1 - example_simple_test 172 ok 1 - example 173 174Running tests as modules 175------------------------ 176 177Depending on the tests, you can build them as loadable modules. 178 179For example, we'd change the config options from before to 180 181.. code-block:: none 182 183 CONFIG_KUNIT=y 184 CONFIG_KUNIT_EXAMPLE_TEST=m 185 186Then after booting into our kernel, we can run the test via 187 188.. code-block:: none 189 190 $ modprobe kunit-example-test 191 192This will then cause it to print TAP output to stdout. 193 194.. note:: 195 The ``modprobe`` will *not* have a non-zero exit code if any test 196 failed (as of 5.13). But ``kunit.py parse`` would, see below. 197 198.. note:: 199 You can set ``CONFIG_KUNIT=m`` as well, however, some features will not 200 work and thus some tests might break. Ideally tests would specify they 201 depend on ``KUNIT=y`` in their ``Kconfig``'s, but this is an edge case 202 most test authors won't think about. 203 As of 5.13, the only difference is that ``current->kunit_test`` will 204 not exist. 205 206Pretty-printing results 207----------------------- 208 209You can use ``kunit.py parse`` to parse dmesg for test output and print out 210results in the same familiar format that ``kunit.py run`` does. 211 212.. code-block:: bash 213 214 $ ./tools/testing/kunit/kunit.py parse /var/log/dmesg 215 216 217Retrieving per suite results 218---------------------------- 219 220Regardless of how you're running your tests, you can enable 221``CONFIG_KUNIT_DEBUGFS`` to expose per-suite TAP-formatted results: 222 223.. code-block:: none 224 225 CONFIG_KUNIT=y 226 CONFIG_KUNIT_EXAMPLE_TEST=m 227 CONFIG_KUNIT_DEBUGFS=y 228 229The results for each suite will be exposed under 230``/sys/kernel/debug/kunit/<suite>/results``. 231So using our example config: 232 233.. code-block:: bash 234 235 $ modprobe kunit-example-test > /dev/null 236 $ cat /sys/kernel/debug/kunit/example/results 237 ... <TAP output> ... 238 239 # After removing the module, the corresponding files will go away 240 $ modprobe -r kunit-example-test 241 $ cat /sys/kernel/debug/kunit/example/results 242 /sys/kernel/debug/kunit/example/results: No such file or directory 243 244Generating code coverage reports 245-------------------------------- 246 247See Documentation/dev-tools/gcov.rst for details on how to do this. 248 249The only vaguely KUnit-specific advice here is that you probably want to build 250your tests as modules. That way you can isolate the coverage from tests from 251other code executed during boot, e.g. 252 253.. code-block:: bash 254 255 # Reset coverage counters before running the test. 256 $ echo 0 > /sys/kernel/debug/gcov/reset 257 $ modprobe kunit-example-test 258