blob: 16490e00ab3bac10a084d74186203e18258c88df [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Joe Hershberger11dd7cc2015-05-20 14:27:28 -05002/*
3 * (C) Copyright 2015
4 * Joe Hershberger, National Instruments, joe.hershberger@ni.com
Joe Hershberger11dd7cc2015-05-20 14:27:28 -05005 */
6
Joe Hershberger11dd7cc2015-05-20 14:27:28 -05007#include <command.h>
Simon Glass6db8ea52020-07-28 19:41:13 -06008#include <console.h>
Tom Rinidec7ea02024-05-20 13:35:03 -06009#include <vsprintf.h>
Joe Hershberger11dd7cc2015-05-20 14:27:28 -050010#include <test/suites.h>
Simon Glass81cbe1c2017-11-25 11:57:29 -070011#include <test/test.h>
Simon Glass5722fb22021-03-07 17:34:47 -070012#include <test/ut.h>
Joe Hershberger11dd7cc2015-05-20 14:27:28 -050013
Simon Glass78fd76b2025-01-20 14:25:33 -070014/**
15 * struct suite - A set of tests for a certain topic
16 *
17 * All tests end up in a single 'struct unit_test' linker-list array, in order
18 * of the suite they are in
19 *
20 * @name: Name of suite
21 * @start: First test in suite
22 * @end: End test in suite (points to the first test in the next suite)
23 * @cmd: Command to use to run the suite
24 */
25struct suite {
26 const char *name;
27 struct unit_test *start;
28 struct unit_test *end;
29 ut_cmd_func cmd;
30};
31
Simon Glassed38aef2020-05-10 11:40:03 -060032static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc,
33 char *const argv[]);
Joe Hershberger11dd7cc2015-05-20 14:27:28 -050034
Simon Glassfb998c22022-10-29 19:47:12 -060035static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc,
36 char *const argv[]);
37
Philippe Reynes1f99f842019-12-17 19:07:04 +010038int cmd_ut_category(const char *name, const char *prefix,
39 struct unit_test *tests, int n_ents,
Simon Glassed38aef2020-05-10 11:40:03 -060040 int argc, char *const argv[])
Simon Glass81cbe1c2017-11-25 11:57:29 -070041{
Simon Glass3869eb52025-01-20 14:25:26 -070042 struct unit_test_state uts;
Simon Glass85ba7c32022-10-29 19:47:13 -060043 const char *test_insert = NULL;
Simon Glass91a187b2022-08-01 07:58:45 -060044 int runs_per_text = 1;
Simon Glass1f1614b2022-10-20 18:22:50 -060045 bool force_run = false;
Simon Glass5722fb22021-03-07 17:34:47 -070046 int ret;
Simon Glass81cbe1c2017-11-25 11:57:29 -070047
Simon Glass1f1614b2022-10-20 18:22:50 -060048 while (argc > 1 && *argv[1] == '-') {
49 const char *str = argv[1];
50
51 switch (str[1]) {
52 case 'r':
53 runs_per_text = dectoul(str + 2, NULL);
54 break;
55 case 'f':
56 force_run = true;
57 break;
Simon Glass85ba7c32022-10-29 19:47:13 -060058 case 'I':
59 test_insert = str + 2;
60 break;
Simon Glass1f1614b2022-10-20 18:22:50 -060061 }
Simon Glass91a187b2022-08-01 07:58:45 -060062 argv++;
Simon Glass85ba7c32022-10-29 19:47:13 -060063 argc--;
Simon Glass91a187b2022-08-01 07:58:45 -060064 }
65
Simon Glass3869eb52025-01-20 14:25:26 -070066 ut_init_state(&uts);
67 ret = ut_run_list(&uts, name, prefix, tests, n_ents,
Simon Glass793a98e2023-11-18 14:05:20 -070068 cmd_arg1(argc, argv), runs_per_text, force_run,
Simon Glass85ba7c32022-10-29 19:47:13 -060069 test_insert);
Simon Glass3869eb52025-01-20 14:25:26 -070070 ut_uninit_state(&uts);
Simon Glass81cbe1c2017-11-25 11:57:29 -070071
Simon Glass5722fb22021-03-07 17:34:47 -070072 return ret ? CMD_RET_FAILURE : 0;
Simon Glass81cbe1c2017-11-25 11:57:29 -070073}
74
Simon Glass78fd76b2025-01-20 14:25:33 -070075/* declare linker-list symbols for the start and end of a suite */
76#define SUITE_DECL(_name) \
77 ll_start_decl(suite_start_ ## _name, struct unit_test, ut_ ## _name); \
78 ll_end_decl(suite_end_ ## _name, struct unit_test, ut_ ## _name)
79
80/* declare a test suite which uses a subcommand to run */
81#define SUITE_CMD(_name, _cmd_func) { \
82 #_name, \
83 suite_start_ ## _name, \
84 suite_end_ ## _name, \
85 _cmd_func, \
86 }
87
88/* declare a test suite which can be run directly without a subcommand */
89#define SUITE(_name) { \
90 #_name, \
91 suite_start_ ## _name, \
92 suite_end_ ## _name, \
93 NULL, \
94 }
95
Simon Glass78fd76b2025-01-20 14:25:33 -070096SUITE_DECL(bdinfo);
97SUITE_DECL(bootstd);
98SUITE_DECL(cmd);
99SUITE_DECL(common);
100SUITE_DECL(dm);
101SUITE_DECL(env);
102SUITE_DECL(exit);
103SUITE_DECL(fdt);
104SUITE_DECL(font);
105SUITE_DECL(optee);
106SUITE_DECL(overlay);
107SUITE_DECL(lib);
108SUITE_DECL(log);
109SUITE_DECL(mbr);
110SUITE_DECL(mem);
111SUITE_DECL(setexpr);
112SUITE_DECL(measurement);
113SUITE_DECL(bloblist);
114SUITE_DECL(bootm);
115SUITE_DECL(addrmap);
116SUITE_DECL(hush);
117SUITE_DECL(loadm);
118SUITE_DECL(pci_mps);
119SUITE_DECL(seama);
120SUITE_DECL(upl);
121
122static struct suite suites[] = {
Simon Glasse1dc0502025-01-20 14:25:34 -0700123 SUITE(bdinfo),
Simon Glass804aa372023-10-01 19:15:15 -0600124#ifdef CONFIG_UT_BOOTSTD
Simon Glass78fd76b2025-01-20 14:25:33 -0700125 SUITE_CMD(bootstd, do_ut_bootstd),
Simon Glassb255efc2022-04-24 23:31:24 -0600126#endif
Simon Glassc2356572025-01-20 14:25:35 -0700127 SUITE(cmd),
Simon Glassbc39468a2025-01-20 14:25:36 -0700128 SUITE(common),
Simon Glass82f00f22025-01-20 14:25:37 -0700129 SUITE(dm),
Simon Glass2ff779d2025-01-20 14:25:38 -0700130 SUITE(env),
Simon Glass3e5f32d2025-01-20 14:25:39 -0700131 SUITE(exit),
Simon Glass936b69e2025-01-20 14:25:40 -0700132 SUITE(fdt),
Simon Glass1b0b3f52025-01-20 14:25:41 -0700133 SUITE(font),
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200134#ifdef CONFIG_UT_OPTEE
Simon Glass78fd76b2025-01-20 14:25:33 -0700135 SUITE_CMD(optee, do_ut_optee),
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200136#endif
Maxime Ripard0e31a112016-07-05 10:26:46 +0200137#ifdef CONFIG_UT_OVERLAY
Simon Glass78fd76b2025-01-20 14:25:33 -0700138 SUITE_CMD(overlay, do_ut_overlay),
Maxime Ripard0e31a112016-07-05 10:26:46 +0200139#endif
Simon Glassb315ffb2025-01-20 14:25:42 -0700140 SUITE(lib),
Simon Glassf7ad5092025-01-20 14:25:43 -0700141 SUITE(log),
Simon Glassc16ffb22025-01-20 14:25:44 -0700142 SUITE(mbr),
Simon Glass05512d62025-01-20 14:25:45 -0700143 SUITE(mem),
Simon Glass8feb5ee2025-01-20 14:25:46 -0700144 SUITE(setexpr),
Simon Glasscc9d1de2025-01-20 14:25:47 -0700145 SUITE(measurement),
Simon Glassacec4be2025-01-20 14:25:48 -0700146 SUITE(bloblist),
Simon Glass4060c362025-01-20 14:25:49 -0700147 SUITE(bootm),
Simon Glass03bf0042025-01-20 14:25:50 -0700148 SUITE(addrmap),
Simon Glassb5f92742025-01-20 14:25:51 -0700149 SUITE(hush),
Simon Glass401c2cf2025-01-20 14:25:52 -0700150 SUITE(loadm),
Simon Glassc6cede32025-01-20 14:25:53 -0700151 SUITE(pci_mps),
Simon Glassf0764dd2025-01-20 14:25:54 -0700152 SUITE(seama),
Simon Glass0cf497c2025-01-20 14:25:55 -0700153 SUITE(upl),
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500154};
155
Simon Glassa3ce1292025-01-20 14:25:57 -0700156/**
157 * has_tests() - Check if a suite has tests, i.e. is supported in this build
158 *
159 * If the suite is run using a command, we have to assume that tests may be
160 * present, since we have no visibility
161 *
162 * @ste: Suite to check
163 * Return: true if supported, false if not
164 */
165static bool has_tests(struct suite *ste)
166{
167 int n_ents = ste->end - ste->start;
168
169 return n_ents || ste->cmd;
170}
171
Simon Glass78fd76b2025-01-20 14:25:33 -0700172/** run_suite() - Run a suite of tests */
173static int run_suite(struct suite *ste, struct cmd_tbl *cmdtp, int flag,
174 int argc, char *const argv[])
175{
176 int ret;
177
178 if (ste->cmd) {
179 ret = ste->cmd(cmdtp, flag, argc, argv);
180 } else {
181 int n_ents = ste->end - ste->start;
182 char prefix[30];
183
184 /* use a standard prefix */
185 snprintf(prefix, sizeof(prefix), "%s_test", ste->name);
186 ret = cmd_ut_category(ste->name, prefix, ste->start, n_ents,
187 argc, argv);
188 }
189
190 return ret;
191}
192
Simon Glassed38aef2020-05-10 11:40:03 -0600193static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc,
194 char *const argv[])
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500195{
196 int i;
197 int retval;
198 int any_fail = 0;
199
Simon Glass78fd76b2025-01-20 14:25:33 -0700200 for (i = 0; i < ARRAY_SIZE(suites); i++) {
201 struct suite *ste = &suites[i];
202 char *const argv[] = {(char *)ste->name, NULL};
203
Simon Glassa3ce1292025-01-20 14:25:57 -0700204 if (has_tests(ste)) {
205 printf("----Running %s tests----\n", ste->name);
206 retval = run_suite(ste, cmdtp, flag, 1, argv);
207 if (!any_fail)
208 any_fail = retval;
209 }
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500210 }
211
212 return any_fail;
213}
214
Simon Glassfb998c22022-10-29 19:47:12 -0600215static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc,
216 char *const argv[])
217{
Simon Glassa3ce1292025-01-20 14:25:57 -0700218 int suite_count, i;
Simon Glasscfb38f82025-01-20 14:25:30 -0700219 const char *flags;
220
Simon Glassa3ce1292025-01-20 14:25:57 -0700221 for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) {
222 struct suite *ste = &suites[i];
223
224 if (has_tests(ste))
225 suite_count++;
226 }
227
228 printf("Test suites: %d\n", suite_count);
Simon Glassfb998c22022-10-29 19:47:12 -0600229 printf("Total tests: %d\n", (int)UNIT_TEST_ALL_COUNT());
230
Simon Glasscfb38f82025-01-20 14:25:30 -0700231 flags = cmd_arg1(argc, argv);
232 if (flags && !strcmp("-s", flags)) {
233 int i;
234
235 puts("\nTests Suite\n");
236 puts("----- -----\n");
Simon Glass7d4ae012025-01-20 14:25:56 -0700237 for (i = 0; i < ARRAY_SIZE(suites); i++) {
Simon Glass78fd76b2025-01-20 14:25:33 -0700238 struct suite *ste = &suites[i];
239 long n_ent = ste->end - ste->start;
240
241 if (n_ent)
242 printf("%5ld %s\n", n_ent, ste->name);
Simon Glassa3ce1292025-01-20 14:25:57 -0700243 else if (ste->cmd)
Simon Glass78fd76b2025-01-20 14:25:33 -0700244 printf("%5s %s\n", "?", ste->name);
245 }
Simon Glasscfb38f82025-01-20 14:25:30 -0700246 }
247
Simon Glassfb998c22022-10-29 19:47:12 -0600248 return 0;
249}
250
Simon Glass78fd76b2025-01-20 14:25:33 -0700251static struct suite *find_suite(const char *name)
252{
253 struct suite *ste;
254 int i;
255
256 for (i = 0, ste = suites; i < ARRAY_SIZE(suites); i++, ste++) {
257 if (!strcmp(ste->name, name))
258 return ste;
259 }
260
261 return NULL;
262}
263
Simon Glassed38aef2020-05-10 11:40:03 -0600264static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500265{
Simon Glass78fd76b2025-01-20 14:25:33 -0700266 struct suite *ste;
267 const char *name;
268 int ret;
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500269
270 if (argc < 2)
271 return CMD_RET_USAGE;
272
273 /* drop initial "ut" arg */
274 argc--;
275 argv++;
276
Simon Glass78fd76b2025-01-20 14:25:33 -0700277 name = argv[0];
278 if (!strcmp(name, "all")) {
279 ret = do_ut_all(cmdtp, flag, argc, argv);
280 } else if (!strcmp(name, "info")) {
281 ret = do_ut_info(cmdtp, flag, argc, argv);
282 } else {
283 ste = find_suite(argv[0]);
284 if (!ste) {
285 printf("Suite '%s' not found\n", argv[0]);
286 return CMD_RET_FAILURE;
Simon Glassa3ce1292025-01-20 14:25:57 -0700287 } else if (!has_tests(ste)) {
288 /* perhaps a Kconfig option needs to be set? */
289 printf("Suite '%s' is not enabled\n", argv[0]);
290 return CMD_RET_FAILURE;
Simon Glass78fd76b2025-01-20 14:25:33 -0700291 }
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500292
Simon Glass78fd76b2025-01-20 14:25:33 -0700293 ret = run_suite(ste, cmdtp, flag, argc, argv);
294 }
295 if (ret)
296 return ret;
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500297
Simon Glass78fd76b2025-01-20 14:25:33 -0700298 return 0;
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500299}
300
Tom Rini03f146c2023-10-07 15:13:08 -0400301U_BOOT_LONGHELP(ut,
Simon Glass154bb8e2022-10-29 19:47:10 -0600302 "[-r] [-f] [<suite>] - run unit tests\n"
303 " -r<runs> Number of times to run each test\n"
304 " -f Force 'manual' tests to run as well\n"
305 " <suite> Test suite to run, or all\n"
306 "\n"
Simon Glassfb998c22022-10-29 19:47:12 -0600307 "\nOptions for <suite>:"
Simon Glass154bb8e2022-10-29 19:47:10 -0600308 "\nall - execute all enabled tests"
Simon Glasscfb38f82025-01-20 14:25:30 -0700309 "\ninfo [-s] - show info about tests [and suites]"
Simon Glass154bb8e2022-10-29 19:47:10 -0600310#ifdef CONFIG_CMD_ADDRMAP
311 "\naddrmap - very basic test of addrmap command"
312#endif
Marek Vasut2cd173c2023-05-31 03:03:58 +0200313#ifdef CONFIG_CMD_BDI
314 "\nbdinfo - bdinfo command"
315#endif
Heinrich Schuchardtb8b6c812018-08-31 21:31:28 +0200316#ifdef CONFIG_SANDBOX
Simon Glass154bb8e2022-10-29 19:47:10 -0600317 "\nbloblist - bloblist implementation"
Heinrich Schuchardtb8b6c812018-08-31 21:31:28 +0200318#endif
Simon Glassb255efc2022-04-24 23:31:24 -0600319#ifdef CONFIG_BOOTSTD
Simon Glass154bb8e2022-10-29 19:47:10 -0600320 "\nbootstd - standard boot implementation"
321#endif
Simon Glass621a97e2023-10-01 19:15:12 -0600322#ifdef CONFIG_CMDLINE
323 "\ncmd - test various commands"
324#endif
Simon Glass3394c3c2024-11-02 13:36:56 -0600325 "\ncommon - tests for common/ directory"
Joe Hershberger9dc1d712015-05-20 14:27:29 -0500326#ifdef CONFIG_UT_DM
Simon Glass154bb8e2022-10-29 19:47:10 -0600327 "\ndm - driver model"
Joe Hershberger9dc1d712015-05-20 14:27:29 -0500328#endif
Joe Hershberger26e038f2015-05-20 14:27:36 -0500329#ifdef CONFIG_UT_ENV
Simon Glass154bb8e2022-10-29 19:47:10 -0600330 "\nenv - environment"
Joe Hershberger26e038f2015-05-20 14:27:36 -0500331#endif
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600332#ifdef CONFIG_CMD_FDT
Simon Glass154bb8e2022-10-29 19:47:10 -0600333 "\nfdt - fdt command"
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600334#endif
Simon Glass9e972c32022-10-06 08:36:16 -0600335#ifdef CONFIG_CONSOLE_TRUETYPE
Marek Vasutef9eb6c2023-08-13 00:16:41 +0200336 "\nfont - font command"
Simon Glass154bb8e2022-10-29 19:47:10 -0600337#endif
Francis Laniel2dba91a2023-12-22 22:02:21 +0100338#if CONFIG_IS_ENABLED(HUSH_PARSER)
339 "\nhush - Test hush behavior"
340#endif
Simon Glass154bb8e2022-10-29 19:47:10 -0600341#ifdef CONFIG_CMD_LOADM
342 "\nloadm - loadm command parameters and loading memory blob"
Simon Glass9e972c32022-10-06 08:36:16 -0600343#endif
Heinrich Schuchardtf77a6352019-01-30 07:53:31 +0100344#ifdef CONFIG_UT_LIB
Simon Glass154bb8e2022-10-29 19:47:10 -0600345 "\nlib - library functions"
Heinrich Schuchardtf77a6352019-01-30 07:53:31 +0100346#endif
Heinrich Schuchardtf433d502020-02-26 21:48:18 +0100347#ifdef CONFIG_UT_LOG
Simon Glass154bb8e2022-10-29 19:47:10 -0600348 "\nlog - logging functions"
Heinrich Schuchardtf433d502020-02-26 21:48:18 +0100349#endif
Simon Glass154bb8e2022-10-29 19:47:10 -0600350 "\nmem - memory-related commands"
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200351#ifdef CONFIG_UT_OPTEE
Simon Glass154bb8e2022-10-29 19:47:10 -0600352 "\noptee - test OP-TEE"
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200353#endif
Maxime Ripard0e31a112016-07-05 10:26:46 +0200354#ifdef CONFIG_UT_OVERLAY
Simon Glass154bb8e2022-10-29 19:47:10 -0600355 "\noverlay - device tree overlays"
Maxime Ripard0e31a112016-07-05 10:26:46 +0200356#endif
Stephen Carlsone5c05ae2023-03-10 11:07:15 -0800357#ifdef CONFIG_CMD_PCI_MPS
358 "\npci_mps - PCI Express Maximum Payload Size"
359#endif
Simon Glass154bb8e2022-10-29 19:47:10 -0600360 "\nsetexpr - setexpr command"
Linus Walleijbef39252023-02-01 00:16:13 +0100361#ifdef CONFIG_CMD_SEAMA
362 "\nseama - seama command parameters loading and decoding"
363#endif
Tom Rini03f146c2023-10-07 15:13:08 -0400364 );
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500365
366U_BOOT_CMD(
367 ut, CONFIG_SYS_MAXARGS, 1, do_ut,
368 "unit tests", ut_help_text
369);