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