blob: 2e5519b55f9571c8ec23c493e6f2feb11d0cf8aa [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 Glass6685ece2025-01-20 14:25:58 -070032static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp,
33 int flag, int argc, 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
Simon Glass6685ece2025-01-20 14:25:58 -070038int cmd_ut_category(struct unit_test_state *uts, const char *name,
39 const char *prefix, 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 Glass85ba7c32022-10-29 19:47:13 -060042 const char *test_insert = NULL;
Simon Glass91a187b2022-08-01 07:58:45 -060043 int runs_per_text = 1;
Simon Glass1f1614b2022-10-20 18:22:50 -060044 bool force_run = false;
Simon Glass5722fb22021-03-07 17:34:47 -070045 int ret;
Simon Glass81cbe1c2017-11-25 11:57:29 -070046
Simon Glass1f1614b2022-10-20 18:22:50 -060047 while (argc > 1 && *argv[1] == '-') {
48 const char *str = argv[1];
49
50 switch (str[1]) {
51 case 'r':
52 runs_per_text = dectoul(str + 2, NULL);
53 break;
54 case 'f':
55 force_run = true;
56 break;
Simon Glass85ba7c32022-10-29 19:47:13 -060057 case 'I':
58 test_insert = str + 2;
59 break;
Simon Glass1f1614b2022-10-20 18:22:50 -060060 }
Simon Glass91a187b2022-08-01 07:58:45 -060061 argv++;
Simon Glass85ba7c32022-10-29 19:47:13 -060062 argc--;
Simon Glass91a187b2022-08-01 07:58:45 -060063 }
64
Simon Glass6685ece2025-01-20 14:25:58 -070065 ret = ut_run_list(uts, name, prefix, tests, n_ents,
Simon Glass793a98e2023-11-18 14:05:20 -070066 cmd_arg1(argc, argv), runs_per_text, force_run,
Simon Glass85ba7c32022-10-29 19:47:13 -060067 test_insert);
Simon Glass81cbe1c2017-11-25 11:57:29 -070068
Simon Glass5722fb22021-03-07 17:34:47 -070069 return ret ? CMD_RET_FAILURE : 0;
Simon Glass81cbe1c2017-11-25 11:57:29 -070070}
71
Simon Glass78fd76b2025-01-20 14:25:33 -070072/* declare linker-list symbols for the start and end of a suite */
73#define SUITE_DECL(_name) \
74 ll_start_decl(suite_start_ ## _name, struct unit_test, ut_ ## _name); \
75 ll_end_decl(suite_end_ ## _name, struct unit_test, ut_ ## _name)
76
77/* declare a test suite which uses a subcommand to run */
78#define SUITE_CMD(_name, _cmd_func) { \
79 #_name, \
80 suite_start_ ## _name, \
81 suite_end_ ## _name, \
82 _cmd_func, \
83 }
84
85/* declare a test suite which can be run directly without a subcommand */
86#define SUITE(_name) { \
87 #_name, \
88 suite_start_ ## _name, \
89 suite_end_ ## _name, \
90 NULL, \
91 }
92
Simon Glass4c990702025-01-20 14:26:03 -070093SUITE_DECL(addrmap);
Simon Glass78fd76b2025-01-20 14:25:33 -070094SUITE_DECL(bdinfo);
Simon Glass4c990702025-01-20 14:26:03 -070095SUITE_DECL(bloblist);
96SUITE_DECL(bootm);
Simon Glass78fd76b2025-01-20 14:25:33 -070097SUITE_DECL(bootstd);
98SUITE_DECL(cmd);
99SUITE_DECL(common);
100SUITE_DECL(dm);
101SUITE_DECL(env);
102SUITE_DECL(exit);
103SUITE_DECL(fdt);
104SUITE_DECL(font);
Simon Glass4c990702025-01-20 14:26:03 -0700105SUITE_DECL(hush);
Simon Glass78fd76b2025-01-20 14:25:33 -0700106SUITE_DECL(lib);
Simon Glass4c990702025-01-20 14:26:03 -0700107SUITE_DECL(loadm);
Simon Glass78fd76b2025-01-20 14:25:33 -0700108SUITE_DECL(log);
109SUITE_DECL(mbr);
Simon Glass78fd76b2025-01-20 14:25:33 -0700110SUITE_DECL(measurement);
Simon Glass4c990702025-01-20 14:26:03 -0700111SUITE_DECL(mem);
112SUITE_DECL(optee);
113SUITE_DECL(overlay);
Simon Glass78fd76b2025-01-20 14:25:33 -0700114SUITE_DECL(pci_mps);
115SUITE_DECL(seama);
Simon Glass4c990702025-01-20 14:26:03 -0700116SUITE_DECL(setexpr);
Simon Glass78fd76b2025-01-20 14:25:33 -0700117SUITE_DECL(upl);
118
119static struct suite suites[] = {
Simon Glass4c990702025-01-20 14:26:03 -0700120 SUITE(addrmap),
Simon Glasse1dc0502025-01-20 14:25:34 -0700121 SUITE(bdinfo),
Simon Glass4c990702025-01-20 14:26:03 -0700122 SUITE(bloblist),
123 SUITE(bootm),
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),
Simon Glass4c990702025-01-20 14:26:03 -0700134 SUITE(hush),
135 SUITE(lib),
136 SUITE(loadm),
137 SUITE(log),
138 SUITE(mbr),
139 SUITE(measurement),
140 SUITE(mem),
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200141#ifdef CONFIG_UT_OPTEE
Simon Glass78fd76b2025-01-20 14:25:33 -0700142 SUITE_CMD(optee, do_ut_optee),
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200143#endif
Maxime Ripard0e31a112016-07-05 10:26:46 +0200144#ifdef CONFIG_UT_OVERLAY
Simon Glass78fd76b2025-01-20 14:25:33 -0700145 SUITE_CMD(overlay, do_ut_overlay),
Maxime Ripard0e31a112016-07-05 10:26:46 +0200146#endif
Simon Glassc6cede32025-01-20 14:25:53 -0700147 SUITE(pci_mps),
Simon Glassf0764dd2025-01-20 14:25:54 -0700148 SUITE(seama),
Simon Glass4c990702025-01-20 14:26:03 -0700149 SUITE(setexpr),
Simon Glass0cf497c2025-01-20 14:25:55 -0700150 SUITE(upl),
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500151};
152
Simon Glassa3ce1292025-01-20 14:25:57 -0700153/**
154 * has_tests() - Check if a suite has tests, i.e. is supported in this build
155 *
156 * If the suite is run using a command, we have to assume that tests may be
157 * present, since we have no visibility
158 *
159 * @ste: Suite to check
160 * Return: true if supported, false if not
161 */
162static bool has_tests(struct suite *ste)
163{
164 int n_ents = ste->end - ste->start;
165
166 return n_ents || ste->cmd;
167}
168
Simon Glass78fd76b2025-01-20 14:25:33 -0700169/** run_suite() - Run a suite of tests */
Simon Glass6685ece2025-01-20 14:25:58 -0700170static int run_suite(struct unit_test_state *uts, struct suite *ste,
171 struct cmd_tbl *cmdtp, int flag, int argc,
172 char *const argv[])
Simon Glass78fd76b2025-01-20 14:25:33 -0700173{
174 int ret;
175
176 if (ste->cmd) {
Simon Glass6685ece2025-01-20 14:25:58 -0700177 ret = ste->cmd(uts, cmdtp, flag, argc, argv);
Simon Glass78fd76b2025-01-20 14:25:33 -0700178 } else {
179 int n_ents = ste->end - ste->start;
180 char prefix[30];
181
182 /* use a standard prefix */
183 snprintf(prefix, sizeof(prefix), "%s_test", ste->name);
Simon Glass6685ece2025-01-20 14:25:58 -0700184 ret = cmd_ut_category(uts, ste->name, prefix, ste->start,
185 n_ents, argc, argv);
Simon Glass78fd76b2025-01-20 14:25:33 -0700186 }
187
188 return ret;
189}
190
Simon Glass6685ece2025-01-20 14:25:58 -0700191static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp,
192 int flag, int argc, char *const argv[])
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500193{
194 int i;
195 int retval;
196 int any_fail = 0;
197
Simon Glass78fd76b2025-01-20 14:25:33 -0700198 for (i = 0; i < ARRAY_SIZE(suites); i++) {
199 struct suite *ste = &suites[i];
200 char *const argv[] = {(char *)ste->name, NULL};
201
Simon Glassa3ce1292025-01-20 14:25:57 -0700202 if (has_tests(ste)) {
203 printf("----Running %s tests----\n", ste->name);
Simon Glass6685ece2025-01-20 14:25:58 -0700204 retval = run_suite(uts, ste, cmdtp, flag, 1, argv);
Simon Glassa3ce1292025-01-20 14:25:57 -0700205 if (!any_fail)
206 any_fail = retval;
207 }
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500208 }
Simon Glassfb82a042025-01-20 14:26:02 -0700209 ut_report(&uts->total, uts->run_count);
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500210
211 return any_fail;
212}
213
Simon Glassfb998c22022-10-29 19:47:12 -0600214static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc,
215 char *const argv[])
216{
Simon Glassa3ce1292025-01-20 14:25:57 -0700217 int suite_count, i;
Simon Glasscfb38f82025-01-20 14:25:30 -0700218 const char *flags;
219
Simon Glassa3ce1292025-01-20 14:25:57 -0700220 for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) {
221 struct suite *ste = &suites[i];
222
223 if (has_tests(ste))
224 suite_count++;
225 }
226
227 printf("Test suites: %d\n", suite_count);
Simon Glassfb998c22022-10-29 19:47:12 -0600228 printf("Total tests: %d\n", (int)UNIT_TEST_ALL_COUNT());
229
Simon Glasscfb38f82025-01-20 14:25:30 -0700230 flags = cmd_arg1(argc, argv);
231 if (flags && !strcmp("-s", flags)) {
232 int i;
233
234 puts("\nTests Suite\n");
235 puts("----- -----\n");
Simon Glass7d4ae012025-01-20 14:25:56 -0700236 for (i = 0; i < ARRAY_SIZE(suites); i++) {
Simon Glass78fd76b2025-01-20 14:25:33 -0700237 struct suite *ste = &suites[i];
238 long n_ent = ste->end - ste->start;
239
240 if (n_ent)
241 printf("%5ld %s\n", n_ent, ste->name);
Simon Glassa3ce1292025-01-20 14:25:57 -0700242 else if (ste->cmd)
Simon Glass78fd76b2025-01-20 14:25:33 -0700243 printf("%5s %s\n", "?", ste->name);
244 }
Simon Glasscfb38f82025-01-20 14:25:30 -0700245 }
246
Simon Glassfb998c22022-10-29 19:47:12 -0600247 return 0;
248}
249
Simon Glass78fd76b2025-01-20 14:25:33 -0700250static struct suite *find_suite(const char *name)
251{
252 struct suite *ste;
253 int i;
254
255 for (i = 0, ste = suites; i < ARRAY_SIZE(suites); i++, ste++) {
256 if (!strcmp(ste->name, name))
257 return ste;
258 }
259
260 return NULL;
261}
262
Simon Glassed38aef2020-05-10 11:40:03 -0600263static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500264{
Simon Glass6685ece2025-01-20 14:25:58 -0700265 struct unit_test_state uts;
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 Glass6685ece2025-01-20 14:25:58 -0700277 ut_init_state(&uts);
Simon Glass78fd76b2025-01-20 14:25:33 -0700278 name = argv[0];
279 if (!strcmp(name, "all")) {
Simon Glass6685ece2025-01-20 14:25:58 -0700280 ret = do_ut_all(&uts, cmdtp, flag, argc, argv);
Simon Glass78fd76b2025-01-20 14:25:33 -0700281 } else if (!strcmp(name, "info")) {
282 ret = do_ut_info(cmdtp, flag, argc, argv);
283 } else {
284 ste = find_suite(argv[0]);
285 if (!ste) {
286 printf("Suite '%s' not found\n", argv[0]);
287 return CMD_RET_FAILURE;
Simon Glassa3ce1292025-01-20 14:25:57 -0700288 } else if (!has_tests(ste)) {
289 /* perhaps a Kconfig option needs to be set? */
290 printf("Suite '%s' is not enabled\n", argv[0]);
291 return CMD_RET_FAILURE;
Simon Glass78fd76b2025-01-20 14:25:33 -0700292 }
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500293
Simon Glass6685ece2025-01-20 14:25:58 -0700294 ret = run_suite(&uts, ste, cmdtp, flag, argc, argv);
Simon Glass78fd76b2025-01-20 14:25:33 -0700295 }
296 if (ret)
297 return ret;
Simon Glass6685ece2025-01-20 14:25:58 -0700298 ut_uninit_state(&uts);
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500299
Simon Glass78fd76b2025-01-20 14:25:33 -0700300 return 0;
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500301}
302
Tom Rini03f146c2023-10-07 15:13:08 -0400303U_BOOT_LONGHELP(ut,
Simon Glass154bb8e2022-10-29 19:47:10 -0600304 "[-r] [-f] [<suite>] - run unit tests\n"
305 " -r<runs> Number of times to run each test\n"
306 " -f Force 'manual' tests to run as well\n"
307 " <suite> Test suite to run, or all\n"
308 "\n"
Simon Glassfb998c22022-10-29 19:47:12 -0600309 "\nOptions for <suite>:"
Simon Glass154bb8e2022-10-29 19:47:10 -0600310 "\nall - execute all enabled tests"
Simon Glasscfb38f82025-01-20 14:25:30 -0700311 "\ninfo [-s] - show info about tests [and suites]"
Simon Glass154bb8e2022-10-29 19:47:10 -0600312#ifdef CONFIG_CMD_ADDRMAP
313 "\naddrmap - very basic test of addrmap command"
314#endif
Marek Vasut2cd173c2023-05-31 03:03:58 +0200315#ifdef CONFIG_CMD_BDI
316 "\nbdinfo - bdinfo command"
317#endif
Heinrich Schuchardtb8b6c812018-08-31 21:31:28 +0200318#ifdef CONFIG_SANDBOX
Simon Glass154bb8e2022-10-29 19:47:10 -0600319 "\nbloblist - bloblist implementation"
Heinrich Schuchardtb8b6c812018-08-31 21:31:28 +0200320#endif
Simon Glassb255efc2022-04-24 23:31:24 -0600321#ifdef CONFIG_BOOTSTD
Simon Glass154bb8e2022-10-29 19:47:10 -0600322 "\nbootstd - standard boot implementation"
323#endif
Simon Glass621a97e2023-10-01 19:15:12 -0600324#ifdef CONFIG_CMDLINE
325 "\ncmd - test various commands"
326#endif
Simon Glass3394c3c2024-11-02 13:36:56 -0600327 "\ncommon - tests for common/ directory"
Joe Hershberger9dc1d712015-05-20 14:27:29 -0500328#ifdef CONFIG_UT_DM
Simon Glass154bb8e2022-10-29 19:47:10 -0600329 "\ndm - driver model"
Joe Hershberger9dc1d712015-05-20 14:27:29 -0500330#endif
Joe Hershberger26e038f2015-05-20 14:27:36 -0500331#ifdef CONFIG_UT_ENV
Simon Glass154bb8e2022-10-29 19:47:10 -0600332 "\nenv - environment"
Joe Hershberger26e038f2015-05-20 14:27:36 -0500333#endif
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600334#ifdef CONFIG_CMD_FDT
Simon Glass154bb8e2022-10-29 19:47:10 -0600335 "\nfdt - fdt command"
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600336#endif
Simon Glass9e972c32022-10-06 08:36:16 -0600337#ifdef CONFIG_CONSOLE_TRUETYPE
Marek Vasutef9eb6c2023-08-13 00:16:41 +0200338 "\nfont - font command"
Simon Glass154bb8e2022-10-29 19:47:10 -0600339#endif
Francis Laniel2dba91a2023-12-22 22:02:21 +0100340#if CONFIG_IS_ENABLED(HUSH_PARSER)
341 "\nhush - Test hush behavior"
342#endif
Simon Glass154bb8e2022-10-29 19:47:10 -0600343#ifdef CONFIG_CMD_LOADM
344 "\nloadm - loadm command parameters and loading memory blob"
Simon Glass9e972c32022-10-06 08:36:16 -0600345#endif
Heinrich Schuchardtf77a6352019-01-30 07:53:31 +0100346#ifdef CONFIG_UT_LIB
Simon Glass154bb8e2022-10-29 19:47:10 -0600347 "\nlib - library functions"
Heinrich Schuchardtf77a6352019-01-30 07:53:31 +0100348#endif
Heinrich Schuchardtf433d502020-02-26 21:48:18 +0100349#ifdef CONFIG_UT_LOG
Simon Glass154bb8e2022-10-29 19:47:10 -0600350 "\nlog - logging functions"
Heinrich Schuchardtf433d502020-02-26 21:48:18 +0100351#endif
Simon Glass154bb8e2022-10-29 19:47:10 -0600352 "\nmem - memory-related commands"
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200353#ifdef CONFIG_UT_OPTEE
Simon Glass154bb8e2022-10-29 19:47:10 -0600354 "\noptee - test OP-TEE"
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +0200355#endif
Maxime Ripard0e31a112016-07-05 10:26:46 +0200356#ifdef CONFIG_UT_OVERLAY
Simon Glass154bb8e2022-10-29 19:47:10 -0600357 "\noverlay - device tree overlays"
Maxime Ripard0e31a112016-07-05 10:26:46 +0200358#endif
Stephen Carlsone5c05ae2023-03-10 11:07:15 -0800359#ifdef CONFIG_CMD_PCI_MPS
360 "\npci_mps - PCI Express Maximum Payload Size"
361#endif
Simon Glass154bb8e2022-10-29 19:47:10 -0600362 "\nsetexpr - setexpr command"
Linus Walleijbef39252023-02-01 00:16:13 +0100363#ifdef CONFIG_CMD_SEAMA
364 "\nseama - seama command parameters loading and decoding"
365#endif
Tom Rini03f146c2023-10-07 15:13:08 -0400366 );
Joe Hershberger11dd7cc2015-05-20 14:27:28 -0500367
368U_BOOT_CMD(
369 ut, CONFIG_SYS_MAXARGS, 1, do_ut,
370 "unit tests", ut_help_text
371);