blob: ee38d1faea8ded036c8afa66fbd3af947e70f0eb [file] [log] [blame]
Simon Glass1c721752021-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 Glassd8ed2342021-03-07 17:34:50 -07009#include <dm.h>
Simon Glass7d026452022-03-04 08:43:01 -070010#include <event.h>
Simon Glassd8ed2342021-03-07 17:34:50 -070011#include <dm/root.h>
Simon Glassc79705e2021-03-07 17:34:58 -070012#include <dm/test.h>
Simon Glasse77615d2021-03-07 17:34:59 -070013#include <dm/uclass-internal.h>
Simon Glass1c721752021-03-07 17:34:47 -070014#include <test/test.h>
Simon Glassd8ed2342021-03-07 17:34:50 -070015#include <test/ut.h>
Simon Glass1c721752021-03-07 17:34:47 -070016
Simon Glass30a0d202021-03-07 17:34:49 -070017DECLARE_GLOBAL_DATA_PTR;
18
Simon Glassfe806862021-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 Glassc79705e2021-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 Glass719d2862021-07-05 16:32:43 -060049 if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
Simon Glassc79705e2021-03-07 17:34:58 -070050 memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
Simon Glassd4a15922021-03-25 10:44:33 +130051 arch_reset_for_test();
Simon Glassc79705e2021-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 Glasse77615d2021-03-07 17:34:59 -070061static int dm_test_post_run(struct unit_test_state *uts)
62{
63 int id;
64
Simon Glasse8c023c2021-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 Glasse77615d2021-03-07 17:34:59 -070073
Simon Glasse8c023c2021-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 Glasse77615d2021-03-07 17:34:59 -070084 }
85
86 return 0;
87}
88
Simon Glass4b8b27e2021-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 Glassd2281bb2021-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 Schuchardt185f8122022-01-19 18:05:50 +0100110 * Return: true to run the given test on the flat device tree
Simon Glassd2281bb2021-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 Glassca44ca02021-03-07 17:35:01 -0700122/**
Simon Glassf97f85e2021-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 Glass84823562021-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 Glassf97f85e2021-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 Schuchardt185f8122022-01-19 18:05:50 +0100134 * Return: true to run this test, false to skip it
Simon Glassf97f85e2021-03-07 17:35:05 -0700135 */
136static bool test_matches(const char *prefix, const char *test_name,
137 const char *select_name)
138{
Andy Shevchenkoff232a72021-02-11 16:40:10 +0200139 size_t len;
140
Simon Glassf97f85e2021-03-07 17:35:05 -0700141 if (!select_name)
142 return true;
143
Andy Shevchenkoff232a72021-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 Glassf97f85e2021-03-07 17:35:05 -0700150 return true;
151
Andy Shevchenko494a5e12021-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 Glass84823562021-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 Shevchenko494a5e12021-02-11 16:40:11 +0200161 test_name = p + strlen("_test_");
Simon Glass84823562021-03-07 17:35:12 -0700162 }
Simon Glassf97f85e2021-03-07 17:35:05 -0700163
Andy Shevchenkoff232a72021-02-11 16:40:10 +0200164 if (!strncmp(test_name, select_name, len))
Simon Glassf97f85e2021-03-07 17:35:05 -0700165 return true;
166
167 return false;
168}
169
Simon Glass664277f2021-03-07 17:35:08 -0700170/**
Simon Glass1fc9c122021-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 Schuchardt185f8122022-01-19 18:05:50 +0100175 * Return: true if any of the tests have the UT_TESTF_DM flag
Simon Glass1fc9c122021-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 Glassf97f85e2021-03-07 17:35:05 -0700189/**
Simon Glass664277f2021-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 Schuchardt185f8122022-01-19 18:05:50 +0100193 * Return: 0 if OK, -ve on error
Simon Glass664277f2021-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 Glassca44ca02021-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 Schuchardt185f8122022-01-19 18:05:50 +0100216 * Return: 0 if OK, -EAGAIN to skip this test since some required feature is not
Simon Glassca44ca02021-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 Glassd002a272021-03-07 17:34:48 -0700221{
Simon Glass7d026452022-03-04 08:43:01 -0700222 ut_assertok(event_init());
223
Simon Glass72b524c2021-03-07 17:34:56 -0700224 if (test->flags & UT_TESTF_DM)
Simon Glassc79705e2021-03-07 17:34:58 -0700225 ut_assertok(dm_test_pre_run(uts));
Simon Glass72b524c2021-03-07 17:34:56 -0700226
Simon Glass47ec3ed2021-03-07 17:34:55 -0700227 ut_set_skip_delays(uts, false);
228
Simon Glass19fb3db2021-03-07 17:34:53 -0700229 uts->start = mallinfo();
Simon Glassd002a272021-03-07 17:34:48 -0700230
Simon Glass5a986f32021-03-07 17:34:52 -0700231 if (test->flags & UT_TESTF_SCAN_PDATA)
232 ut_assertok(dm_scan_plat(false));
233
Simon Glass4b8b27e2021-03-07 17:34:51 -0700234 if (test->flags & UT_TESTF_PROBE_TEST)
235 ut_assertok(do_autoprobe(uts));
236
Simon Glassd8ed2342021-03-07 17:34:50 -0700237 if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
238 (test->flags & UT_TESTF_SCAN_FDT))
239 ut_assertok(dm_extended_scan(false));
240
Simon Glassd002a272021-03-07 17:34:48 -0700241 if (test->flags & UT_TESTF_CONSOLE_REC) {
242 int ret = console_record_reset_enable();
243
244 if (ret) {
245 printf("Skipping: Console recording disabled\n");
246 return -EAGAIN;
247 }
248 }
Simon Glass74524712021-03-07 17:34:54 -0700249 ut_silence_console(uts);
Simon Glassd002a272021-03-07 17:34:48 -0700250
251 return 0;
252}
253
Simon Glassca44ca02021-03-07 17:35:01 -0700254/**
255 * test_post_run() - Handle cleaning up after a test
256 *
257 * @uts: Test state
258 * @test: Test to clean up after
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100259 * Return: 0 if OK, -ve on error (meaning that testing cannot likely continue)
Simon Glassca44ca02021-03-07 17:35:01 -0700260 */
261static int test_post_run(struct unit_test_state *uts, struct unit_test *test)
Simon Glassd002a272021-03-07 17:34:48 -0700262{
Simon Glass74524712021-03-07 17:34:54 -0700263 ut_unsilence_console(uts);
Simon Glasse77615d2021-03-07 17:34:59 -0700264 if (test->flags & UT_TESTF_DM)
265 ut_assertok(dm_test_post_run(uts));
Simon Glass7d026452022-03-04 08:43:01 -0700266 ut_assertok(event_uninit());
Simon Glass30a0d202021-03-07 17:34:49 -0700267
Simon Glassd002a272021-03-07 17:34:48 -0700268 return 0;
269}
270
Simon Glassd2281bb2021-03-07 17:35:03 -0700271/**
272 * ut_run_test() - Run a single test
273 *
274 * This runs the test, handling any preparation and clean-up needed. It prints
275 * the name of each test before running it.
276 *
277 * @uts: Test state to update. The caller should ensure that this is zeroed for
278 * the first call to this function. On exit, @uts->fail_count is
279 * incremented by the number of failures (0, one hopes)
280 * @test_name: Test to run
281 * @name: Name of test, possibly skipping a prefix that should not be displayed
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100282 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
Simon Glassd2281bb2021-03-07 17:35:03 -0700283 * any failed
284 */
285static int ut_run_test(struct unit_test_state *uts, struct unit_test *test,
286 const char *test_name)
Simon Glass99a88fe2021-03-07 17:35:00 -0700287{
Simon Glassca44ca02021-03-07 17:35:01 -0700288 const char *fname = strrchr(test->file, '/') + 1;
289 const char *note = "";
Simon Glass99a88fe2021-03-07 17:35:00 -0700290 int ret;
291
Simon Glassca44ca02021-03-07 17:35:01 -0700292 if ((test->flags & UT_TESTF_DM) && !uts->of_live)
293 note = " (flat tree)";
294 printf("Test: %s: %s%s\n", test_name, fname, note);
Simon Glass99a88fe2021-03-07 17:35:00 -0700295
Simon Glassfe806862021-03-07 17:35:04 -0700296 /* Allow access to test state from drivers */
297 test_set_state(uts);
298
Simon Glass99a88fe2021-03-07 17:35:00 -0700299 ret = test_pre_run(uts, test);
300 if (ret == -EAGAIN)
301 return -EAGAIN;
302 if (ret)
303 return ret;
304
305 test->func(uts);
306
307 ret = test_post_run(uts, test);
308 if (ret)
309 return ret;
310
Simon Glassfe806862021-03-07 17:35:04 -0700311 test_set_state( NULL);
312
Simon Glass99a88fe2021-03-07 17:35:00 -0700313 return 0;
314}
315
Simon Glassf97f85e2021-03-07 17:35:05 -0700316/**
317 * ut_run_test_live_flat() - Run a test with both live and flat tree
318 *
319 * This calls ut_run_test() with livetree enabled, which is the standard setup
320 * for runnig tests. Then, for driver model test, it calls it again with
321 * livetree disabled. This allows checking of flattree being used when OF_LIVE
322 * is enabled, as is the case in U-Boot proper before relocation, as well as in
323 * SPL.
324 *
325 * @uts: Test state to update. The caller should ensure that this is zeroed for
326 * the first call to this function. On exit, @uts->fail_count is
327 * incremented by the number of failures (0, one hopes)
328 * @test: Test to run
329 * @name: Name of test, possibly skipping a prefix that should not be displayed
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100330 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
Simon Glassf97f85e2021-03-07 17:35:05 -0700331 * any failed
332 */
333static int ut_run_test_live_flat(struct unit_test_state *uts,
334 struct unit_test *test, const char *name)
Simon Glassd2281bb2021-03-07 17:35:03 -0700335{
336 int runs;
337
338 /* Run with the live tree if possible */
339 runs = 0;
340 if (CONFIG_IS_ENABLED(OF_LIVE)) {
341 if (!(test->flags & UT_TESTF_FLAT_TREE)) {
342 uts->of_live = true;
343 ut_assertok(ut_run_test(uts, test, test->name));
344 runs++;
345 }
346 }
347
348 /*
349 * Run with the flat tree if we couldn't run it with live tree,
350 * or it is a core test.
351 */
352 if (!(test->flags & UT_TESTF_LIVE_TREE) &&
353 (!runs || ut_test_run_on_flattree(test))) {
354 uts->of_live = false;
355 ut_assertok(ut_run_test(uts, test, test->name));
356 runs++;
357 }
358
359 return 0;
360}
361
Simon Glassf97f85e2021-03-07 17:35:05 -0700362/**
363 * ut_run_tests() - Run a set of tests
364 *
365 * This runs the tests, handling any preparation and clean-up needed. It prints
366 * the name of each test before running it.
367 *
368 * @uts: Test state to update. The caller should ensure that this is zeroed for
369 * the first call to this function. On exit, @uts->fail_count is
370 * incremented by the number of failures (0, one hopes)
371 * @prefix: String prefix for the tests. Any tests that have this prefix will be
372 * printed without the prefix, so that it is easier to see the unique part
373 * of the test name. If NULL, no prefix processing is done
374 * @tests: List of tests to run
375 * @count: Number of tests to run
376 * @select_name: Name of a single test to run (from the list provided). If NULL
377 * then all tests are run
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100378 * Return: 0 if all tests passed, -ENOENT if test @select_name was not found,
Simon Glassf97f85e2021-03-07 17:35:05 -0700379 * -EBADF if any failed
380 */
381static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
382 struct unit_test *tests, int count,
383 const char *select_name)
Simon Glass1c721752021-03-07 17:34:47 -0700384{
385 struct unit_test *test;
Simon Glass1c721752021-03-07 17:34:47 -0700386 int found = 0;
387
388 for (test = tests; test < tests + count; test++) {
389 const char *test_name = test->name;
Simon Glassd002a272021-03-07 17:34:48 -0700390 int ret;
Simon Glass1c721752021-03-07 17:34:47 -0700391
Simon Glassf97f85e2021-03-07 17:35:05 -0700392 if (!test_matches(prefix, test_name, select_name))
Simon Glass1c721752021-03-07 17:34:47 -0700393 continue;
Simon Glassf97f85e2021-03-07 17:35:05 -0700394 ret = ut_run_test_live_flat(uts, test, select_name);
Simon Glass1c721752021-03-07 17:34:47 -0700395 found++;
Simon Glassd002a272021-03-07 17:34:48 -0700396 if (ret == -EAGAIN)
397 continue;
398 if (ret)
399 return ret;
Simon Glass1c721752021-03-07 17:34:47 -0700400 }
401 if (select_name && !found)
402 return -ENOENT;
403
404 return uts->fail_count ? -EBADF : 0;
405}
406
407int ut_run_list(const char *category, const char *prefix,
408 struct unit_test *tests, int count, const char *select_name)
409{
410 struct unit_test_state uts = { .fail_count = 0 };
Simon Glass664277f2021-03-07 17:35:08 -0700411 bool has_dm_tests = false;
Simon Glass1c721752021-03-07 17:34:47 -0700412 int ret;
413
Simon Glass1fc9c122021-03-07 17:35:07 -0700414 if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
415 ut_list_has_dm_tests(tests, count)) {
Simon Glass664277f2021-03-07 17:35:08 -0700416 has_dm_tests = true;
Simon Glass1fc9c122021-03-07 17:35:07 -0700417 /*
418 * If we have no device tree, or it only has a root node, then
419 * these * tests clearly aren't going to work...
420 */
421 if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
422 puts("Please run with test device tree:\n"
423 " ./u-boot -d arch/sandbox/dts/test.dtb\n");
424 return CMD_RET_FAILURE;
425 }
426 }
427
Simon Glass1c721752021-03-07 17:34:47 -0700428 if (!select_name)
429 printf("Running %d %s tests\n", count, category);
430
Simon Glassf97f85e2021-03-07 17:35:05 -0700431 uts.of_root = gd_of_root();
Simon Glass1c721752021-03-07 17:34:47 -0700432 ret = ut_run_tests(&uts, prefix, tests, count, select_name);
433
434 if (ret == -ENOENT)
435 printf("Test '%s' not found\n", select_name);
436 else
437 printf("Failures: %d\n", uts.fail_count);
438
Simon Glass664277f2021-03-07 17:35:08 -0700439 /* Best efforts only...ignore errors */
440 if (has_dm_tests)
441 dm_test_restore(uts.of_root);
442
Simon Glass1c721752021-03-07 17:34:47 -0700443 return ret;
444}