blob: 4f1c54b0f9ba211abc2403f22be6a367f52034e9 [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
7#include <common.h>
8#include <console.h>
Simon Glassd18f7392021-03-07 17:34:50 -07009#include <dm.h>
Simon Glassa128b1b2022-03-04 08:43:01 -070010#include <event.h>
Simon Glassd18f7392021-03-07 17:34:50 -070011#include <dm/root.h>
Simon Glass2dba4762021-03-07 17:34:58 -070012#include <dm/test.h>
Simon Glass5b7e55b2021-03-07 17:34:59 -070013#include <dm/uclass-internal.h>
Simon Glass5722fb22021-03-07 17:34:47 -070014#include <test/test.h>
Simon Glassd18f7392021-03-07 17:34:50 -070015#include <test/ut.h>
Simon Glass5722fb22021-03-07 17:34:47 -070016
Simon Glass0f8f6772021-03-07 17:34:49 -070017DECLARE_GLOBAL_DATA_PTR;
18
Simon Glass4066d8d2021-03-07 17:35:04 -070019/* This is valid when a test is running, NULL otherwise */
20static struct unit_test_state *cur_test_state;
21
22struct unit_test_state *test_get_state(void)
23{
24 return cur_test_state;
25}
26
27void test_set_state(struct unit_test_state *uts)
28{
29 cur_test_state = uts;
30}
31
Simon Glass2dba4762021-03-07 17:34:58 -070032/**
33 * dm_test_pre_run() - Get ready to run a driver model test
34 *
35 * This clears out the driver model data structures. For sandbox it resets the
36 * state structure
37 *
38 * @uts: Test state
39 */
40static int dm_test_pre_run(struct unit_test_state *uts)
41{
42 bool of_live = uts->of_live;
43
44 uts->root = NULL;
45 uts->testdev = NULL;
46 uts->force_fail_alloc = false;
47 uts->skip_post_probe = false;
48 gd->dm_root = NULL;
Simon Glassf7005042021-07-05 16:32:43 -060049 if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
Simon Glass2dba4762021-03-07 17:34:58 -070050 memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
Simon Glass45b807d2021-03-25 10:44:33 +130051 arch_reset_for_test();
Simon Glass2dba4762021-03-07 17:34:58 -070052
53 /* Determine whether to make the live tree available */
54 gd_set_of_root(of_live ? uts->of_root : NULL);
55 ut_assertok(dm_init(of_live));
56 uts->root = dm_root();
57
58 return 0;
59}
60
Simon Glass5b7e55b2021-03-07 17:34:59 -070061static int dm_test_post_run(struct unit_test_state *uts)
62{
63 int id;
64
Simon Glass96113c12021-03-15 17:25:21 +130065 /*
66 * With of-platdata-inst the uclasses are created at build time. If we
67 * destroy them we cannot get them back since uclass_add() is not
68 * supported. So skip this.
69 */
70 if (!CONFIG_IS_ENABLED(OF_PLATDATA_INST)) {
71 for (id = 0; id < UCLASS_COUNT; id++) {
72 struct uclass *uc;
Simon Glass5b7e55b2021-03-07 17:34:59 -070073
Simon Glass96113c12021-03-15 17:25:21 +130074 /*
75 * If the uclass doesn't exist we don't want to create
76 * it. So check that here before we call
77 * uclass_find_device().
78 */
79 uc = uclass_find(id);
80 if (!uc)
81 continue;
82 ut_assertok(uclass_destroy(uc));
83 }
Simon Glass5b7e55b2021-03-07 17:34:59 -070084 }
85
86 return 0;
87}
88
Simon Glass242357c2021-03-07 17:34:51 -070089/* Ensure all the test devices are probed */
90static int do_autoprobe(struct unit_test_state *uts)
91{
92 struct udevice *dev;
93 int ret;
94
95 /* Scanning the uclass is enough to probe all the devices */
96 for (ret = uclass_first_device(UCLASS_TEST, &dev);
97 dev;
98 ret = uclass_next_device(&dev))
99 ;
100
101 return ret;
102}
103
Simon Glass0d32ec22021-03-07 17:35:03 -0700104/*
105 * ut_test_run_on_flattree() - Check if we should run a test with flat DT
106 *
107 * This skips long/slow tests where there is not much value in running a flat
108 * DT test in addition to a live DT test.
109 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100110 * Return: true to run the given test on the flat device tree
Simon Glass0d32ec22021-03-07 17:35:03 -0700111 */
112static bool ut_test_run_on_flattree(struct unit_test *test)
113{
114 const char *fname = strrchr(test->file, '/') + 1;
115
116 if (!(test->flags & UT_TESTF_DM))
117 return false;
118
119 return !strstr(fname, "video") || strstr(test->name, "video_base");
120}
121
Simon Glass436687e2021-03-07 17:35:01 -0700122/**
Simon Glassbb2b1732021-03-07 17:35:05 -0700123 * test_matches() - Check if a test should be run
124 *
125 * This checks if the a test should be run. In the normal case of running all
126 * tests, @select_name is NULL.
127 *
128 * @prefix: String prefix for the tests. Any tests that have this prefix will be
129 * printed without the prefix, so that it is easier to see the unique part
Simon Glass1ef74ab2021-03-07 17:35:12 -0700130 * of the test name. If NULL, any suite name (xxx_test) is considered to be
131 * a prefix.
Simon Glassbb2b1732021-03-07 17:35:05 -0700132 * @test_name: Name of current test
133 * @select_name: Name of test to run (or NULL for all)
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100134 * Return: true to run this test, false to skip it
Simon Glassbb2b1732021-03-07 17:35:05 -0700135 */
136static bool test_matches(const char *prefix, const char *test_name,
137 const char *select_name)
138{
Andy Shevchenkod91cfbb2021-02-11 16:40:10 +0200139 size_t len;
140
Simon Glassbb2b1732021-03-07 17:35:05 -0700141 if (!select_name)
142 return true;
143
Andy Shevchenkod91cfbb2021-02-11 16:40:10 +0200144 /* Allow glob expansion in the test name */
145 len = select_name[strlen(select_name) - 1] == '*' ? strlen(select_name) : 0;
146 if (len-- == 1)
147 return true;
148
149 if (!strncmp(test_name, select_name, len))
Simon Glassbb2b1732021-03-07 17:35:05 -0700150 return true;
151
Andy Shevchenko00d42902021-02-11 16:40:11 +0200152 if (prefix) {
153 /* All tests have this prefix */
154 if (!strncmp(test_name, prefix, strlen(prefix)))
155 test_name += strlen(prefix);
156 } else {
Simon Glass1ef74ab2021-03-07 17:35:12 -0700157 const char *p = strstr(test_name, "_test_");
158
159 /* convert xxx_test_yyy to yyy, i.e. remove the suite name */
160 if (p)
Andy Shevchenko00d42902021-02-11 16:40:11 +0200161 test_name = p + strlen("_test_");
Simon Glass1ef74ab2021-03-07 17:35:12 -0700162 }
Simon Glassbb2b1732021-03-07 17:35:05 -0700163
Andy Shevchenkod91cfbb2021-02-11 16:40:10 +0200164 if (!strncmp(test_name, select_name, len))
Simon Glassbb2b1732021-03-07 17:35:05 -0700165 return true;
166
167 return false;
168}
169
Simon Glass53d1b192021-03-07 17:35:08 -0700170/**
Simon Glass1899e132021-03-07 17:35:07 -0700171 * ut_list_has_dm_tests() - Check if a list of tests has driver model ones
172 *
173 * @tests: List of tests to run
174 * @count: Number of tests to ru
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100175 * Return: true if any of the tests have the UT_TESTF_DM flag
Simon Glass1899e132021-03-07 17:35:07 -0700176 */
177static bool ut_list_has_dm_tests(struct unit_test *tests, int count)
178{
179 struct unit_test *test;
180
181 for (test = tests; test < tests + count; test++) {
182 if (test->flags & UT_TESTF_DM)
183 return true;
184 }
185
186 return false;
187}
188
Simon Glassbb2b1732021-03-07 17:35:05 -0700189/**
Simon Glass53d1b192021-03-07 17:35:08 -0700190 * dm_test_restore() Put things back to normal so sandbox works as expected
191 *
192 * @of_root: Value to set for of_root
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100193 * Return: 0 if OK, -ve on error
Simon Glass53d1b192021-03-07 17:35:08 -0700194 */
195static int dm_test_restore(struct device_node *of_root)
196{
197 int ret;
198
199 gd_set_of_root(of_root);
200 gd->dm_root = NULL;
201 ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE));
202 if (ret)
203 return ret;
204 dm_scan_plat(false);
205 if (!CONFIG_IS_ENABLED(OF_PLATDATA))
206 dm_scan_fdt(false);
207
208 return 0;
209}
210
211/**
Simon Glass436687e2021-03-07 17:35:01 -0700212 * test_pre_run() - Handle any preparation needed to run a test
213 *
214 * @uts: Test state
215 * @test: Test to prepare for
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100216 * Return: 0 if OK, -EAGAIN to skip this test since some required feature is not
Simon Glass436687e2021-03-07 17:35:01 -0700217 * available, other -ve on error (meaning that testing cannot likely
218 * continue)
219 */
220static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
Simon Glassd93dc7d2021-03-07 17:34:48 -0700221{
Simon Glassa128b1b2022-03-04 08:43:01 -0700222 ut_assertok(event_init());
223
Simon Glassb2890a12021-03-07 17:34:56 -0700224 if (test->flags & UT_TESTF_DM)
Simon Glass2dba4762021-03-07 17:34:58 -0700225 ut_assertok(dm_test_pre_run(uts));
Simon Glassb2890a12021-03-07 17:34:56 -0700226
Simon Glass59cad962021-03-07 17:34:55 -0700227 ut_set_skip_delays(uts, false);
228
Simon Glass86a5bd02021-03-07 17:34:53 -0700229 uts->start = mallinfo();
Simon Glassd93dc7d2021-03-07 17:34:48 -0700230
Simon Glass9c80e542022-07-30 15:52:26 -0600231 if (test->flags & UT_TESTF_SCAN_PDATA) {
Simon Glass177e0fd2021-03-07 17:34:52 -0700232 ut_assertok(dm_scan_plat(false));
Simon Glass9c80e542022-07-30 15:52:26 -0600233 ut_assertok(dm_scan_other(false));
234 }
Simon Glass177e0fd2021-03-07 17:34:52 -0700235
Simon Glass242357c2021-03-07 17:34:51 -0700236 if (test->flags & UT_TESTF_PROBE_TEST)
237 ut_assertok(do_autoprobe(uts));
238
Simon Glassd18f7392021-03-07 17:34:50 -0700239 if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
240 (test->flags & UT_TESTF_SCAN_FDT))
241 ut_assertok(dm_extended_scan(false));
242
Simon Glassd93dc7d2021-03-07 17:34:48 -0700243 if (test->flags & UT_TESTF_CONSOLE_REC) {
244 int ret = console_record_reset_enable();
245
246 if (ret) {
247 printf("Skipping: Console recording disabled\n");
248 return -EAGAIN;
249 }
250 }
Simon Glass2b566b92021-03-07 17:34:54 -0700251 ut_silence_console(uts);
Simon Glassd93dc7d2021-03-07 17:34:48 -0700252
253 return 0;
254}
255
Simon Glass436687e2021-03-07 17:35:01 -0700256/**
257 * test_post_run() - Handle cleaning up after a test
258 *
259 * @uts: Test state
260 * @test: Test to clean up after
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100261 * Return: 0 if OK, -ve on error (meaning that testing cannot likely continue)
Simon Glass436687e2021-03-07 17:35:01 -0700262 */
263static int test_post_run(struct unit_test_state *uts, struct unit_test *test)
Simon Glassd93dc7d2021-03-07 17:34:48 -0700264{
Simon Glass2b566b92021-03-07 17:34:54 -0700265 ut_unsilence_console(uts);
Simon Glass5b7e55b2021-03-07 17:34:59 -0700266 if (test->flags & UT_TESTF_DM)
267 ut_assertok(dm_test_post_run(uts));
Simon Glassa128b1b2022-03-04 08:43:01 -0700268 ut_assertok(event_uninit());
Simon Glass0f8f6772021-03-07 17:34:49 -0700269
Simon Glassd93dc7d2021-03-07 17:34:48 -0700270 return 0;
271}
272
Simon Glass0d32ec22021-03-07 17:35:03 -0700273/**
274 * ut_run_test() - Run a single test
275 *
276 * This runs the test, handling any preparation and clean-up needed. It prints
277 * the name of each test before running it.
278 *
279 * @uts: Test state to update. The caller should ensure that this is zeroed for
280 * the first call to this function. On exit, @uts->fail_count is
281 * incremented by the number of failures (0, one hopes)
282 * @test_name: Test to run
283 * @name: Name of test, possibly skipping a prefix that should not be displayed
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100284 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
Simon Glass0d32ec22021-03-07 17:35:03 -0700285 * any failed
286 */
287static int ut_run_test(struct unit_test_state *uts, struct unit_test *test,
288 const char *test_name)
Simon Glass5517edb2021-03-07 17:35:00 -0700289{
Simon Glass436687e2021-03-07 17:35:01 -0700290 const char *fname = strrchr(test->file, '/') + 1;
291 const char *note = "";
Simon Glass5517edb2021-03-07 17:35:00 -0700292 int ret;
293
Simon Glass436687e2021-03-07 17:35:01 -0700294 if ((test->flags & UT_TESTF_DM) && !uts->of_live)
295 note = " (flat tree)";
296 printf("Test: %s: %s%s\n", test_name, fname, note);
Simon Glass5517edb2021-03-07 17:35:00 -0700297
Simon Glass4066d8d2021-03-07 17:35:04 -0700298 /* Allow access to test state from drivers */
299 test_set_state(uts);
300
Simon Glass5517edb2021-03-07 17:35:00 -0700301 ret = test_pre_run(uts, test);
302 if (ret == -EAGAIN)
303 return -EAGAIN;
304 if (ret)
305 return ret;
306
307 test->func(uts);
308
309 ret = test_post_run(uts, test);
310 if (ret)
311 return ret;
312
Simon Glass4066d8d2021-03-07 17:35:04 -0700313 test_set_state( NULL);
314
Simon Glass5517edb2021-03-07 17:35:00 -0700315 return 0;
316}
317
Simon Glassbb2b1732021-03-07 17:35:05 -0700318/**
319 * ut_run_test_live_flat() - Run a test with both live and flat tree
320 *
321 * This calls ut_run_test() with livetree enabled, which is the standard setup
322 * for runnig tests. Then, for driver model test, it calls it again with
323 * livetree disabled. This allows checking of flattree being used when OF_LIVE
324 * is enabled, as is the case in U-Boot proper before relocation, as well as in
325 * SPL.
326 *
327 * @uts: Test state to update. The caller should ensure that this is zeroed for
328 * the first call to this function. On exit, @uts->fail_count is
329 * incremented by the number of failures (0, one hopes)
330 * @test: Test to run
331 * @name: Name of test, possibly skipping a prefix that should not be displayed
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100332 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
Simon Glassbb2b1732021-03-07 17:35:05 -0700333 * any failed
334 */
335static int ut_run_test_live_flat(struct unit_test_state *uts,
336 struct unit_test *test, const char *name)
Simon Glass0d32ec22021-03-07 17:35:03 -0700337{
338 int runs;
339
340 /* Run with the live tree if possible */
341 runs = 0;
342 if (CONFIG_IS_ENABLED(OF_LIVE)) {
Simon Glass2f0cb8f2022-07-30 15:52:12 -0600343 if (!(test->flags &
344 (UT_TESTF_FLAT_TREE | UT_TESTF_LIVE_OR_FLAT))) {
Simon Glass0d32ec22021-03-07 17:35:03 -0700345 uts->of_live = true;
346 ut_assertok(ut_run_test(uts, test, test->name));
347 runs++;
348 }
349 }
350
351 /*
352 * Run with the flat tree if we couldn't run it with live tree,
353 * or it is a core test.
354 */
355 if (!(test->flags & UT_TESTF_LIVE_TREE) &&
356 (!runs || ut_test_run_on_flattree(test))) {
357 uts->of_live = false;
358 ut_assertok(ut_run_test(uts, test, test->name));
359 runs++;
360 }
361
362 return 0;
363}
364
Simon Glassbb2b1732021-03-07 17:35:05 -0700365/**
366 * ut_run_tests() - Run a set of tests
367 *
368 * This runs the tests, handling any preparation and clean-up needed. It prints
369 * the name of each test before running it.
370 *
371 * @uts: Test state to update. The caller should ensure that this is zeroed for
372 * the first call to this function. On exit, @uts->fail_count is
373 * incremented by the number of failures (0, one hopes)
374 * @prefix: String prefix for the tests. Any tests that have this prefix will be
375 * printed without the prefix, so that it is easier to see the unique part
376 * of the test name. If NULL, no prefix processing is done
377 * @tests: List of tests to run
378 * @count: Number of tests to run
379 * @select_name: Name of a single test to run (from the list provided). If NULL
380 * then all tests are run
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100381 * Return: 0 if all tests passed, -ENOENT if test @select_name was not found,
Simon Glassbb2b1732021-03-07 17:35:05 -0700382 * -EBADF if any failed
383 */
384static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
385 struct unit_test *tests, int count,
386 const char *select_name)
Simon Glass5722fb22021-03-07 17:34:47 -0700387{
388 struct unit_test *test;
Simon Glass5722fb22021-03-07 17:34:47 -0700389 int found = 0;
390
391 for (test = tests; test < tests + count; test++) {
392 const char *test_name = test->name;
Simon Glass91a187b2022-08-01 07:58:45 -0600393 int ret, i, old_fail_count;
Simon Glass5722fb22021-03-07 17:34:47 -0700394
Simon Glassbb2b1732021-03-07 17:35:05 -0700395 if (!test_matches(prefix, test_name, select_name))
Simon Glass5722fb22021-03-07 17:34:47 -0700396 continue;
Simon Glass91a187b2022-08-01 07:58:45 -0600397 old_fail_count = uts->fail_count;
398 for (i = 0; i < uts->runs_per_test; i++)
399 ret = ut_run_test_live_flat(uts, test, select_name);
400 if (uts->fail_count != old_fail_count) {
401 printf("Test %s failed %d times\n", select_name,
402 uts->fail_count - old_fail_count);
403 }
Simon Glass5722fb22021-03-07 17:34:47 -0700404 found++;
Simon Glassd93dc7d2021-03-07 17:34:48 -0700405 if (ret == -EAGAIN)
406 continue;
407 if (ret)
408 return ret;
Simon Glass5722fb22021-03-07 17:34:47 -0700409 }
410 if (select_name && !found)
411 return -ENOENT;
412
413 return uts->fail_count ? -EBADF : 0;
414}
415
416int ut_run_list(const char *category, const char *prefix,
Simon Glass91a187b2022-08-01 07:58:45 -0600417 struct unit_test *tests, int count, const char *select_name,
418 int runs_per_test)
Simon Glass5722fb22021-03-07 17:34:47 -0700419{
420 struct unit_test_state uts = { .fail_count = 0 };
Simon Glass53d1b192021-03-07 17:35:08 -0700421 bool has_dm_tests = false;
Simon Glass5722fb22021-03-07 17:34:47 -0700422 int ret;
423
Simon Glass1899e132021-03-07 17:35:07 -0700424 if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
425 ut_list_has_dm_tests(tests, count)) {
Simon Glass53d1b192021-03-07 17:35:08 -0700426 has_dm_tests = true;
Simon Glass1899e132021-03-07 17:35:07 -0700427 /*
428 * If we have no device tree, or it only has a root node, then
429 * these * tests clearly aren't going to work...
430 */
431 if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
432 puts("Please run with test device tree:\n"
433 " ./u-boot -d arch/sandbox/dts/test.dtb\n");
434 return CMD_RET_FAILURE;
435 }
436 }
437
Simon Glass5722fb22021-03-07 17:34:47 -0700438 if (!select_name)
439 printf("Running %d %s tests\n", count, category);
440
Simon Glassbb2b1732021-03-07 17:35:05 -0700441 uts.of_root = gd_of_root();
Simon Glass91a187b2022-08-01 07:58:45 -0600442 uts.runs_per_test = runs_per_test;
Simon Glass5722fb22021-03-07 17:34:47 -0700443 ret = ut_run_tests(&uts, prefix, tests, count, select_name);
444
445 if (ret == -ENOENT)
446 printf("Test '%s' not found\n", select_name);
447 else
448 printf("Failures: %d\n", uts.fail_count);
449
Simon Glass53d1b192021-03-07 17:35:08 -0700450 /* Best efforts only...ignore errors */
451 if (has_dm_tests)
452 dm_test_restore(uts.of_root);
453
Simon Glass5722fb22021-03-07 17:34:47 -0700454 return ret;
455}