Tom Rini | 10e4779 | 2018-05-06 17:58:06 -0400 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 2 | /* |
| 3 | * (C) Copyright 2015 |
| 4 | * Joe Hershberger, National Instruments, joe.hershberger@ni.com |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 5 | */ |
| 6 | |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 7 | #include <command.h> |
Simon Glass | 6db8ea5 | 2020-07-28 19:41:13 -0600 | [diff] [blame] | 8 | #include <console.h> |
Tom Rini | dec7ea0 | 2024-05-20 13:35:03 -0600 | [diff] [blame] | 9 | #include <vsprintf.h> |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 10 | #include <test/suites.h> |
Simon Glass | 81cbe1c | 2017-11-25 11:57:29 -0700 | [diff] [blame] | 11 | #include <test/test.h> |
Simon Glass | 5722fb2 | 2021-03-07 17:34:47 -0700 | [diff] [blame] | 12 | #include <test/ut.h> |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 13 | |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 14 | /** |
| 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 |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 24 | * @help: Help-string to show for this suite |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 25 | */ |
| 26 | struct suite { |
| 27 | const char *name; |
| 28 | struct unit_test *start; |
| 29 | struct unit_test *end; |
| 30 | ut_cmd_func cmd; |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 31 | const char *help; |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 32 | }; |
| 33 | |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 34 | static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, |
| 35 | int flag, int argc, char *const argv[]); |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 36 | |
Simon Glass | fb998c2 | 2022-10-29 19:47:12 -0600 | [diff] [blame] | 37 | static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, |
| 38 | char *const argv[]); |
| 39 | |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 40 | int cmd_ut_category(struct unit_test_state *uts, const char *name, |
| 41 | const char *prefix, struct unit_test *tests, int n_ents, |
Simon Glass | ed38aef | 2020-05-10 11:40:03 -0600 | [diff] [blame] | 42 | int argc, char *const argv[]) |
Simon Glass | 81cbe1c | 2017-11-25 11:57:29 -0700 | [diff] [blame] | 43 | { |
Simon Glass | 85ba7c3 | 2022-10-29 19:47:13 -0600 | [diff] [blame] | 44 | const char *test_insert = NULL; |
Simon Glass | 91a187b | 2022-08-01 07:58:45 -0600 | [diff] [blame] | 45 | int runs_per_text = 1; |
Simon Glass | 1f1614b | 2022-10-20 18:22:50 -0600 | [diff] [blame] | 46 | bool force_run = false; |
Simon Glass | 5722fb2 | 2021-03-07 17:34:47 -0700 | [diff] [blame] | 47 | int ret; |
Simon Glass | 81cbe1c | 2017-11-25 11:57:29 -0700 | [diff] [blame] | 48 | |
Simon Glass | 1f1614b | 2022-10-20 18:22:50 -0600 | [diff] [blame] | 49 | while (argc > 1 && *argv[1] == '-') { |
| 50 | const char *str = argv[1]; |
| 51 | |
| 52 | switch (str[1]) { |
| 53 | case 'r': |
| 54 | runs_per_text = dectoul(str + 2, NULL); |
| 55 | break; |
| 56 | case 'f': |
| 57 | force_run = true; |
| 58 | break; |
Simon Glass | 85ba7c3 | 2022-10-29 19:47:13 -0600 | [diff] [blame] | 59 | case 'I': |
| 60 | test_insert = str + 2; |
| 61 | break; |
Simon Glass | 1f1614b | 2022-10-20 18:22:50 -0600 | [diff] [blame] | 62 | } |
Simon Glass | 91a187b | 2022-08-01 07:58:45 -0600 | [diff] [blame] | 63 | argv++; |
Simon Glass | 85ba7c3 | 2022-10-29 19:47:13 -0600 | [diff] [blame] | 64 | argc--; |
Simon Glass | 91a187b | 2022-08-01 07:58:45 -0600 | [diff] [blame] | 65 | } |
| 66 | |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 67 | ret = ut_run_list(uts, name, prefix, tests, n_ents, |
Simon Glass | 793a98e | 2023-11-18 14:05:20 -0700 | [diff] [blame] | 68 | cmd_arg1(argc, argv), runs_per_text, force_run, |
Simon Glass | 85ba7c3 | 2022-10-29 19:47:13 -0600 | [diff] [blame] | 69 | test_insert); |
Simon Glass | 81cbe1c | 2017-11-25 11:57:29 -0700 | [diff] [blame] | 70 | |
Simon Glass | 5722fb2 | 2021-03-07 17:34:47 -0700 | [diff] [blame] | 71 | return ret ? CMD_RET_FAILURE : 0; |
Simon Glass | 81cbe1c | 2017-11-25 11:57:29 -0700 | [diff] [blame] | 72 | } |
| 73 | |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 74 | /* declare linker-list symbols for the start and end of a suite */ |
| 75 | #define SUITE_DECL(_name) \ |
| 76 | ll_start_decl(suite_start_ ## _name, struct unit_test, ut_ ## _name); \ |
| 77 | ll_end_decl(suite_end_ ## _name, struct unit_test, ut_ ## _name) |
| 78 | |
| 79 | /* declare a test suite which uses a subcommand to run */ |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 80 | #define SUITE_CMD(_name, _cmd_func, _help) { \ |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 81 | #_name, \ |
| 82 | suite_start_ ## _name, \ |
| 83 | suite_end_ ## _name, \ |
| 84 | _cmd_func, \ |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 85 | _help, \ |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | /* declare a test suite which can be run directly without a subcommand */ |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 89 | #define SUITE(_name, _help) { \ |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 90 | #_name, \ |
| 91 | suite_start_ ## _name, \ |
| 92 | suite_end_ ## _name, \ |
| 93 | NULL, \ |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 94 | _help, \ |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 95 | } |
| 96 | |
Simon Glass | 4c99070 | 2025-01-20 14:26:03 -0700 | [diff] [blame] | 97 | SUITE_DECL(addrmap); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 98 | SUITE_DECL(bdinfo); |
Simon Glass | 4c99070 | 2025-01-20 14:26:03 -0700 | [diff] [blame] | 99 | SUITE_DECL(bloblist); |
| 100 | SUITE_DECL(bootm); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 101 | SUITE_DECL(bootstd); |
| 102 | SUITE_DECL(cmd); |
| 103 | SUITE_DECL(common); |
| 104 | SUITE_DECL(dm); |
| 105 | SUITE_DECL(env); |
| 106 | SUITE_DECL(exit); |
| 107 | SUITE_DECL(fdt); |
Simon Glass | 04e76d5 | 2025-02-07 11:30:39 -0700 | [diff] [blame^] | 108 | SUITE_DECL(fdt_overlay); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 109 | SUITE_DECL(font); |
Simon Glass | 4c99070 | 2025-01-20 14:26:03 -0700 | [diff] [blame] | 110 | SUITE_DECL(hush); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 111 | SUITE_DECL(lib); |
Simon Glass | 4c99070 | 2025-01-20 14:26:03 -0700 | [diff] [blame] | 112 | SUITE_DECL(loadm); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 113 | SUITE_DECL(log); |
| 114 | SUITE_DECL(mbr); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 115 | SUITE_DECL(measurement); |
Simon Glass | 4c99070 | 2025-01-20 14:26:03 -0700 | [diff] [blame] | 116 | SUITE_DECL(mem); |
| 117 | SUITE_DECL(optee); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 118 | SUITE_DECL(pci_mps); |
| 119 | SUITE_DECL(seama); |
Simon Glass | 4c99070 | 2025-01-20 14:26:03 -0700 | [diff] [blame] | 120 | SUITE_DECL(setexpr); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 121 | SUITE_DECL(upl); |
| 122 | |
| 123 | static struct suite suites[] = { |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 124 | SUITE(addrmap, "very basic test of addrmap command"), |
| 125 | SUITE(bdinfo, "bdinfo (board info) command"), |
| 126 | SUITE(bloblist, "bloblist implementation"), |
| 127 | SUITE(bootm, "bootm command"), |
Simon Glass | 804aa37 | 2023-10-01 19:15:15 -0600 | [diff] [blame] | 128 | #ifdef CONFIG_UT_BOOTSTD |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 129 | SUITE_CMD(bootstd, do_ut_bootstd, "standard boot implementation"), |
Simon Glass | b255efc | 2022-04-24 23:31:24 -0600 | [diff] [blame] | 130 | #endif |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 131 | SUITE(cmd, "various commands"), |
| 132 | SUITE(common, "tests for common/ directory"), |
| 133 | SUITE(dm, "driver model"), |
| 134 | SUITE(env, "environment"), |
| 135 | SUITE(exit, "shell exit and variables"), |
| 136 | SUITE(fdt, "fdt command"), |
Simon Glass | 04e76d5 | 2025-02-07 11:30:39 -0700 | [diff] [blame^] | 137 | #ifdef CONFIG_UT_FDT_OVERLAY |
| 138 | SUITE_CMD(fdt_overlay, do_ut_fdt_overlay, "device tree overlays"), |
| 139 | #endif |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 140 | SUITE(font, "font command"), |
| 141 | SUITE(hush, "hush behaviour"), |
| 142 | SUITE(lib, "library functions"), |
| 143 | SUITE(loadm, "loadm command parameters and loading memory blob"), |
| 144 | SUITE(log, "logging functions"), |
| 145 | SUITE(mbr, "mbr command"), |
| 146 | SUITE(measurement, "TPM-based measured boot"), |
| 147 | SUITE(mem, "memory-related commands"), |
Heiko Stuebner | 1c9bb9b | 2019-10-23 16:46:41 +0200 | [diff] [blame] | 148 | #ifdef CONFIG_UT_OPTEE |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 149 | SUITE_CMD(optee, do_ut_optee, "OP-TEE"), |
Heiko Stuebner | 1c9bb9b | 2019-10-23 16:46:41 +0200 | [diff] [blame] | 150 | #endif |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 151 | SUITE(pci_mps, "PCI Express Maximum Payload Size"), |
| 152 | SUITE(seama, "seama command parameters loading and decoding"), |
| 153 | SUITE(setexpr, "setexpr command"), |
| 154 | SUITE(upl, "Universal payload support"), |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 155 | }; |
| 156 | |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 157 | /** |
| 158 | * has_tests() - Check if a suite has tests, i.e. is supported in this build |
| 159 | * |
| 160 | * If the suite is run using a command, we have to assume that tests may be |
| 161 | * present, since we have no visibility |
| 162 | * |
| 163 | * @ste: Suite to check |
| 164 | * Return: true if supported, false if not |
| 165 | */ |
| 166 | static bool has_tests(struct suite *ste) |
| 167 | { |
| 168 | int n_ents = ste->end - ste->start; |
| 169 | |
| 170 | return n_ents || ste->cmd; |
| 171 | } |
| 172 | |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 173 | /** run_suite() - Run a suite of tests */ |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 174 | static int run_suite(struct unit_test_state *uts, struct suite *ste, |
| 175 | struct cmd_tbl *cmdtp, int flag, int argc, |
| 176 | char *const argv[]) |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 177 | { |
| 178 | int ret; |
| 179 | |
| 180 | if (ste->cmd) { |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 181 | ret = ste->cmd(uts, cmdtp, flag, argc, argv); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 182 | } else { |
| 183 | int n_ents = ste->end - ste->start; |
| 184 | char prefix[30]; |
| 185 | |
| 186 | /* use a standard prefix */ |
Simon Glass | 598a1a5 | 2025-02-07 11:30:37 -0700 | [diff] [blame] | 187 | snprintf(prefix, sizeof(prefix), "%s_test_", ste->name); |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 188 | ret = cmd_ut_category(uts, ste->name, prefix, ste->start, |
| 189 | n_ents, argc, argv); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | return ret; |
| 193 | } |
| 194 | |
Simon Glass | bd9b151 | 2025-02-07 11:30:36 -0700 | [diff] [blame] | 195 | static void show_stats(struct unit_test_state *uts) |
| 196 | { |
| 197 | if (uts->run_count < 2) |
| 198 | return; |
| 199 | |
| 200 | ut_report(&uts->total, uts->run_count); |
| 201 | if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION) && |
| 202 | uts->total.test_count && uts->worst) { |
| 203 | ulong avg = uts->total.duration_ms / uts->total.test_count; |
| 204 | |
| 205 | printf("Average test time: %ld ms, worst case '%s' took %d ms\n", |
| 206 | avg, uts->worst->name, uts->worst_ms); |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | static void update_stats(struct unit_test_state *uts, const struct suite *ste) |
| 211 | { |
| 212 | if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION) && uts->cur.test_count) { |
| 213 | ulong avg; |
| 214 | |
| 215 | avg = uts->cur.duration_ms ? |
| 216 | uts->cur.duration_ms / |
| 217 | uts->cur.test_count : 0; |
| 218 | if (avg > uts->worst_ms) { |
| 219 | uts->worst_ms = avg; |
| 220 | uts->worst = ste; |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 225 | static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, |
| 226 | int flag, int argc, char *const argv[]) |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 227 | { |
| 228 | int i; |
| 229 | int retval; |
| 230 | int any_fail = 0; |
| 231 | |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 232 | for (i = 0; i < ARRAY_SIZE(suites); i++) { |
| 233 | struct suite *ste = &suites[i]; |
| 234 | char *const argv[] = {(char *)ste->name, NULL}; |
| 235 | |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 236 | if (has_tests(ste)) { |
| 237 | printf("----Running %s tests----\n", ste->name); |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 238 | retval = run_suite(uts, ste, cmdtp, flag, 1, argv); |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 239 | if (!any_fail) |
| 240 | any_fail = retval; |
Simon Glass | bd9b151 | 2025-02-07 11:30:36 -0700 | [diff] [blame] | 241 | update_stats(uts, ste); |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 242 | } |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 243 | } |
Simon Glass | fb82a04 | 2025-01-20 14:26:02 -0700 | [diff] [blame] | 244 | ut_report(&uts->total, uts->run_count); |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 245 | |
| 246 | return any_fail; |
| 247 | } |
| 248 | |
Simon Glass | fb998c2 | 2022-10-29 19:47:12 -0600 | [diff] [blame] | 249 | static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, |
| 250 | char *const argv[]) |
| 251 | { |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 252 | int suite_count, i; |
Simon Glass | cfb38f8 | 2025-01-20 14:25:30 -0700 | [diff] [blame] | 253 | const char *flags; |
| 254 | |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 255 | for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) { |
| 256 | struct suite *ste = &suites[i]; |
| 257 | |
| 258 | if (has_tests(ste)) |
| 259 | suite_count++; |
| 260 | } |
| 261 | |
| 262 | printf("Test suites: %d\n", suite_count); |
Simon Glass | fb998c2 | 2022-10-29 19:47:12 -0600 | [diff] [blame] | 263 | printf("Total tests: %d\n", (int)UNIT_TEST_ALL_COUNT()); |
| 264 | |
Simon Glass | cfb38f8 | 2025-01-20 14:25:30 -0700 | [diff] [blame] | 265 | flags = cmd_arg1(argc, argv); |
| 266 | if (flags && !strcmp("-s", flags)) { |
Simon Glass | 3669a97 | 2025-02-07 11:30:34 -0700 | [diff] [blame] | 267 | int i, total; |
Simon Glass | cfb38f8 | 2025-01-20 14:25:30 -0700 | [diff] [blame] | 268 | |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 269 | puts("\nTests Suite Purpose"); |
| 270 | puts("\n----- ------------ -------------------------\n"); |
Simon Glass | 3669a97 | 2025-02-07 11:30:34 -0700 | [diff] [blame] | 271 | for (i = 0, total = 0; i < ARRAY_SIZE(suites); i++) { |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 272 | struct suite *ste = &suites[i]; |
| 273 | long n_ent = ste->end - ste->start; |
| 274 | |
| 275 | if (n_ent) |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 276 | printf("%5ld", n_ent); |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 277 | else if (ste->cmd) |
Simon Glass | 46093b3 | 2025-01-20 14:26:05 -0700 | [diff] [blame] | 278 | printf("%5s", "?"); |
| 279 | else /* suite is not present */ |
| 280 | continue; |
| 281 | printf(" %-13.13s %s\n", ste->name, ste->help); |
Simon Glass | 3669a97 | 2025-02-07 11:30:34 -0700 | [diff] [blame] | 282 | total += n_ent; |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 283 | } |
Simon Glass | 3669a97 | 2025-02-07 11:30:34 -0700 | [diff] [blame] | 284 | puts("----- ------------ -------------------------\n"); |
| 285 | printf("%5d %-13.13s\n", total, "Total"); |
| 286 | |
| 287 | if (UNIT_TEST_ALL_COUNT() != total) |
| 288 | puts("Error: Suite test-count does not match total\n"); |
Simon Glass | cfb38f8 | 2025-01-20 14:25:30 -0700 | [diff] [blame] | 289 | } |
| 290 | |
Simon Glass | fb998c2 | 2022-10-29 19:47:12 -0600 | [diff] [blame] | 291 | return 0; |
| 292 | } |
| 293 | |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 294 | static struct suite *find_suite(const char *name) |
| 295 | { |
| 296 | struct suite *ste; |
| 297 | int i; |
| 298 | |
| 299 | for (i = 0, ste = suites; i < ARRAY_SIZE(suites); i++, ste++) { |
| 300 | if (!strcmp(ste->name, name)) |
| 301 | return ste; |
| 302 | } |
| 303 | |
| 304 | return NULL; |
| 305 | } |
| 306 | |
Simon Glass | ed38aef | 2020-05-10 11:40:03 -0600 | [diff] [blame] | 307 | static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 308 | { |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 309 | struct unit_test_state uts; |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 310 | struct suite *ste; |
| 311 | const char *name; |
| 312 | int ret; |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 313 | |
| 314 | if (argc < 2) |
| 315 | return CMD_RET_USAGE; |
| 316 | |
| 317 | /* drop initial "ut" arg */ |
| 318 | argc--; |
| 319 | argv++; |
| 320 | |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 321 | ut_init_state(&uts); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 322 | name = argv[0]; |
| 323 | if (!strcmp(name, "all")) { |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 324 | ret = do_ut_all(&uts, cmdtp, flag, argc, argv); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 325 | } else if (!strcmp(name, "info")) { |
| 326 | ret = do_ut_info(cmdtp, flag, argc, argv); |
| 327 | } else { |
| 328 | ste = find_suite(argv[0]); |
| 329 | if (!ste) { |
| 330 | printf("Suite '%s' not found\n", argv[0]); |
| 331 | return CMD_RET_FAILURE; |
Simon Glass | a3ce129 | 2025-01-20 14:25:57 -0700 | [diff] [blame] | 332 | } else if (!has_tests(ste)) { |
| 333 | /* perhaps a Kconfig option needs to be set? */ |
| 334 | printf("Suite '%s' is not enabled\n", argv[0]); |
| 335 | return CMD_RET_FAILURE; |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 336 | } |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 337 | |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 338 | ret = run_suite(&uts, ste, cmdtp, flag, argc, argv); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 339 | } |
Simon Glass | bd9b151 | 2025-02-07 11:30:36 -0700 | [diff] [blame] | 340 | show_stats(&uts); |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 341 | if (ret) |
| 342 | return ret; |
Simon Glass | 6685ece | 2025-01-20 14:25:58 -0700 | [diff] [blame] | 343 | ut_uninit_state(&uts); |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 344 | |
Simon Glass | 78fd76b | 2025-01-20 14:25:33 -0700 | [diff] [blame] | 345 | return 0; |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 346 | } |
| 347 | |
Tom Rini | 03f146c | 2023-10-07 15:13:08 -0400 | [diff] [blame] | 348 | U_BOOT_LONGHELP(ut, |
Simon Glass | 154bb8e | 2022-10-29 19:47:10 -0600 | [diff] [blame] | 349 | "[-r] [-f] [<suite>] - run unit tests\n" |
| 350 | " -r<runs> Number of times to run each test\n" |
| 351 | " -f Force 'manual' tests to run as well\n" |
| 352 | " <suite> Test suite to run, or all\n" |
| 353 | "\n" |
Simon Glass | fb998c2 | 2022-10-29 19:47:12 -0600 | [diff] [blame] | 354 | "\nOptions for <suite>:" |
Simon Glass | 154bb8e | 2022-10-29 19:47:10 -0600 | [diff] [blame] | 355 | "\nall - execute all enabled tests" |
Simon Glass | cfb38f8 | 2025-01-20 14:25:30 -0700 | [diff] [blame] | 356 | "\ninfo [-s] - show info about tests [and suites]" |
Tom Rini | 03f146c | 2023-10-07 15:13:08 -0400 | [diff] [blame] | 357 | ); |
Joe Hershberger | 11dd7cc | 2015-05-20 14:27:28 -0500 | [diff] [blame] | 358 | |
| 359 | U_BOOT_CMD( |
| 360 | ut, CONFIG_SYS_MAXARGS, 1, do_ut, |
| 361 | "unit tests", ut_help_text |
| 362 | ); |