tests_sandbox.rst 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. .. SPDX-License-Identifier: GPL-2.0+
  2. Sandbox tests
  3. =============
  4. Test Design
  5. -----------
  6. Most uclasses and many functions of U-Boot have sandbox tests. This allows much
  7. of the code to be checked in an developer-friendly environment.
  8. Sandbox provides a way to write and run unit tests. The traditional approach to
  9. unit tests is to build lots of little executables, one for each test or
  10. category of tests. With sandbox, so far as possible, all the tests share a
  11. small number of executables (e.g. 'u-boot' for sandbox, 'u-boot-spl' and
  12. 'u-boot' for sandbox_spl) and can be run very quickly. The vast majority of
  13. tests can run on the 'sandbox' build,
  14. Available tests
  15. ---------------
  16. Some of the available tests are:
  17. - command_ut: Unit tests for command parsing and handling
  18. - compression: Unit tests for U-Boot's compression algorithms, useful for
  19. security checking. It supports gzip, bzip2, lzma and lzo.
  20. - image: Unit tests for images:
  21. - test/image/test-imagetools.sh - multi-file images
  22. - test/py/tests/test-fit.py - FIT images
  23. - tracing: test/trace/test-trace.sh tests the tracing system (see
  24. README.trace)
  25. - verified boot: test/py/tests/test_vboot.py
  26. If you change or enhance any U-Boot subsystem, you should write or expand a
  27. test and include it with your patch series submission. Test coverage in some
  28. older areas of U-Boot is still somewhat limited and we need to work to improve
  29. it.
  30. Note that many of these tests are implemented as commands which you can
  31. run natively on your board if desired (and enabled).
  32. To run all tests, use 'make check'.
  33. Running sandbox tests directly
  34. ------------------------------
  35. Typically tests are run using the pytest suite. Running pytests on sandbox is
  36. easy and always gets things right. For example some tests require files to be
  37. set up before they can work.
  38. But it is also possible to run some sandbox tests directly. For example, this
  39. runs the dm_test_gpio() test which you can find in test/dm/gpio.c::
  40. $ ./u-boot -T -c "ut dm gpio"
  41. U-Boot 2021.01
  42. Model: sandbox
  43. DRAM: 128 MiB
  44. WDT: Started with servicing (60s timeout)
  45. MMC: mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
  46. In: serial
  47. Out: vidconsole
  48. Err: vidconsole
  49. Model: sandbox
  50. SCSI:
  51. Net: eth0: eth@10002000, eth5: eth@10003000, eth3: sbe5, eth6: eth@10004000
  52. Test: dm_test_gpio: gpio.c
  53. Test: dm_test_gpio: gpio.c (flat tree)
  54. Failures: 0
  55. The -T option tells the U-Boot sandbox to run with the 'test' devicetree
  56. (test.dts) instead of -D which selects the normal sandbox.dts - this is
  57. necessary because many tests rely on nodes or properties in the test devicetree.
  58. If you try running tests without -T then you may see failures, like::
  59. $ ./u-boot -c "ut dm gpio"
  60. U-Boot 2021.01
  61. DRAM: 128 MiB
  62. WDT: Not found!
  63. MMC:
  64. In: serial
  65. Out: serial
  66. Err: serial
  67. SCSI:
  68. Net: No ethernet found.
  69. Please run with test device tree:
  70. ./u-boot -d arch/sandbox/dts/test.dtb
  71. Test: dm_test_gpio: gpio.c
  72. test/dm/gpio.c:37, dm_test_gpio(): 0 == gpio_lookup_name("b4", &dev, &offset, &gpio): Expected 0x0 (0), got 0xffffffea (-22)
  73. Test: dm_test_gpio: gpio.c (flat tree)
  74. test/dm/gpio.c:37, dm_test_gpio(): 0 == gpio_lookup_name("b4", &dev, &offset, &gpio): Expected 0x0 (0), got 0xffffffea (-22)
  75. Failures: 2
  76. The message above should provide a hint if you forget to use the -T flag. Even
  77. running with -D will produce different results.
  78. You can easily use gdb on these tests, without needing --gdbserver::
  79. $ gdb --args u-boot -T -c "ut dm gpio"
  80. ...
  81. (gdb) break dm_test_gpio
  82. Breakpoint 1 at 0x1415bd: file test/dm/gpio.c, line 37.
  83. (gdb) run -T -c "ut dm gpio"
  84. Starting program: u-boot -T -c "ut dm gpio"
  85. Test: dm_test_gpio: gpio.c
  86. Breakpoint 1, dm_test_gpio (uts=0x5555558029a0 <global_dm_test_state>)
  87. at files/test/dm/gpio.c:37
  88. 37 ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio));
  89. (gdb)
  90. You can then single-step and look at variables as needed.
  91. Running tests multiple times
  92. ----------------------------
  93. Some tests can have race conditions which are hard to detect on a single
  94. one. It is possible to run each individual test multiple times, before moving
  95. to the next test, with the '-r' flag.
  96. This is most useful when running a single test, since running all tests
  97. multiple times can take a while.
  98. For example::
  99. => ut dm -r1000 dm_test_rtc_set_get
  100. ...
  101. Test: dm_test_rtc_set_get: rtc.c (flat tree)
  102. Test: dm_test_rtc_set_get: rtc.c
  103. test/dm/rtc.c:257, dm_test_rtc_reset(): old_base_time == base_time: Expected 0x62e7453c (1659323708), got 0x62e7453d (1659323709)
  104. Test: dm_test_rtc_set_get: rtc.c (flat tree)
  105. Test: dm_test_rtc_set_get: rtc.c
  106. Test: dm_test_rtc_set_get: rtc.c (flat tree)
  107. ...
  108. Test dm_test_rtc_reset failed 3 times
  109. Isolating a test that breaks another
  110. ------------------------------------
  111. When running unit tests, some may have side effects which cause a subsequent
  112. test to break. This can sometimes be seen when using 'ut dm' or similar.
  113. You can use the `-I` argument to the `ut` command to isolate this problem.
  114. First use `ut info` to see how many tests there are, then use a binary search to
  115. home in on the problem. Note that you might need to restart U-Boot after each
  116. iteration, so the `-c` argument to U-Boot is useful.
  117. For example, let's stay that dm_test_host() is failing::
  118. => ut dm
  119. ...
  120. Test: dm_test_get_stats: core.c
  121. Test: dm_test_get_stats: core.c (flat tree)
  122. Test: dm_test_host: host.c
  123. test/dm/host.c:71, dm_test_host(): 0 == ut_check_delta(mem_start): Expected 0x0 (0), got 0xffffcbb0 (-13392)
  124. Test: dm_test_host: host.c (flat tree)
  125. Test <NULL> failed 1 times
  126. Test: dm_test_host_dup: host.c
  127. Test: dm_test_host_dup: host.c (flat tree)
  128. ...
  129. You can then tell U-Boot to run the failing test at different points in the
  130. sequence:
  131. => ut info
  132. Test suites: 21
  133. Total tests: 645
  134. ::
  135. $ ./u-boot -T -c "ut dm -I300:dm_test_host"
  136. ...
  137. Test: dm_test_pinctrl_single: pinmux.c (flat tree)
  138. Test: dm_test_host: host.c
  139. test/dm/host.c:71, dm_test_host(): 0 == ut_check_delta(mem_start): Expected 0x0 (0), got 0xfffffdb0 (-592)
  140. Test: dm_test_host: host.c (flat tree)
  141. Test dm_test_host failed 1 times (position 300)
  142. Failures: 4
  143. So it happened before position 300. Trying 150 shows it failing, so we try 75::
  144. $ ./u-boot -T -c "ut dm -I75:dm_test_host"
  145. ...
  146. Test: dm_test_autoprobe: core.c
  147. Test: dm_test_autoprobe: core.c (flat tree)
  148. Test: dm_test_host: host.c
  149. Test: dm_test_host: host.c (flat tree)
  150. Failures: 0
  151. That succeeds, so we try 120, etc. until eventually we can figure out that the
  152. problem first happens at position 82.
  153. $ ./u-boot -T -c "ut dm -I82:dm_test_host"
  154. ...
  155. Test: dm_test_blk_flags: blk.c
  156. Test: dm_test_blk_flags: blk.c (flat tree)
  157. Test: dm_test_host: host.c
  158. test/dm/host.c:71, dm_test_host(): 0 == ut_check_delta(mem_start): Expected 0x0 (0), got 0xffffc960 (-13984)
  159. Test: dm_test_host: host.c (flat tree)
  160. Test dm_test_host failed 1 times (position 82)
  161. Failures: 1
  162. From this we can deduce that `dm_test_blk_flags()` causes the problem with
  163. `dm_test_host()`.
  164. Running sandbox_spl tests directly
  165. ----------------------------------
  166. SPL is the phase before U-Boot proper. It is present in the sandbox_spl build,
  167. so you can run SPL like this::
  168. ./spl/u-boot-spl
  169. SPL tests are special in that they run (only in the SPL phase, of course) if the
  170. -u flag is given::
  171. ./spl/u-boot-spl -u
  172. U-Boot SPL 2021.01-00723-g43c77b51be5-dirty (Jan 24 2021 - 16:38:24 -0700)
  173. Running 5 driver model tests
  174. Test: dm_test_of_plat_base: of_platdata.c (flat tree)
  175. Test: dm_test_of_plat_dev: of_platdata.c (flat tree)
  176. Test: dm_test_of_plat_parent: of_platdata.c (flat tree)
  177. Test: dm_test_of_plat_phandle: of_platdata.c (flat tree)
  178. Test: dm_test_of_plat_props: of_platdata.c (flat tree)
  179. Failures: 0
  180. U-Boot 2021.01-00723-g43c77b51be5-dirty (Jan 24 2021 - 16:38:24 -0700)
  181. DRAM: 128 MiB
  182. ...
  183. It is not possible to run SPL tests in U-Boot proper, firstly because they are
  184. not built into U-Boot proper and secondly because the environment is very
  185. different, e.g. some SPL tests rely on of-platdata which is only available in
  186. SPL.
  187. Note that after running, SPL continues to boot into U-Boot proper. You can add
  188. '-c exit' to make U-Boot quit without doing anything further. It is not
  189. currently possible to run SPL tests and then stop, since the pytests require
  190. that U-Boot produces the expected banner.
  191. You can use the -k flag to select which tests run::
  192. ./spl/u-boot-spl -u -k dm_test_of_plat_parent
  193. Of course you can use gdb with sandbox_spl, just as with sandbox.
  194. Running all tests directly
  195. --------------------------
  196. A fast way to run all sandbox tests is::
  197. ./u-boot -T -c "ut all"
  198. It typically runs single-thread in 6 seconds on 2021 hardware, with 2s of that
  199. to the delays in the time test.
  200. This should not be considered a substitute for 'make check', but can be helpful
  201. for git bisect, etc.
  202. What tests are built in?
  203. ------------------------
  204. Whatever sandbox build is used, which tests are present is determined by which
  205. source files are built. For sandbox_spl, the of_platdata tests are built
  206. because of the build rule in test/dm/Makefile::
  207. ifeq ($(CONFIG_SPL_BUILD),y)
  208. obj-$(CONFIG_SPL_OF_PLATDATA) += of_platdata.o
  209. else
  210. ...other tests for non-spl
  211. endif
  212. You can get a list of tests in a U-Boot ELF file by looking for the
  213. linker_list::
  214. $ nm /tmp/b/sandbox_spl/spl/u-boot-spl |grep 2_dm_test
  215. 000000000001f200 D _u_boot_list_2_dm_test_2_dm_test_of_plat_base
  216. 000000000001f220 D _u_boot_list_2_dm_test_2_dm_test_of_plat_dev
  217. 000000000001f240 D _u_boot_list_2_dm_test_2_dm_test_of_plat_parent
  218. 000000000001f260 D _u_boot_list_2_dm_test_2_dm_test_of_plat_phandle
  219. 000000000001f280 D _u_boot_list_2_dm_test_2_dm_test_of_plat_props
  220. Writing tests
  221. -------------
  222. See :doc:`tests_writing` for how to write new tests.