1 .. SPDX-License-Identifier: GPL-2.0+
9 Most uclasses and many functions of U-Boot have sandbox tests. This allows much
10 of the code to be checked in an developer-friendly environment.
12 Sandbox provides a way to write and run unit tests. The traditional approach to
13 unit tests is to build lots of little executables, one for each test or
14 category of tests. With sandbox, so far as possible, all the tests share a
15 small number of executables (e.g. 'u-boot' for sandbox, 'u-boot-spl' and
16 'u-boot' for sandbox_spl) and can be run very quickly. The vast majority of
17 tests can run on the 'sandbox' build,
22 Some of the available tests are:
24 - command_ut: Unit tests for command parsing and handling
25 - compression: Unit tests for U-Boot's compression algorithms, useful for
26 security checking. It supports gzip, bzip2, lzma and lzo.
27 - image: Unit tests for images:
29 - test/image/test-imagetools.sh - multi-file images
30 - test/py/tests/test-fit.py - FIT images
31 - tracing: test/trace/test-trace.sh tests the tracing system
33 - verified boot: test/py/tests/test_vboot.py
35 If you change or enhance any U-Boot subsystem, you should write or expand a
36 test and include it with your patch series submission. Test coverage in some
37 older areas of U-Boot is still somewhat limited and we need to work to improve
40 Note that many of these tests are implemented as commands which you can
41 run natively on your board if desired (and enabled).
43 To run all tests, use 'make check'.
46 Running sandbox tests directly
47 ------------------------------
49 Typically tests are run using the pytest suite. Running pytests on sandbox is
50 easy and always gets things right. For example some tests require files to be
51 set up before they can work.
53 But it is also possible to run some sandbox tests directly. For example, this
54 runs the dm_test_gpio() test which you can find in test/dm/gpio.c::
56 $ ./u-boot -T -c "ut dm gpio"
63 WDT: Started with servicing (60s timeout)
64 MMC: mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
70 Net: eth0: eth@10002000, eth5: eth@10003000, eth3: sbe5, eth6: eth@10004000
71 Test: dm_test_gpio: gpio.c
72 Test: dm_test_gpio: gpio.c (flat tree)
75 The -T option tells the U-Boot sandbox to run with the 'test' devicetree
76 (test.dts) instead of -D which selects the normal sandbox.dts - this is
77 necessary because many tests rely on nodes or properties in the test devicetree.
78 If you try running tests without -T then you may see failures, like::
80 $ ./u-boot -c "ut dm gpio"
92 Net: No ethernet found.
93 Please run with test device tree:
94 ./u-boot -d arch/sandbox/dts/test.dtb
95 Test: dm_test_gpio: gpio.c
96 test/dm/gpio.c:37, dm_test_gpio(): 0 == gpio_lookup_name("b4", &dev, &offset, &gpio): Expected 0x0 (0), got 0xffffffea (-22)
97 Test: dm_test_gpio: gpio.c (flat tree)
98 test/dm/gpio.c:37, dm_test_gpio(): 0 == gpio_lookup_name("b4", &dev, &offset, &gpio): Expected 0x0 (0), got 0xffffffea (-22)
101 The message above should provide a hint if you forget to use the -T flag. Even
102 running with -D will produce different results.
104 You can easily use gdb on these tests, without needing --gdbserver::
106 $ gdb --args u-boot -T -c "ut dm gpio"
108 (gdb) break dm_test_gpio
109 Breakpoint 1 at 0x1415bd: file test/dm/gpio.c, line 37.
110 (gdb) run -T -c "ut dm gpio"
111 Starting program: u-boot -T -c "ut dm gpio"
112 Test: dm_test_gpio: gpio.c
114 Breakpoint 1, dm_test_gpio (uts=0x5555558029a0 <global_dm_test_state>)
115 at files/test/dm/gpio.c:37
116 37 ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio));
119 You can then single-step and look at variables as needed.
122 Running tests multiple times
123 ----------------------------
125 Some tests can have race conditions which are hard to detect on a single
126 one. It is possible to run each individual test multiple times, before moving
127 to the next test, with the '-r' flag.
129 This is most useful when running a single test, since running all tests
130 multiple times can take a while.
134 => ut dm -r1000 dm_test_rtc_set_get
136 Test: dm_test_rtc_set_get: rtc.c (flat tree)
137 Test: dm_test_rtc_set_get: rtc.c
138 test/dm/rtc.c:257, dm_test_rtc_reset(): old_base_time == base_time: Expected 0x62e7453c (1659323708), got 0x62e7453d (1659323709)
139 Test: dm_test_rtc_set_get: rtc.c (flat tree)
140 Test: dm_test_rtc_set_get: rtc.c
141 Test: dm_test_rtc_set_get: rtc.c (flat tree)
143 Test dm_test_rtc_reset failed 3 times
146 Isolating a test that breaks another
147 ------------------------------------
149 When running unit tests, some may have side effects which cause a subsequent
150 test to break. This can sometimes be seen when using 'ut dm' or similar.
152 You can use the `-I` argument to the `ut` command to isolate this problem.
153 First use `ut info` to see how many tests there are, then use a binary search to
154 home in on the problem. Note that you might need to restart U-Boot after each
155 iteration, so the `-c` argument to U-Boot is useful.
157 For example, let's stay that dm_test_host() is failing::
161 Test: dm_test_get_stats: core.c
162 Test: dm_test_get_stats: core.c (flat tree)
163 Test: dm_test_host: host.c
164 test/dm/host.c:71, dm_test_host(): 0 == ut_check_delta(mem_start): Expected 0x0 (0), got 0xffffcbb0 (-13392)
165 Test: dm_test_host: host.c (flat tree)
166 Test <NULL> failed 1 times
167 Test: dm_test_host_dup: host.c
168 Test: dm_test_host_dup: host.c (flat tree)
171 You can then tell U-Boot to run the failing test at different points in the
180 $ ./u-boot -T -c "ut dm -I300:dm_test_host"
182 Test: dm_test_pinctrl_single: pinmux.c (flat tree)
183 Test: dm_test_host: host.c
184 test/dm/host.c:71, dm_test_host(): 0 == ut_check_delta(mem_start): Expected 0x0 (0), got 0xfffffdb0 (-592)
185 Test: dm_test_host: host.c (flat tree)
186 Test dm_test_host failed 1 times (position 300)
189 So it happened before position 300. Trying 150 shows it failing, so we try 75::
191 $ ./u-boot -T -c "ut dm -I75:dm_test_host"
193 Test: dm_test_autoprobe: core.c
194 Test: dm_test_autoprobe: core.c (flat tree)
195 Test: dm_test_host: host.c
196 Test: dm_test_host: host.c (flat tree)
199 That succeeds, so we try 120, etc. until eventually we can figure out that the
200 problem first happens at position 82.
202 $ ./u-boot -T -c "ut dm -I82:dm_test_host"
204 Test: dm_test_blk_flags: blk.c
205 Test: dm_test_blk_flags: blk.c (flat tree)
206 Test: dm_test_host: host.c
207 test/dm/host.c:71, dm_test_host(): 0 == ut_check_delta(mem_start): Expected 0x0 (0), got 0xffffc960 (-13984)
208 Test: dm_test_host: host.c (flat tree)
209 Test dm_test_host failed 1 times (position 82)
212 From this we can deduce that `dm_test_blk_flags()` causes the problem with
215 Running sandbox_spl tests directly
216 ----------------------------------
218 SPL is the phase before U-Boot proper. It is present in the sandbox_spl build,
219 so you can run SPL like this::
223 SPL tests are special in that they run (only in the SPL phase, of course) if the
228 U-Boot SPL 2021.01-00723-g43c77b51be5-dirty (Jan 24 2021 - 16:38:24 -0700)
229 Running 5 driver model tests
230 Test: dm_test_of_plat_base: of_platdata.c (flat tree)
231 Test: dm_test_of_plat_dev: of_platdata.c (flat tree)
232 Test: dm_test_of_plat_parent: of_platdata.c (flat tree)
233 Test: dm_test_of_plat_phandle: of_platdata.c (flat tree)
234 Test: dm_test_of_plat_props: of_platdata.c (flat tree)
238 U-Boot 2021.01-00723-g43c77b51be5-dirty (Jan 24 2021 - 16:38:24 -0700)
243 It is not possible to run SPL tests in U-Boot proper, firstly because they are
244 not built into U-Boot proper and secondly because the environment is very
245 different, e.g. some SPL tests rely on of-platdata which is only available in
248 Note that after running, SPL continues to boot into U-Boot proper. You can add
249 '-c exit' to make U-Boot quit without doing anything further. It is not
250 currently possible to run SPL tests and then stop, since the pytests require
251 that U-Boot produces the expected banner.
253 You can use the -k flag to select which tests run::
255 ./spl/u-boot-spl -u -k dm_test_of_plat_parent
257 Of course you can use gdb with sandbox_spl, just as with sandbox.
260 Running all tests directly
261 --------------------------
263 A fast way to run all sandbox tests is::
265 ./u-boot -T -c "ut all"
267 It typically runs single-thread in 6 seconds on 2021 hardware, with 2s of that
268 to the delays in the time test.
270 This should not be considered a substitute for 'make check', but can be helpful
274 What tests are built in?
275 ------------------------
277 Whatever sandbox build is used, which tests are present is determined by which
278 source files are built. For sandbox_spl, the of_platdata tests are built
279 because of the build rule in test/dm/Makefile::
281 ifeq ($(CONFIG_XPL_BUILD),y)
282 obj-$(CONFIG_SPL_OF_PLATDATA) += of_platdata.o
284 ...other tests for non-spl
287 You can get a list of tests in a U-Boot ELF file by looking for the
290 $ nm /tmp/b/sandbox_spl/spl/u-boot-spl |grep 2_dm_test
291 000000000001f200 D _u_boot_list_2_dm_test_2_dm_test_of_plat_base
292 000000000001f220 D _u_boot_list_2_dm_test_2_dm_test_of_plat_dev
293 000000000001f240 D _u_boot_list_2_dm_test_2_dm_test_of_plat_parent
294 000000000001f260 D _u_boot_list_2_dm_test_2_dm_test_of_plat_phandle
295 000000000001f280 D _u_boot_list_2_dm_test_2_dm_test_of_plat_props
301 See :doc:`tests_writing` for how to write new tests.