blob: 8d764892fa6a45956154c14034d9c10013d6ed57 [file] [log] [blame]
Simon Glass5722fb22021-03-07 17:34:47 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2021 Google LLC
4 * Written by Simon Glass <sjg@chromium.org>
5 */
6
Simon Glassbe277ee2024-10-28 13:47:53 +01007#define LOG_CATEGORY LOGC_TEST
8
Simon Glass76c62692022-10-29 19:47:08 -06009#include <blk.h>
Simon Glass5722fb22021-03-07 17:34:47 -070010#include <console.h>
Stefan Roese5be8f372022-09-02 13:57:54 +020011#include <cyclic.h>
Simon Glassd18f7392021-03-07 17:34:50 -070012#include <dm.h>
Simon Glassa128b1b2022-03-04 08:43:01 -070013#include <event.h>
Simon Glassb490f5f2023-01-17 10:47:28 -070014#include <net.h>
Simon Glassb9958072022-09-06 20:27:11 -060015#include <of_live.h>
Simon Glass3ba76752022-09-06 20:27:05 -060016#include <os.h>
Simon Glass1880b8a2024-09-01 16:26:20 -060017#include <usb.h>
Simon Glassba8457b2022-09-06 20:27:19 -060018#include <dm/ofnode.h>
Simon Glassd18f7392021-03-07 17:34:50 -070019#include <dm/root.h>
Simon Glass2dba4762021-03-07 17:34:58 -070020#include <dm/test.h>
Simon Glass5b7e55b2021-03-07 17:34:59 -070021#include <dm/uclass-internal.h>
Simon Glass5722fb22021-03-07 17:34:47 -070022#include <test/test.h>
Simon Glassd18f7392021-03-07 17:34:50 -070023#include <test/ut.h>
Simon Glass3ba76752022-09-06 20:27:05 -060024#include <u-boot/crc.h>
Simon Glass5722fb22021-03-07 17:34:47 -070025
Simon Glass0f8f6772021-03-07 17:34:49 -070026DECLARE_GLOBAL_DATA_PTR;
27
Simon Glass3ba76752022-09-06 20:27:05 -060028/**
29 * enum fdtchk_t - what to do with the device tree (gd->fdt_blob)
30 *
31 * This affects what happens with the device tree before and after a test
32 *
33 * @FDTCHK_NONE: Do nothing
34 * @FDTCHK_CHECKSUM: Take a checksum of the FDT before the test runs and
35 * compare it afterwards to detect any changes
36 * @FDTCHK_COPY: Make a copy of the FDT and restore it afterwards
37 */
38enum fdtchk_t {
39 FDTCHK_NONE,
40 FDTCHK_CHECKSUM,
41 FDTCHK_COPY,
42};
43
44/**
45 * fdt_action() - get the required action for the FDT
46 *
47 * @return the action that should be taken for this build
48 */
49static enum fdtchk_t fdt_action(void)
50{
Simon Glass3ba76752022-09-06 20:27:05 -060051 /* For sandbox SPL builds, do nothing */
Simon Glass0e84d962024-09-29 19:49:50 -060052 if (IS_ENABLED(CONFIG_SANDBOX) && IS_ENABLED(CONFIG_XPL_BUILD))
Simon Glass3ba76752022-09-06 20:27:05 -060053 return FDTCHK_NONE;
54
Simon Glass234f05b2023-02-22 09:34:12 -070055 /* Do a copy for sandbox (but only the U-Boot build, not SPL) */
56 if (IS_ENABLED(CONFIG_SANDBOX))
57 return FDTCHK_COPY;
58
Simon Glass3ba76752022-09-06 20:27:05 -060059 /* For all other boards, do a checksum */
60 return FDTCHK_CHECKSUM;
61}
62
Simon Glass4066d8d2021-03-07 17:35:04 -070063/* This is valid when a test is running, NULL otherwise */
64static struct unit_test_state *cur_test_state;
65
66struct unit_test_state *test_get_state(void)
67{
68 return cur_test_state;
69}
70
71void test_set_state(struct unit_test_state *uts)
72{
73 cur_test_state = uts;
74}
75
Simon Glass2dba4762021-03-07 17:34:58 -070076/**
77 * dm_test_pre_run() - Get ready to run a driver model test
78 *
79 * This clears out the driver model data structures. For sandbox it resets the
80 * state structure
81 *
82 * @uts: Test state
83 */
84static int dm_test_pre_run(struct unit_test_state *uts)
85{
86 bool of_live = uts->of_live;
87
Simon Glass60f08992022-09-06 20:27:06 -060088 if (of_live && (gd->flags & GD_FLG_FDT_CHANGED)) {
89 printf("Cannot run live tree test as device tree changed\n");
90 return -EFAULT;
91 }
Simon Glass2dba4762021-03-07 17:34:58 -070092 uts->root = NULL;
93 uts->testdev = NULL;
94 uts->force_fail_alloc = false;
95 uts->skip_post_probe = false;
Simon Glass3ba76752022-09-06 20:27:05 -060096 if (fdt_action() == FDTCHK_CHECKSUM)
97 uts->fdt_chksum = crc8(0, gd->fdt_blob,
98 fdt_totalsize(gd->fdt_blob));
Simon Glass2dba4762021-03-07 17:34:58 -070099 gd->dm_root = NULL;
Simon Glass1a3e39b2022-09-06 20:27:00 -0600100 malloc_disable_testing();
Simon Glassf7005042021-07-05 16:32:43 -0600101 if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
Simon Glass2dba4762021-03-07 17:34:58 -0700102 memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
Simon Glass45b807d2021-03-25 10:44:33 +1300103 arch_reset_for_test();
Simon Glass2dba4762021-03-07 17:34:58 -0700104
105 /* Determine whether to make the live tree available */
106 gd_set_of_root(of_live ? uts->of_root : NULL);
Simon Glassba8457b2022-09-06 20:27:19 -0600107 oftree_reset();
Simon Glass2dba4762021-03-07 17:34:58 -0700108 ut_assertok(dm_init(of_live));
109 uts->root = dm_root();
110
111 return 0;
112}
113
Simon Glass5b7e55b2021-03-07 17:34:59 -0700114static int dm_test_post_run(struct unit_test_state *uts)
115{
116 int id;
117
Simon Glass3ba76752022-09-06 20:27:05 -0600118 if (gd->fdt_blob) {
119 switch (fdt_action()) {
120 case FDTCHK_COPY:
121 memcpy((void *)gd->fdt_blob, uts->fdt_copy, uts->fdt_size);
122 break;
123 case FDTCHK_CHECKSUM: {
124 uint chksum;
125
126 chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob));
Simon Glass60f08992022-09-06 20:27:06 -0600127 if (chksum != uts->fdt_chksum) {
128 /*
129 * We cannot run any more tests that need the
130 * live tree, since its strings point into the
131 * flat tree, which has changed. This likely
132 * means that at least some of the pointers from
133 * the live tree point to different things
134 */
Simon Glass3ba76752022-09-06 20:27:05 -0600135 printf("Device tree changed: cannot run live tree tests\n");
Simon Glass60f08992022-09-06 20:27:06 -0600136 gd->flags |= GD_FLG_FDT_CHANGED;
137 }
Simon Glass3ba76752022-09-06 20:27:05 -0600138 break;
139 }
140 case FDTCHK_NONE:
141 break;
142 }
143 }
144
Simon Glass96113c12021-03-15 17:25:21 +1300145 /*
146 * With of-platdata-inst the uclasses are created at build time. If we
147 * destroy them we cannot get them back since uclass_add() is not
148 * supported. So skip this.
149 */
150 if (!CONFIG_IS_ENABLED(OF_PLATDATA_INST)) {
151 for (id = 0; id < UCLASS_COUNT; id++) {
152 struct uclass *uc;
Simon Glass5b7e55b2021-03-07 17:34:59 -0700153
Simon Glass96113c12021-03-15 17:25:21 +1300154 /*
155 * If the uclass doesn't exist we don't want to create
156 * it. So check that here before we call
157 * uclass_find_device().
158 */
159 uc = uclass_find(id);
160 if (!uc)
161 continue;
162 ut_assertok(uclass_destroy(uc));
163 }
Simon Glass5b7e55b2021-03-07 17:34:59 -0700164 }
165
166 return 0;
167}
168
Simon Glass242357c2021-03-07 17:34:51 -0700169/* Ensure all the test devices are probed */
170static int do_autoprobe(struct unit_test_state *uts)
171{
Michal Suchanek44322b52022-10-12 21:57:51 +0200172 return uclass_probe_all(UCLASS_TEST);
Simon Glass242357c2021-03-07 17:34:51 -0700173}
174
Simon Glass0d32ec22021-03-07 17:35:03 -0700175/*
176 * ut_test_run_on_flattree() - Check if we should run a test with flat DT
177 *
178 * This skips long/slow tests where there is not much value in running a flat
179 * DT test in addition to a live DT test.
180 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100181 * Return: true to run the given test on the flat device tree
Simon Glass0d32ec22021-03-07 17:35:03 -0700182 */
183static bool ut_test_run_on_flattree(struct unit_test *test)
184{
185 const char *fname = strrchr(test->file, '/') + 1;
186
Simon Glass1a92f832024-08-22 07:57:48 -0600187 if (!(test->flags & UTF_DM))
Simon Glass0d32ec22021-03-07 17:35:03 -0700188 return false;
189
190 return !strstr(fname, "video") || strstr(test->name, "video_base");
191}
192
Simon Glass436687e2021-03-07 17:35:01 -0700193/**
Simon Glassbb2b1732021-03-07 17:35:05 -0700194 * test_matches() - Check if a test should be run
195 *
196 * This checks if the a test should be run. In the normal case of running all
197 * tests, @select_name is NULL.
198 *
199 * @prefix: String prefix for the tests. Any tests that have this prefix will be
200 * printed without the prefix, so that it is easier to see the unique part
Simon Glass1ef74ab2021-03-07 17:35:12 -0700201 * of the test name. If NULL, any suite name (xxx_test) is considered to be
202 * a prefix.
Simon Glassbb2b1732021-03-07 17:35:05 -0700203 * @test_name: Name of current test
204 * @select_name: Name of test to run (or NULL for all)
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100205 * Return: true to run this test, false to skip it
Simon Glassbb2b1732021-03-07 17:35:05 -0700206 */
207static bool test_matches(const char *prefix, const char *test_name,
208 const char *select_name)
209{
Andy Shevchenkod91cfbb2021-02-11 16:40:10 +0200210 size_t len;
211
Simon Glassbb2b1732021-03-07 17:35:05 -0700212 if (!select_name)
213 return true;
214
Andy Shevchenkod91cfbb2021-02-11 16:40:10 +0200215 /* Allow glob expansion in the test name */
216 len = select_name[strlen(select_name) - 1] == '*' ? strlen(select_name) : 0;
217 if (len-- == 1)
218 return true;
219
220 if (!strncmp(test_name, select_name, len))
Simon Glassbb2b1732021-03-07 17:35:05 -0700221 return true;
222
Andy Shevchenko00d42902021-02-11 16:40:11 +0200223 if (prefix) {
224 /* All tests have this prefix */
225 if (!strncmp(test_name, prefix, strlen(prefix)))
226 test_name += strlen(prefix);
227 } else {
Simon Glass1ef74ab2021-03-07 17:35:12 -0700228 const char *p = strstr(test_name, "_test_");
229
230 /* convert xxx_test_yyy to yyy, i.e. remove the suite name */
231 if (p)
Andy Shevchenko00d42902021-02-11 16:40:11 +0200232 test_name = p + strlen("_test_");
Simon Glass1ef74ab2021-03-07 17:35:12 -0700233 }
Simon Glassbb2b1732021-03-07 17:35:05 -0700234
Andy Shevchenkod91cfbb2021-02-11 16:40:10 +0200235 if (!strncmp(test_name, select_name, len))
Simon Glassbb2b1732021-03-07 17:35:05 -0700236 return true;
237
238 return false;
239}
240
Simon Glass53d1b192021-03-07 17:35:08 -0700241/**
Simon Glass1899e132021-03-07 17:35:07 -0700242 * ut_list_has_dm_tests() - Check if a list of tests has driver model ones
243 *
244 * @tests: List of tests to run
Simon Glass798b5c52024-10-19 09:21:56 -0600245 * @count: Number of tests to run
246 * @prefix: String prefix for the tests. Any tests that have this prefix will be
247 * printed without the prefix, so that it is easier to see the unique part
248 * of the test name. If NULL, no prefix processing is done
249 * @select_name: Name of a single test being run (from the list provided). If
250 * NULL all tests are being run
Simon Glass1a92f832024-08-22 07:57:48 -0600251 * Return: true if any of the tests have the UTF_DM flag
Simon Glass1899e132021-03-07 17:35:07 -0700252 */
Simon Glass798b5c52024-10-19 09:21:56 -0600253static bool ut_list_has_dm_tests(struct unit_test *tests, int count,
254 const char *prefix, const char *select_name)
Simon Glass1899e132021-03-07 17:35:07 -0700255{
256 struct unit_test *test;
257
258 for (test = tests; test < tests + count; test++) {
Simon Glass798b5c52024-10-19 09:21:56 -0600259 if (test_matches(prefix, test->name, select_name) &&
260 (test->flags & UTF_DM))
Simon Glass1899e132021-03-07 17:35:07 -0700261 return true;
262 }
263
264 return false;
265}
266
Simon Glassbb2b1732021-03-07 17:35:05 -0700267/**
Simon Glass53d1b192021-03-07 17:35:08 -0700268 * dm_test_restore() Put things back to normal so sandbox works as expected
269 *
270 * @of_root: Value to set for of_root
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100271 * Return: 0 if OK, -ve on error
Simon Glass53d1b192021-03-07 17:35:08 -0700272 */
273static int dm_test_restore(struct device_node *of_root)
274{
275 int ret;
276
277 gd_set_of_root(of_root);
278 gd->dm_root = NULL;
279 ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE));
280 if (ret)
281 return ret;
282 dm_scan_plat(false);
283 if (!CONFIG_IS_ENABLED(OF_PLATDATA))
AKASHI Takahiro16f51472023-06-08 09:55:59 +0900284 dm_extended_scan(false);
Simon Glass53d1b192021-03-07 17:35:08 -0700285
286 return 0;
287}
288
289/**
Simon Glass436687e2021-03-07 17:35:01 -0700290 * test_pre_run() - Handle any preparation needed to run a test
291 *
292 * @uts: Test state
293 * @test: Test to prepare for
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100294 * Return: 0 if OK, -EAGAIN to skip this test since some required feature is not
Simon Glass436687e2021-03-07 17:35:01 -0700295 * available, other -ve on error (meaning that testing cannot likely
296 * continue)
297 */
298static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
Simon Glassd93dc7d2021-03-07 17:34:48 -0700299{
Simon Glassa128b1b2022-03-04 08:43:01 -0700300 ut_assertok(event_init());
301
Simon Glass1880b8a2024-09-01 16:26:20 -0600302 /*
303 * Remove any USB keyboard, so that we can add and remove USB devices
304 * in tests.
305 *
Simon Glassb0fd7a22024-10-14 14:17:53 -0600306 * For UTF_DM tests, the old driver model state is saved and
Simon Glass1880b8a2024-09-01 16:26:20 -0600307 * restored across each test. Within in each test there is therefore a
308 * new driver model state, which means that any USB keyboard device in
309 * stdio points to the old state.
310 *
Simon Glassb0fd7a22024-10-14 14:17:53 -0600311 * This is fine in most cases. But if a non-UTF_DM test starts up
Simon Glass1880b8a2024-09-01 16:26:20 -0600312 * USB (thus creating a stdio record pointing to the USB keyboard
313 * device) then when the test finishes, the new driver model state is
314 * freed, meaning that there is now a stale pointer in stdio.
315 *
Simon Glassb0fd7a22024-10-14 14:17:53 -0600316 * This means that any future UTF_DM test which uses stdin will
Simon Glass1880b8a2024-09-01 16:26:20 -0600317 * cause the console system to call tstc() on the stale device pointer,
318 * causing a crash.
319 *
Simon Glassb0fd7a22024-10-14 14:17:53 -0600320 * We don't want to fix this by enabling UTF_DM for all tests as
Simon Glass1880b8a2024-09-01 16:26:20 -0600321 * this causes other problems. For example, bootflow_efi relies on
322 * U-Boot going through a proper init - without that we don't have the
323 * TCG measurement working and get an error
324 * 'tcg2 measurement fails(0x8000000000000007)'. Once we tidy up how EFI
325 * runs tests (e.g. get rid of all the restarting of U-Boot) we could
Simon Glassb0fd7a22024-10-14 14:17:53 -0600326 * potentially make the bootstd tests set UTF_DM, but other tests
Simon Glass1880b8a2024-09-01 16:26:20 -0600327 * might do the same thing.
328 *
329 * We could add a test flag to declare that USB is being used, but that
330 * seems unnecessary, at least for now. We could detect USB being used
331 * in a test, but there is no obvious drawback to clearing out stale
332 * pointers always.
333 *
334 * So just remove any USB keyboards from the console tables. This allows
Simon Glassb0fd7a22024-10-14 14:17:53 -0600335 * UTF_DM and non-UTF_DM tests to coexist happily.
Simon Glass1880b8a2024-09-01 16:26:20 -0600336 */
337 usb_kbd_remove_for_test();
338
Simon Glass1a92f832024-08-22 07:57:48 -0600339 if (test->flags & UTF_DM)
Simon Glass2dba4762021-03-07 17:34:58 -0700340 ut_assertok(dm_test_pre_run(uts));
Simon Glassb2890a12021-03-07 17:34:56 -0700341
Simon Glass59cad962021-03-07 17:34:55 -0700342 ut_set_skip_delays(uts, false);
343
Simon Glass86a5bd02021-03-07 17:34:53 -0700344 uts->start = mallinfo();
Simon Glassd93dc7d2021-03-07 17:34:48 -0700345
Simon Glass1a92f832024-08-22 07:57:48 -0600346 if (test->flags & UTF_SCAN_PDATA)
Simon Glass177e0fd2021-03-07 17:34:52 -0700347 ut_assertok(dm_scan_plat(false));
348
Simon Glass1a92f832024-08-22 07:57:48 -0600349 if (test->flags & UTF_PROBE_TEST)
Simon Glass242357c2021-03-07 17:34:51 -0700350 ut_assertok(do_autoprobe(uts));
351
Sean Anderson7bf2f8c2023-10-14 16:47:46 -0400352 if (CONFIG_IS_ENABLED(OF_REAL) &&
Simon Glass1a92f832024-08-22 07:57:48 -0600353 (test->flags & UTF_SCAN_FDT)) {
Simon Glassb490f5f2023-01-17 10:47:28 -0700354 /*
355 * only set this if we know the ethernet uclass will be created
356 */
Simon Glass1a92f832024-08-22 07:57:48 -0600357 eth_set_enable_bootdevs(test->flags & UTF_ETH_BOOTDEV);
358 test_sf_set_enable_bootdevs(test->flags & UTF_SF_BOOTDEV);
Simon Glassd18f7392021-03-07 17:34:50 -0700359 ut_assertok(dm_extended_scan(false));
Simon Glassb490f5f2023-01-17 10:47:28 -0700360 }
Simon Glassd18f7392021-03-07 17:34:50 -0700361
Simon Glassb9ff6482023-01-17 10:47:23 -0700362 /*
363 * Do this after FDT scan since dm_scan_other() in bootstd-uclass.c
364 * checks for the existence of bootstd
365 */
Simon Glass1a92f832024-08-22 07:57:48 -0600366 if (test->flags & UTF_SCAN_PDATA)
Simon Glassb9ff6482023-01-17 10:47:23 -0700367 ut_assertok(dm_scan_other(false));
368
Simon Glass1a92f832024-08-22 07:57:48 -0600369 if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UTF_OTHER_FDT)) {
Simon Glassb9958072022-09-06 20:27:11 -0600370 /* make sure the other FDT is available */
371 ut_assertok(test_load_other_fdt(uts));
372
373 /*
374 * create a new live tree with it for every test, in case a
375 * test modifies the tree
376 */
377 if (of_live_active()) {
378 ut_assertok(unflatten_device_tree(uts->other_fdt,
379 &uts->of_other));
380 }
381 }
382
Simon Glass11fcfa32024-08-22 07:57:50 -0600383 if (test->flags & UTF_CONSOLE) {
Simon Glassd93dc7d2021-03-07 17:34:48 -0700384 int ret = console_record_reset_enable();
385
386 if (ret) {
387 printf("Skipping: Console recording disabled\n");
388 return -EAGAIN;
389 }
390 }
Simon Glassbe277ee2024-10-28 13:47:53 +0100391 if (test->flags & UFT_BLOBLIST) {
392 log_debug("save bloblist %p\n", gd_bloblist());
393 uts->old_bloblist = gd_bloblist();
394 gd_set_bloblist(NULL);
395 }
396
Simon Glass2b566b92021-03-07 17:34:54 -0700397 ut_silence_console(uts);
Simon Glassd93dc7d2021-03-07 17:34:48 -0700398
399 return 0;
400}
401
Simon Glass436687e2021-03-07 17:35:01 -0700402/**
403 * test_post_run() - Handle cleaning up after a test
404 *
405 * @uts: Test state
406 * @test: Test to clean up after
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100407 * Return: 0 if OK, -ve on error (meaning that testing cannot likely continue)
Simon Glass436687e2021-03-07 17:35:01 -0700408 */
409static int test_post_run(struct unit_test_state *uts, struct unit_test *test)
Simon Glassd93dc7d2021-03-07 17:34:48 -0700410{
Simon Glass2b566b92021-03-07 17:34:54 -0700411 ut_unsilence_console(uts);
Simon Glass1a92f832024-08-22 07:57:48 -0600412 if (test->flags & UTF_DM)
Simon Glass5b7e55b2021-03-07 17:34:59 -0700413 ut_assertok(dm_test_post_run(uts));
Rasmus Villemoesc794e492022-10-28 13:50:54 +0200414 ut_assertok(cyclic_unregister_all());
Simon Glassa128b1b2022-03-04 08:43:01 -0700415 ut_assertok(event_uninit());
Simon Glass0f8f6772021-03-07 17:34:49 -0700416
Simon Glassb9958072022-09-06 20:27:11 -0600417 free(uts->of_other);
418 uts->of_other = NULL;
419
Simon Glassbe277ee2024-10-28 13:47:53 +0100420 if (test->flags & UFT_BLOBLIST) {
421 gd_set_bloblist(uts->old_bloblist);
422 log_debug("restore bloblist %p\n", gd_bloblist());
423 }
424
Simon Glass76c62692022-10-29 19:47:08 -0600425 blkcache_free();
426
Simon Glassd93dc7d2021-03-07 17:34:48 -0700427 return 0;
428}
429
Simon Glass0d32ec22021-03-07 17:35:03 -0700430/**
Simon Glass816fe6c2022-10-20 18:22:48 -0600431 * skip_test() - Handle skipping a test
432 *
433 * @uts: Test state to update
434 * @return -EAGAIN (always)
435 */
436static int skip_test(struct unit_test_state *uts)
437{
438 uts->skip_count++;
439
440 return -EAGAIN;
441}
442
443/**
Simon Glass0d32ec22021-03-07 17:35:03 -0700444 * ut_run_test() - Run a single test
445 *
446 * This runs the test, handling any preparation and clean-up needed. It prints
447 * the name of each test before running it.
448 *
449 * @uts: Test state to update. The caller should ensure that this is zeroed for
450 * the first call to this function. On exit, @uts->fail_count is
451 * incremented by the number of failures (0, one hopes)
452 * @test_name: Test to run
453 * @name: Name of test, possibly skipping a prefix that should not be displayed
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100454 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
Simon Glass0d32ec22021-03-07 17:35:03 -0700455 * any failed
456 */
457static int ut_run_test(struct unit_test_state *uts, struct unit_test *test,
458 const char *test_name)
Simon Glass5517edb2021-03-07 17:35:00 -0700459{
Simon Glass436687e2021-03-07 17:35:01 -0700460 const char *fname = strrchr(test->file, '/') + 1;
461 const char *note = "";
Simon Glass5517edb2021-03-07 17:35:00 -0700462 int ret;
463
Simon Glass1a92f832024-08-22 07:57:48 -0600464 if ((test->flags & UTF_DM) && !uts->of_live)
Simon Glass436687e2021-03-07 17:35:01 -0700465 note = " (flat tree)";
466 printf("Test: %s: %s%s\n", test_name, fname, note);
Simon Glass5517edb2021-03-07 17:35:00 -0700467
Simon Glass4066d8d2021-03-07 17:35:04 -0700468 /* Allow access to test state from drivers */
469 test_set_state(uts);
470
Simon Glass5517edb2021-03-07 17:35:00 -0700471 ret = test_pre_run(uts, test);
472 if (ret == -EAGAIN)
Simon Glass816fe6c2022-10-20 18:22:48 -0600473 return skip_test(uts);
Simon Glass5517edb2021-03-07 17:35:00 -0700474 if (ret)
475 return ret;
476
Simon Glass816fe6c2022-10-20 18:22:48 -0600477 ret = test->func(uts);
478 if (ret == -EAGAIN)
479 skip_test(uts);
Simon Glass5517edb2021-03-07 17:35:00 -0700480
481 ret = test_post_run(uts, test);
482 if (ret)
483 return ret;
484
Simon Glass4066d8d2021-03-07 17:35:04 -0700485 test_set_state( NULL);
486
Simon Glass5517edb2021-03-07 17:35:00 -0700487 return 0;
488}
489
Simon Glassbb2b1732021-03-07 17:35:05 -0700490/**
491 * ut_run_test_live_flat() - Run a test with both live and flat tree
492 *
493 * This calls ut_run_test() with livetree enabled, which is the standard setup
494 * for runnig tests. Then, for driver model test, it calls it again with
495 * livetree disabled. This allows checking of flattree being used when OF_LIVE
496 * is enabled, as is the case in U-Boot proper before relocation, as well as in
497 * SPL.
498 *
499 * @uts: Test state to update. The caller should ensure that this is zeroed for
500 * the first call to this function. On exit, @uts->fail_count is
501 * incremented by the number of failures (0, one hopes)
502 * @test: Test to run
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100503 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
Simon Glassbb2b1732021-03-07 17:35:05 -0700504 * any failed
505 */
506static int ut_run_test_live_flat(struct unit_test_state *uts,
Simon Glass0f7eb632022-10-29 19:47:09 -0600507 struct unit_test *test)
Simon Glass0d32ec22021-03-07 17:35:03 -0700508{
Simon Glass94b35832024-10-09 18:28:59 -0600509 int runs, ret;
Simon Glass0d32ec22021-03-07 17:35:03 -0700510
Simon Glass1a92f832024-08-22 07:57:48 -0600511 if ((test->flags & UTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX))
Simon Glass816fe6c2022-10-20 18:22:48 -0600512 return skip_test(uts);
Simon Glassb9958072022-09-06 20:27:11 -0600513
Simon Glass0d32ec22021-03-07 17:35:03 -0700514 /* Run with the live tree if possible */
515 runs = 0;
516 if (CONFIG_IS_ENABLED(OF_LIVE)) {
Simon Glass1a92f832024-08-22 07:57:48 -0600517 if (!(test->flags & UTF_FLAT_TREE)) {
Simon Glass0d32ec22021-03-07 17:35:03 -0700518 uts->of_live = true;
Simon Glass94b35832024-10-09 18:28:59 -0600519 ret = ut_run_test(uts, test, test->name);
520 if (ret != -EAGAIN) {
521 ut_assertok(ret);
522 runs++;
523 }
Simon Glass0d32ec22021-03-07 17:35:03 -0700524 }
525 }
526
527 /*
Simon Glassb9958072022-09-06 20:27:11 -0600528 * Run with the flat tree if:
529 * - it is not marked for live tree only
530 * - it doesn't require the 'other' FDT when OFNODE_MULTI_TREE_MAX is
531 * not enabled (since flat tree can only support a single FDT in that
532 * case
533 * - we couldn't run it with live tree,
534 * - it is a core test (dm tests except video)
535 * - the FDT is still valid and has not been updated by an earlier test
536 * (for sandbox we handle this by copying the tree, but not for other
537 * boards)
Simon Glass0d32ec22021-03-07 17:35:03 -0700538 */
Sean Anderson5765fb12023-09-29 12:06:54 -0400539 if ((!CONFIG_IS_ENABLED(OF_LIVE) ||
Simon Glass1a92f832024-08-22 07:57:48 -0600540 (test->flags & UTF_SCAN_FDT)) &&
541 !(test->flags & UTF_LIVE_TREE) &&
Simon Glassb9958072022-09-06 20:27:11 -0600542 (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) ||
Simon Glass1a92f832024-08-22 07:57:48 -0600543 !(test->flags & UTF_OTHER_FDT)) &&
Simon Glass60f08992022-09-06 20:27:06 -0600544 (!runs || ut_test_run_on_flattree(test)) &&
545 !(gd->flags & GD_FLG_FDT_CHANGED)) {
Simon Glass0d32ec22021-03-07 17:35:03 -0700546 uts->of_live = false;
Simon Glass94b35832024-10-09 18:28:59 -0600547 ret = ut_run_test(uts, test, test->name);
548 if (ret != -EAGAIN) {
549 ut_assertok(ret);
550 runs++;
551 }
Simon Glass0d32ec22021-03-07 17:35:03 -0700552 }
553
554 return 0;
555}
556
Simon Glassbb2b1732021-03-07 17:35:05 -0700557/**
558 * ut_run_tests() - Run a set of tests
559 *
560 * This runs the tests, handling any preparation and clean-up needed. It prints
561 * the name of each test before running it.
562 *
563 * @uts: Test state to update. The caller should ensure that this is zeroed for
564 * the first call to this function. On exit, @uts->fail_count is
565 * incremented by the number of failures (0, one hopes)
566 * @prefix: String prefix for the tests. Any tests that have this prefix will be
567 * printed without the prefix, so that it is easier to see the unique part
568 * of the test name. If NULL, no prefix processing is done
569 * @tests: List of tests to run
570 * @count: Number of tests to run
571 * @select_name: Name of a single test to run (from the list provided). If NULL
572 * then all tests are run
Simon Glass798b5c52024-10-19 09:21:56 -0600573 * @test_insert: String describing a test to run after n other tests run, in the
574 * format n:name where n is the number of tests to run before this one and
575 * name is the name of the test to run
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100576 * Return: 0 if all tests passed, -ENOENT if test @select_name was not found,
Simon Glassbb2b1732021-03-07 17:35:05 -0700577 * -EBADF if any failed
578 */
579static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
580 struct unit_test *tests, int count,
Simon Glass85ba7c32022-10-29 19:47:13 -0600581 const char *select_name, const char *test_insert)
Simon Glass5722fb22021-03-07 17:34:47 -0700582{
Simon Glass85ba7c32022-10-29 19:47:13 -0600583 struct unit_test *test, *one;
Simon Glass5722fb22021-03-07 17:34:47 -0700584 int found = 0;
Simon Glass85ba7c32022-10-29 19:47:13 -0600585 int pos = 0;
586 int upto;
Simon Glass5722fb22021-03-07 17:34:47 -0700587
Simon Glass85ba7c32022-10-29 19:47:13 -0600588 one = NULL;
589 if (test_insert) {
590 char *p;
591
592 pos = dectoul(test_insert, NULL);
593 p = strchr(test_insert, ':');
594 if (p)
595 p++;
596
597 for (test = tests; test < tests + count; test++) {
598 if (!strcmp(p, test->name))
599 one = test;
600 }
601 }
602
603 for (upto = 0, test = tests; test < tests + count; test++, upto++) {
Simon Glass5722fb22021-03-07 17:34:47 -0700604 const char *test_name = test->name;
Simon Glass91a187b2022-08-01 07:58:45 -0600605 int ret, i, old_fail_count;
Simon Glass5722fb22021-03-07 17:34:47 -0700606
Simon Glassbb2b1732021-03-07 17:35:05 -0700607 if (!test_matches(prefix, test_name, select_name))
Simon Glass5722fb22021-03-07 17:34:47 -0700608 continue;
Simon Glass1f1614b2022-10-20 18:22:50 -0600609
Simon Glass1a92f832024-08-22 07:57:48 -0600610 if (test->flags & UTF_MANUAL) {
Simon Glass1f1614b2022-10-20 18:22:50 -0600611 int len;
612
613 /*
614 * manual tests must have a name ending "_norun" as this
615 * is how pytest knows to skip them. See
616 * generate_ut_subtest() for this check.
617 */
618 len = strlen(test_name);
619 if (len < 6 || strcmp(test_name + len - 6, "_norun")) {
Simon Glass4c4bf3e2024-11-02 13:37:05 -0600620 printf("Test '%s' is manual so must have a name ending in _norun\n",
Simon Glass1f1614b2022-10-20 18:22:50 -0600621 test_name);
622 uts->fail_count++;
623 return -EBADF;
624 }
625 if (!uts->force_run) {
626 if (select_name) {
Simon Glass4c4bf3e2024-11-02 13:37:05 -0600627 printf("Test '%s' skipped as it is manual (use -f to run it)\n",
Simon Glass1f1614b2022-10-20 18:22:50 -0600628 test_name);
629 }
630 continue;
631 }
632 }
Simon Glass91a187b2022-08-01 07:58:45 -0600633 old_fail_count = uts->fail_count;
Simon Glass85ba7c32022-10-29 19:47:13 -0600634
635 if (one && upto == pos) {
636 ret = ut_run_test_live_flat(uts, one);
637 if (uts->fail_count != old_fail_count) {
Simon Glass4c4bf3e2024-11-02 13:37:05 -0600638 printf("Test '%s' failed %d times (position %d)\n",
Simon Glass85ba7c32022-10-29 19:47:13 -0600639 one->name,
640 uts->fail_count - old_fail_count, pos);
641 }
642 return -EBADF;
643 }
644
Simon Glass91a187b2022-08-01 07:58:45 -0600645 for (i = 0; i < uts->runs_per_test; i++)
Simon Glass0f7eb632022-10-29 19:47:09 -0600646 ret = ut_run_test_live_flat(uts, test);
Simon Glass91a187b2022-08-01 07:58:45 -0600647 if (uts->fail_count != old_fail_count) {
Simon Glass4c4bf3e2024-11-02 13:37:05 -0600648 printf("Test '%s' failed %d times\n", test_name,
Simon Glass91a187b2022-08-01 07:58:45 -0600649 uts->fail_count - old_fail_count);
650 }
Simon Glass5722fb22021-03-07 17:34:47 -0700651 found++;
Simon Glassd93dc7d2021-03-07 17:34:48 -0700652 if (ret == -EAGAIN)
653 continue;
654 if (ret)
655 return ret;
Simon Glass5722fb22021-03-07 17:34:47 -0700656 }
657 if (select_name && !found)
658 return -ENOENT;
659
660 return uts->fail_count ? -EBADF : 0;
661}
662
663int ut_run_list(const char *category, const char *prefix,
Simon Glass91a187b2022-08-01 07:58:45 -0600664 struct unit_test *tests, int count, const char *select_name,
Simon Glass85ba7c32022-10-29 19:47:13 -0600665 int runs_per_test, bool force_run, const char *test_insert)
Simon Glass5722fb22021-03-07 17:34:47 -0700666{
667 struct unit_test_state uts = { .fail_count = 0 };
Simon Glass53d1b192021-03-07 17:35:08 -0700668 bool has_dm_tests = false;
Simon Glass5722fb22021-03-07 17:34:47 -0700669 int ret;
670
Simon Glass1899e132021-03-07 17:35:07 -0700671 if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
Simon Glass798b5c52024-10-19 09:21:56 -0600672 ut_list_has_dm_tests(tests, count, prefix, select_name)) {
Simon Glass53d1b192021-03-07 17:35:08 -0700673 has_dm_tests = true;
Simon Glass1899e132021-03-07 17:35:07 -0700674 /*
675 * If we have no device tree, or it only has a root node, then
676 * these * tests clearly aren't going to work...
677 */
678 if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
679 puts("Please run with test device tree:\n"
680 " ./u-boot -d arch/sandbox/dts/test.dtb\n");
681 return CMD_RET_FAILURE;
682 }
683 }
684
Simon Glass5722fb22021-03-07 17:34:47 -0700685 if (!select_name)
686 printf("Running %d %s tests\n", count, category);
687
Simon Glassbb2b1732021-03-07 17:35:05 -0700688 uts.of_root = gd_of_root();
Simon Glass91a187b2022-08-01 07:58:45 -0600689 uts.runs_per_test = runs_per_test;
Simon Glass3ba76752022-09-06 20:27:05 -0600690 if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) {
691 uts.fdt_size = fdt_totalsize(gd->fdt_blob);
692 uts.fdt_copy = os_malloc(uts.fdt_size);
693 if (!uts.fdt_copy) {
694 printf("Out of memory for device tree copy\n");
695 return -ENOMEM;
696 }
697 memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size);
698 }
Simon Glass1f1614b2022-10-20 18:22:50 -0600699 uts.force_run = force_run;
Simon Glass85ba7c32022-10-29 19:47:13 -0600700 ret = ut_run_tests(&uts, prefix, tests, count, select_name,
701 test_insert);
Simon Glass5722fb22021-03-07 17:34:47 -0700702
Simon Glass3ba76752022-09-06 20:27:05 -0600703 /* Best efforts only...ignore errors */
704 if (has_dm_tests)
705 dm_test_restore(uts.of_root);
Simon Glassb9958072022-09-06 20:27:11 -0600706 if (IS_ENABLED(CONFIG_SANDBOX)) {
Simon Glass3ba76752022-09-06 20:27:05 -0600707 os_free(uts.fdt_copy);
Simon Glassb9958072022-09-06 20:27:11 -0600708 os_free(uts.other_fdt);
709 }
Simon Glass3ba76752022-09-06 20:27:05 -0600710
Simon Glass816fe6c2022-10-20 18:22:48 -0600711 if (uts.skip_count)
712 printf("Skipped: %d, ", uts.skip_count);
Simon Glass5722fb22021-03-07 17:34:47 -0700713 if (ret == -ENOENT)
714 printf("Test '%s' not found\n", select_name);
715 else
716 printf("Failures: %d\n", uts.fail_count);
717
Simon Glass5722fb22021-03-07 17:34:47 -0700718 return ret;
719}