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