running_tips.rst 7.8 KB

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