]>
Commit | Line | Data |
---|---|---|
1c721751 SG |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright 2021 Google LLC | |
4 | * Written by Simon Glass <sjg@chromium.org> | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
5ea894ac | 8 | #include <blk.h> |
1c721751 | 9 | #include <console.h> |
af042c21 | 10 | #include <cyclic.h> |
d8ed234b | 11 | #include <dm.h> |
7d02645f | 12 | #include <event.h> |
70dd8865 | 13 | #include <net.h> |
8d468a18 | 14 | #include <of_live.h> |
0e4b697f | 15 | #include <os.h> |
ee88ba71 | 16 | #include <dm/ofnode.h> |
d8ed234b | 17 | #include <dm/root.h> |
c79705ea | 18 | #include <dm/test.h> |
e77615d3 | 19 | #include <dm/uclass-internal.h> |
1c721751 | 20 | #include <test/test.h> |
d8ed234b | 21 | #include <test/ut.h> |
0e4b697f | 22 | #include <u-boot/crc.h> |
1c721751 | 23 | |
30a0d206 SG |
24 | DECLARE_GLOBAL_DATA_PTR; |
25 | ||
0e4b697f SG |
26 | /** |
27 | * enum fdtchk_t - what to do with the device tree (gd->fdt_blob) | |
28 | * | |
29 | * This affects what happens with the device tree before and after a test | |
30 | * | |
31 | * @FDTCHK_NONE: Do nothing | |
32 | * @FDTCHK_CHECKSUM: Take a checksum of the FDT before the test runs and | |
33 | * compare it afterwards to detect any changes | |
34 | * @FDTCHK_COPY: Make a copy of the FDT and restore it afterwards | |
35 | */ | |
36 | enum fdtchk_t { | |
37 | FDTCHK_NONE, | |
38 | FDTCHK_CHECKSUM, | |
39 | FDTCHK_COPY, | |
40 | }; | |
41 | ||
42 | /** | |
43 | * fdt_action() - get the required action for the FDT | |
44 | * | |
45 | * @return the action that should be taken for this build | |
46 | */ | |
47 | static enum fdtchk_t fdt_action(void) | |
48 | { | |
0e4b697f | 49 | /* For sandbox SPL builds, do nothing */ |
d5774594 | 50 | if (IS_ENABLED(CONFIG_SANDBOX) && IS_ENABLED(CONFIG_SPL_BUILD)) |
0e4b697f SG |
51 | return FDTCHK_NONE; |
52 | ||
d5774594 SG |
53 | /* Do a copy for sandbox (but only the U-Boot build, not SPL) */ |
54 | if (IS_ENABLED(CONFIG_SANDBOX)) | |
55 | return FDTCHK_COPY; | |
56 | ||
0e4b697f SG |
57 | /* For all other boards, do a checksum */ |
58 | return FDTCHK_CHECKSUM; | |
59 | } | |
60 | ||
fe806861 SG |
61 | /* This is valid when a test is running, NULL otherwise */ |
62 | static struct unit_test_state *cur_test_state; | |
63 | ||
64 | struct unit_test_state *test_get_state(void) | |
65 | { | |
66 | return cur_test_state; | |
67 | } | |
68 | ||
69 | void test_set_state(struct unit_test_state *uts) | |
70 | { | |
71 | cur_test_state = uts; | |
72 | } | |
73 | ||
c79705ea SG |
74 | /** |
75 | * dm_test_pre_run() - Get ready to run a driver model test | |
76 | * | |
77 | * This clears out the driver model data structures. For sandbox it resets the | |
78 | * state structure | |
79 | * | |
80 | * @uts: Test state | |
81 | */ | |
82 | static int dm_test_pre_run(struct unit_test_state *uts) | |
83 | { | |
84 | bool of_live = uts->of_live; | |
85 | ||
eb6e903a SG |
86 | if (of_live && (gd->flags & GD_FLG_FDT_CHANGED)) { |
87 | printf("Cannot run live tree test as device tree changed\n"); | |
88 | return -EFAULT; | |
89 | } | |
c79705ea SG |
90 | uts->root = NULL; |
91 | uts->testdev = NULL; | |
92 | uts->force_fail_alloc = false; | |
93 | uts->skip_post_probe = false; | |
0e4b697f SG |
94 | if (fdt_action() == FDTCHK_CHECKSUM) |
95 | uts->fdt_chksum = crc8(0, gd->fdt_blob, | |
96 | fdt_totalsize(gd->fdt_blob)); | |
c79705ea | 97 | gd->dm_root = NULL; |
62d63838 | 98 | malloc_disable_testing(); |
719d2864 | 99 | if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) |
c79705ea | 100 | memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); |
d4a1592a | 101 | arch_reset_for_test(); |
c79705ea SG |
102 | |
103 | /* Determine whether to make the live tree available */ | |
104 | gd_set_of_root(of_live ? uts->of_root : NULL); | |
ee88ba71 | 105 | oftree_reset(); |
c79705ea SG |
106 | ut_assertok(dm_init(of_live)); |
107 | uts->root = dm_root(); | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
e77615d3 SG |
112 | static int dm_test_post_run(struct unit_test_state *uts) |
113 | { | |
114 | int id; | |
115 | ||
0e4b697f SG |
116 | if (gd->fdt_blob) { |
117 | switch (fdt_action()) { | |
118 | case FDTCHK_COPY: | |
119 | memcpy((void *)gd->fdt_blob, uts->fdt_copy, uts->fdt_size); | |
120 | break; | |
121 | case FDTCHK_CHECKSUM: { | |
122 | uint chksum; | |
123 | ||
124 | chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); | |
eb6e903a SG |
125 | if (chksum != uts->fdt_chksum) { |
126 | /* | |
127 | * We cannot run any more tests that need the | |
128 | * live tree, since its strings point into the | |
129 | * flat tree, which has changed. This likely | |
130 | * means that at least some of the pointers from | |
131 | * the live tree point to different things | |
132 | */ | |
0e4b697f | 133 | printf("Device tree changed: cannot run live tree tests\n"); |
eb6e903a SG |
134 | gd->flags |= GD_FLG_FDT_CHANGED; |
135 | } | |
0e4b697f SG |
136 | break; |
137 | } | |
138 | case FDTCHK_NONE: | |
139 | break; | |
140 | } | |
141 | } | |
142 | ||
e8c023c3 SG |
143 | /* |
144 | * With of-platdata-inst the uclasses are created at build time. If we | |
145 | * destroy them we cannot get them back since uclass_add() is not | |
146 | * supported. So skip this. | |
147 | */ | |
148 | if (!CONFIG_IS_ENABLED(OF_PLATDATA_INST)) { | |
149 | for (id = 0; id < UCLASS_COUNT; id++) { | |
150 | struct uclass *uc; | |
e77615d3 | 151 | |
e8c023c3 SG |
152 | /* |
153 | * If the uclass doesn't exist we don't want to create | |
154 | * it. So check that here before we call | |
155 | * uclass_find_device(). | |
156 | */ | |
157 | uc = uclass_find(id); | |
158 | if (!uc) | |
159 | continue; | |
160 | ut_assertok(uclass_destroy(uc)); | |
161 | } | |
e77615d3 SG |
162 | } |
163 | ||
164 | return 0; | |
165 | } | |
166 | ||
4b8b27e3 SG |
167 | /* Ensure all the test devices are probed */ |
168 | static int do_autoprobe(struct unit_test_state *uts) | |
169 | { | |
c0648b7b | 170 | return uclass_probe_all(UCLASS_TEST); |
4b8b27e3 SG |
171 | } |
172 | ||
d2281bb0 SG |
173 | /* |
174 | * ut_test_run_on_flattree() - Check if we should run a test with flat DT | |
175 | * | |
176 | * This skips long/slow tests where there is not much value in running a flat | |
177 | * DT test in addition to a live DT test. | |
178 | * | |
185f812c | 179 | * Return: true to run the given test on the flat device tree |
d2281bb0 SG |
180 | */ |
181 | static bool ut_test_run_on_flattree(struct unit_test *test) | |
182 | { | |
183 | const char *fname = strrchr(test->file, '/') + 1; | |
184 | ||
185 | if (!(test->flags & UT_TESTF_DM)) | |
186 | return false; | |
187 | ||
188 | return !strstr(fname, "video") || strstr(test->name, "video_base"); | |
189 | } | |
190 | ||
f97f85e6 SG |
191 | /** |
192 | * test_matches() - Check if a test should be run | |
193 | * | |
194 | * This checks if the a test should be run. In the normal case of running all | |
195 | * tests, @select_name is NULL. | |
196 | * | |
197 | * @prefix: String prefix for the tests. Any tests that have this prefix will be | |
198 | * printed without the prefix, so that it is easier to see the unique part | |
8482356f SG |
199 | * of the test name. If NULL, any suite name (xxx_test) is considered to be |
200 | * a prefix. | |
f97f85e6 SG |
201 | * @test_name: Name of current test |
202 | * @select_name: Name of test to run (or NULL for all) | |
185f812c | 203 | * Return: true to run this test, false to skip it |
f97f85e6 SG |
204 | */ |
205 | static bool test_matches(const char *prefix, const char *test_name, | |
206 | const char *select_name) | |
207 | { | |
ff232a72 AS |
208 | size_t len; |
209 | ||
f97f85e6 SG |
210 | if (!select_name) |
211 | return true; | |
212 | ||
ff232a72 AS |
213 | /* Allow glob expansion in the test name */ |
214 | len = select_name[strlen(select_name) - 1] == '*' ? strlen(select_name) : 0; | |
215 | if (len-- == 1) | |
216 | return true; | |
217 | ||
218 | if (!strncmp(test_name, select_name, len)) | |
f97f85e6 SG |
219 | return true; |
220 | ||
494a5e12 AS |
221 | if (prefix) { |
222 | /* All tests have this prefix */ | |
223 | if (!strncmp(test_name, prefix, strlen(prefix))) | |
224 | test_name += strlen(prefix); | |
225 | } else { | |
8482356f SG |
226 | const char *p = strstr(test_name, "_test_"); |
227 | ||
228 | /* convert xxx_test_yyy to yyy, i.e. remove the suite name */ | |
229 | if (p) | |
494a5e12 | 230 | test_name = p + strlen("_test_"); |
8482356f | 231 | } |
f97f85e6 | 232 | |
ff232a72 | 233 | if (!strncmp(test_name, select_name, len)) |
f97f85e6 SG |
234 | return true; |
235 | ||
236 | return false; | |
237 | } | |
238 | ||
664277f1 | 239 | /** |
1fc9c122 SG |
240 | * ut_list_has_dm_tests() - Check if a list of tests has driver model ones |
241 | * | |
242 | * @tests: List of tests to run | |
243 | * @count: Number of tests to ru | |
185f812c | 244 | * Return: true if any of the tests have the UT_TESTF_DM flag |
1fc9c122 SG |
245 | */ |
246 | static bool ut_list_has_dm_tests(struct unit_test *tests, int count) | |
247 | { | |
248 | struct unit_test *test; | |
249 | ||
250 | for (test = tests; test < tests + count; test++) { | |
251 | if (test->flags & UT_TESTF_DM) | |
252 | return true; | |
253 | } | |
254 | ||
255 | return false; | |
256 | } | |
257 | ||
664277f1 SG |
258 | /** |
259 | * dm_test_restore() Put things back to normal so sandbox works as expected | |
260 | * | |
261 | * @of_root: Value to set for of_root | |
185f812c | 262 | * Return: 0 if OK, -ve on error |
664277f1 SG |
263 | */ |
264 | static int dm_test_restore(struct device_node *of_root) | |
265 | { | |
266 | int ret; | |
267 | ||
268 | gd_set_of_root(of_root); | |
269 | gd->dm_root = NULL; | |
270 | ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE)); | |
271 | if (ret) | |
272 | return ret; | |
273 | dm_scan_plat(false); | |
274 | if (!CONFIG_IS_ENABLED(OF_PLATDATA)) | |
230038f8 | 275 | dm_extended_scan(false); |
664277f1 SG |
276 | |
277 | return 0; | |
278 | } | |
279 | ||
ca44ca05 SG |
280 | /** |
281 | * test_pre_run() - Handle any preparation needed to run a test | |
282 | * | |
283 | * @uts: Test state | |
284 | * @test: Test to prepare for | |
185f812c | 285 | * Return: 0 if OK, -EAGAIN to skip this test since some required feature is not |
ca44ca05 SG |
286 | * available, other -ve on error (meaning that testing cannot likely |
287 | * continue) | |
288 | */ | |
289 | static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) | |
d002a276 | 290 | { |
7d02645f SG |
291 | ut_assertok(event_init()); |
292 | ||
72b524cf | 293 | if (test->flags & UT_TESTF_DM) |
c79705ea | 294 | ut_assertok(dm_test_pre_run(uts)); |
72b524cf | 295 | |
47ec3ede SG |
296 | ut_set_skip_delays(uts, false); |
297 | ||
19fb3dba | 298 | uts->start = mallinfo(); |
d002a276 | 299 | |
ecb274cf | 300 | if (test->flags & UT_TESTF_SCAN_PDATA) |
5a986f3f SG |
301 | ut_assertok(dm_scan_plat(false)); |
302 | ||
4b8b27e3 SG |
303 | if (test->flags & UT_TESTF_PROBE_TEST) |
304 | ut_assertok(do_autoprobe(uts)); | |
305 | ||
eaf73855 | 306 | if (CONFIG_IS_ENABLED(OF_REAL) && |
70dd8865 SG |
307 | (test->flags & UT_TESTF_SCAN_FDT)) { |
308 | /* | |
309 | * only set this if we know the ethernet uclass will be created | |
310 | */ | |
311 | eth_set_enable_bootdevs(test->flags & UT_TESTF_ETH_BOOTDEV); | |
081bdc52 | 312 | test_sf_set_enable_bootdevs(test->flags & UT_TESTF_SF_BOOTDEV); |
d8ed234b | 313 | ut_assertok(dm_extended_scan(false)); |
70dd8865 | 314 | } |
d8ed234b | 315 | |
ecb274cf SG |
316 | /* |
317 | * Do this after FDT scan since dm_scan_other() in bootstd-uclass.c | |
318 | * checks for the existence of bootstd | |
319 | */ | |
320 | if (test->flags & UT_TESTF_SCAN_PDATA) | |
321 | ut_assertok(dm_scan_other(false)); | |
322 | ||
8d468a18 SG |
323 | if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UT_TESTF_OTHER_FDT)) { |
324 | /* make sure the other FDT is available */ | |
325 | ut_assertok(test_load_other_fdt(uts)); | |
326 | ||
327 | /* | |
328 | * create a new live tree with it for every test, in case a | |
329 | * test modifies the tree | |
330 | */ | |
331 | if (of_live_active()) { | |
332 | ut_assertok(unflatten_device_tree(uts->other_fdt, | |
333 | &uts->of_other)); | |
334 | } | |
335 | } | |
336 | ||
d002a276 SG |
337 | if (test->flags & UT_TESTF_CONSOLE_REC) { |
338 | int ret = console_record_reset_enable(); | |
339 | ||
340 | if (ret) { | |
341 | printf("Skipping: Console recording disabled\n"); | |
342 | return -EAGAIN; | |
343 | } | |
344 | } | |
74524712 | 345 | ut_silence_console(uts); |
d002a276 SG |
346 | |
347 | return 0; | |
348 | } | |
349 | ||
ca44ca05 SG |
350 | /** |
351 | * test_post_run() - Handle cleaning up after a test | |
352 | * | |
353 | * @uts: Test state | |
354 | * @test: Test to clean up after | |
185f812c | 355 | * Return: 0 if OK, -ve on error (meaning that testing cannot likely continue) |
ca44ca05 SG |
356 | */ |
357 | static int test_post_run(struct unit_test_state *uts, struct unit_test *test) | |
d002a276 | 358 | { |
74524712 | 359 | ut_unsilence_console(uts); |
e77615d3 SG |
360 | if (test->flags & UT_TESTF_DM) |
361 | ut_assertok(dm_test_post_run(uts)); | |
50128aeb | 362 | ut_assertok(cyclic_unregister_all()); |
7d02645f | 363 | ut_assertok(event_uninit()); |
30a0d206 | 364 | |
8d468a18 SG |
365 | free(uts->of_other); |
366 | uts->of_other = NULL; | |
367 | ||
5ea894ac SG |
368 | blkcache_free(); |
369 | ||
d002a276 SG |
370 | return 0; |
371 | } | |
372 | ||
1facaade SG |
373 | /** |
374 | * skip_test() - Handle skipping a test | |
375 | * | |
376 | * @uts: Test state to update | |
377 | * @return -EAGAIN (always) | |
378 | */ | |
379 | static int skip_test(struct unit_test_state *uts) | |
380 | { | |
381 | uts->skip_count++; | |
382 | ||
383 | return -EAGAIN; | |
384 | } | |
385 | ||
d2281bb0 SG |
386 | /** |
387 | * ut_run_test() - Run a single test | |
388 | * | |
389 | * This runs the test, handling any preparation and clean-up needed. It prints | |
390 | * the name of each test before running it. | |
391 | * | |
392 | * @uts: Test state to update. The caller should ensure that this is zeroed for | |
393 | * the first call to this function. On exit, @uts->fail_count is | |
394 | * incremented by the number of failures (0, one hopes) | |
395 | * @test_name: Test to run | |
396 | * @name: Name of test, possibly skipping a prefix that should not be displayed | |
185f812c | 397 | * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if |
d2281bb0 SG |
398 | * any failed |
399 | */ | |
400 | static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, | |
401 | const char *test_name) | |
99a88fe1 | 402 | { |
ca44ca05 SG |
403 | const char *fname = strrchr(test->file, '/') + 1; |
404 | const char *note = ""; | |
99a88fe1 SG |
405 | int ret; |
406 | ||
ca44ca05 SG |
407 | if ((test->flags & UT_TESTF_DM) && !uts->of_live) |
408 | note = " (flat tree)"; | |
409 | printf("Test: %s: %s%s\n", test_name, fname, note); | |
99a88fe1 | 410 | |
fe806861 SG |
411 | /* Allow access to test state from drivers */ |
412 | test_set_state(uts); | |
413 | ||
99a88fe1 SG |
414 | ret = test_pre_run(uts, test); |
415 | if (ret == -EAGAIN) | |
1facaade | 416 | return skip_test(uts); |
99a88fe1 SG |
417 | if (ret) |
418 | return ret; | |
419 | ||
1facaade SG |
420 | ret = test->func(uts); |
421 | if (ret == -EAGAIN) | |
422 | skip_test(uts); | |
99a88fe1 SG |
423 | |
424 | ret = test_post_run(uts, test); | |
425 | if (ret) | |
426 | return ret; | |
427 | ||
fe806861 SG |
428 | test_set_state( NULL); |
429 | ||
99a88fe1 SG |
430 | return 0; |
431 | } | |
432 | ||
f97f85e6 SG |
433 | /** |
434 | * ut_run_test_live_flat() - Run a test with both live and flat tree | |
435 | * | |
436 | * This calls ut_run_test() with livetree enabled, which is the standard setup | |
437 | * for runnig tests. Then, for driver model test, it calls it again with | |
438 | * livetree disabled. This allows checking of flattree being used when OF_LIVE | |
439 | * is enabled, as is the case in U-Boot proper before relocation, as well as in | |
440 | * SPL. | |
441 | * | |
442 | * @uts: Test state to update. The caller should ensure that this is zeroed for | |
443 | * the first call to this function. On exit, @uts->fail_count is | |
444 | * incremented by the number of failures (0, one hopes) | |
445 | * @test: Test to run | |
185f812c | 446 | * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if |
f97f85e6 SG |
447 | * any failed |
448 | */ | |
449 | static int ut_run_test_live_flat(struct unit_test_state *uts, | |
f7a68d22 | 450 | struct unit_test *test) |
d2281bb0 SG |
451 | { |
452 | int runs; | |
453 | ||
8d468a18 | 454 | if ((test->flags & UT_TESTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX)) |
1facaade | 455 | return skip_test(uts); |
8d468a18 | 456 | |
d2281bb0 SG |
457 | /* Run with the live tree if possible */ |
458 | runs = 0; | |
459 | if (CONFIG_IS_ENABLED(OF_LIVE)) { | |
7c14dc7f | 460 | if (!(test->flags & UT_TESTF_FLAT_TREE)) { |
d2281bb0 SG |
461 | uts->of_live = true; |
462 | ut_assertok(ut_run_test(uts, test, test->name)); | |
463 | runs++; | |
464 | } | |
465 | } | |
466 | ||
467 | /* | |
8d468a18 SG |
468 | * Run with the flat tree if: |
469 | * - it is not marked for live tree only | |
470 | * - it doesn't require the 'other' FDT when OFNODE_MULTI_TREE_MAX is | |
471 | * not enabled (since flat tree can only support a single FDT in that | |
472 | * case | |
473 | * - we couldn't run it with live tree, | |
474 | * - it is a core test (dm tests except video) | |
475 | * - the FDT is still valid and has not been updated by an earlier test | |
476 | * (for sandbox we handle this by copying the tree, but not for other | |
477 | * boards) | |
d2281bb0 | 478 | */ |
3f876cb7 SA |
479 | if ((!CONFIG_IS_ENABLED(OF_LIVE) || |
480 | (test->flags & UT_TESTF_SCAN_FDT)) && | |
6ec5178c | 481 | !(test->flags & UT_TESTF_LIVE_TREE) && |
8d468a18 SG |
482 | (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || |
483 | !(test->flags & UT_TESTF_OTHER_FDT)) && | |
eb6e903a SG |
484 | (!runs || ut_test_run_on_flattree(test)) && |
485 | !(gd->flags & GD_FLG_FDT_CHANGED)) { | |
d2281bb0 SG |
486 | uts->of_live = false; |
487 | ut_assertok(ut_run_test(uts, test, test->name)); | |
488 | runs++; | |
489 | } | |
490 | ||
491 | return 0; | |
492 | } | |
493 | ||
f97f85e6 SG |
494 | /** |
495 | * ut_run_tests() - Run a set of tests | |
496 | * | |
497 | * This runs the tests, handling any preparation and clean-up needed. It prints | |
498 | * the name of each test before running it. | |
499 | * | |
500 | * @uts: Test state to update. The caller should ensure that this is zeroed for | |
501 | * the first call to this function. On exit, @uts->fail_count is | |
502 | * incremented by the number of failures (0, one hopes) | |
503 | * @prefix: String prefix for the tests. Any tests that have this prefix will be | |
504 | * printed without the prefix, so that it is easier to see the unique part | |
505 | * of the test name. If NULL, no prefix processing is done | |
506 | * @tests: List of tests to run | |
507 | * @count: Number of tests to run | |
508 | * @select_name: Name of a single test to run (from the list provided). If NULL | |
509 | * then all tests are run | |
185f812c | 510 | * Return: 0 if all tests passed, -ENOENT if test @select_name was not found, |
f97f85e6 SG |
511 | * -EBADF if any failed |
512 | */ | |
513 | static int ut_run_tests(struct unit_test_state *uts, const char *prefix, | |
514 | struct unit_test *tests, int count, | |
d1b46595 | 515 | const char *select_name, const char *test_insert) |
1c721751 | 516 | { |
d1b46595 | 517 | struct unit_test *test, *one; |
1c721751 | 518 | int found = 0; |
d1b46595 SG |
519 | int pos = 0; |
520 | int upto; | |
1c721751 | 521 | |
d1b46595 SG |
522 | one = NULL; |
523 | if (test_insert) { | |
524 | char *p; | |
525 | ||
526 | pos = dectoul(test_insert, NULL); | |
527 | p = strchr(test_insert, ':'); | |
528 | if (p) | |
529 | p++; | |
530 | ||
531 | for (test = tests; test < tests + count; test++) { | |
532 | if (!strcmp(p, test->name)) | |
533 | one = test; | |
534 | } | |
535 | } | |
536 | ||
537 | for (upto = 0, test = tests; test < tests + count; test++, upto++) { | |
1c721751 | 538 | const char *test_name = test->name; |
ea94d053 | 539 | int ret, i, old_fail_count; |
1c721751 | 540 | |
f97f85e6 | 541 | if (!test_matches(prefix, test_name, select_name)) |
1c721751 | 542 | continue; |
cbd71fad SG |
543 | |
544 | if (test->flags & UT_TESTF_MANUAL) { | |
545 | int len; | |
546 | ||
547 | /* | |
548 | * manual tests must have a name ending "_norun" as this | |
549 | * is how pytest knows to skip them. See | |
550 | * generate_ut_subtest() for this check. | |
551 | */ | |
552 | len = strlen(test_name); | |
553 | if (len < 6 || strcmp(test_name + len - 6, "_norun")) { | |
554 | printf("Test %s is manual so must have a name ending in _norun\n", | |
555 | test_name); | |
556 | uts->fail_count++; | |
557 | return -EBADF; | |
558 | } | |
559 | if (!uts->force_run) { | |
560 | if (select_name) { | |
561 | printf("Test %s skipped as it is manual (use -f to run it)\n", | |
562 | test_name); | |
563 | } | |
564 | continue; | |
565 | } | |
566 | } | |
ea94d053 | 567 | old_fail_count = uts->fail_count; |
d1b46595 SG |
568 | |
569 | if (one && upto == pos) { | |
570 | ret = ut_run_test_live_flat(uts, one); | |
571 | if (uts->fail_count != old_fail_count) { | |
572 | printf("Test %s failed %d times (position %d)\n", | |
573 | one->name, | |
574 | uts->fail_count - old_fail_count, pos); | |
575 | } | |
576 | return -EBADF; | |
577 | } | |
578 | ||
ea94d053 | 579 | for (i = 0; i < uts->runs_per_test; i++) |
f7a68d22 | 580 | ret = ut_run_test_live_flat(uts, test); |
ea94d053 SG |
581 | if (uts->fail_count != old_fail_count) { |
582 | printf("Test %s failed %d times\n", select_name, | |
583 | uts->fail_count - old_fail_count); | |
584 | } | |
1c721751 | 585 | found++; |
d002a276 SG |
586 | if (ret == -EAGAIN) |
587 | continue; | |
588 | if (ret) | |
589 | return ret; | |
1c721751 SG |
590 | } |
591 | if (select_name && !found) | |
592 | return -ENOENT; | |
593 | ||
594 | return uts->fail_count ? -EBADF : 0; | |
595 | } | |
596 | ||
597 | int ut_run_list(const char *category, const char *prefix, | |
ea94d053 | 598 | struct unit_test *tests, int count, const char *select_name, |
d1b46595 | 599 | int runs_per_test, bool force_run, const char *test_insert) |
1c721751 SG |
600 | { |
601 | struct unit_test_state uts = { .fail_count = 0 }; | |
664277f1 | 602 | bool has_dm_tests = false; |
1c721751 SG |
603 | int ret; |
604 | ||
1fc9c122 SG |
605 | if (!CONFIG_IS_ENABLED(OF_PLATDATA) && |
606 | ut_list_has_dm_tests(tests, count)) { | |
664277f1 | 607 | has_dm_tests = true; |
1fc9c122 SG |
608 | /* |
609 | * If we have no device tree, or it only has a root node, then | |
610 | * these * tests clearly aren't going to work... | |
611 | */ | |
612 | if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { | |
613 | puts("Please run with test device tree:\n" | |
614 | " ./u-boot -d arch/sandbox/dts/test.dtb\n"); | |
615 | return CMD_RET_FAILURE; | |
616 | } | |
617 | } | |
618 | ||
1c721751 SG |
619 | if (!select_name) |
620 | printf("Running %d %s tests\n", count, category); | |
621 | ||
f97f85e6 | 622 | uts.of_root = gd_of_root(); |
ea94d053 | 623 | uts.runs_per_test = runs_per_test; |
0e4b697f SG |
624 | if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) { |
625 | uts.fdt_size = fdt_totalsize(gd->fdt_blob); | |
626 | uts.fdt_copy = os_malloc(uts.fdt_size); | |
627 | if (!uts.fdt_copy) { | |
628 | printf("Out of memory for device tree copy\n"); | |
629 | return -ENOMEM; | |
630 | } | |
631 | memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size); | |
632 | } | |
cbd71fad | 633 | uts.force_run = force_run; |
d1b46595 SG |
634 | ret = ut_run_tests(&uts, prefix, tests, count, select_name, |
635 | test_insert); | |
1c721751 | 636 | |
0e4b697f SG |
637 | /* Best efforts only...ignore errors */ |
638 | if (has_dm_tests) | |
639 | dm_test_restore(uts.of_root); | |
8d468a18 | 640 | if (IS_ENABLED(CONFIG_SANDBOX)) { |
0e4b697f | 641 | os_free(uts.fdt_copy); |
8d468a18 SG |
642 | os_free(uts.other_fdt); |
643 | } | |
0e4b697f | 644 | |
1facaade SG |
645 | if (uts.skip_count) |
646 | printf("Skipped: %d, ", uts.skip_count); | |
1c721751 SG |
647 | if (ret == -ENOENT) |
648 | printf("Test '%s' not found\n", select_name); | |
649 | else | |
650 | printf("Failures: %d\n", uts.fail_count); | |
651 | ||
652 | return ret; | |
653 | } |