"Das U-Boot" Source Tree
at master 324 lines 7.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * (C) Copyright 2015 4 * Joe Hershberger, National Instruments, joe.hershberger@ni.com 5 */ 6 7#include <command.h> 8#include <console.h> 9#include <vsprintf.h> 10#include <test/suites.h> 11#include <test/test.h> 12#include <test/ut.h> 13 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 24 * @help: Help-string to show for this suite 25 */ 26struct suite { 27 const char *name; 28 struct unit_test *start; 29 struct unit_test *end; 30 ut_cmd_func cmd; 31 const char *help; 32}; 33 34static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, 35 int flag, int argc, char *const argv[]); 36 37static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, 38 char *const argv[]); 39 40int cmd_ut_category(struct unit_test_state *uts, const char *name, 41 const char *prefix, struct unit_test *tests, int n_ents, 42 int argc, char *const argv[]) 43{ 44 const char *test_insert = NULL; 45 int runs_per_text = 1; 46 bool force_run = false; 47 int ret; 48 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; 59 case 'I': 60 test_insert = str + 2; 61 break; 62 } 63 argv++; 64 argc--; 65 } 66 67 ret = ut_run_list(uts, name, prefix, tests, n_ents, 68 cmd_arg1(argc, argv), runs_per_text, force_run, 69 test_insert); 70 71 return ret ? CMD_RET_FAILURE : 0; 72} 73 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 */ 80#define SUITE_CMD(_name, _cmd_func, _help) { \ 81 #_name, \ 82 suite_start_ ## _name, \ 83 suite_end_ ## _name, \ 84 _cmd_func, \ 85 _help, \ 86 } 87 88/* declare a test suite which can be run directly without a subcommand */ 89#define SUITE(_name, _help) { \ 90 #_name, \ 91 suite_start_ ## _name, \ 92 suite_end_ ## _name, \ 93 NULL, \ 94 _help, \ 95 } 96 97SUITE_DECL(addrmap); 98SUITE_DECL(bdinfo); 99SUITE_DECL(bloblist); 100SUITE_DECL(bootm); 101SUITE_DECL(bootstd); 102SUITE_DECL(cmd); 103SUITE_DECL(common); 104SUITE_DECL(dm); 105SUITE_DECL(env); 106SUITE_DECL(exit); 107SUITE_DECL(fdt); 108SUITE_DECL(font); 109SUITE_DECL(hush); 110SUITE_DECL(lib); 111SUITE_DECL(loadm); 112SUITE_DECL(log); 113SUITE_DECL(mbr); 114SUITE_DECL(measurement); 115SUITE_DECL(mem); 116SUITE_DECL(optee); 117SUITE_DECL(overlay); 118SUITE_DECL(pci_mps); 119SUITE_DECL(seama); 120SUITE_DECL(setexpr); 121SUITE_DECL(upl); 122 123static struct suite suites[] = { 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"), 128#ifdef CONFIG_UT_BOOTSTD 129 SUITE_CMD(bootstd, do_ut_bootstd, "standard boot implementation"), 130#endif 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"), 137 SUITE(font, "font command"), 138 SUITE(hush, "hush behaviour"), 139 SUITE(lib, "library functions"), 140 SUITE(loadm, "loadm command parameters and loading memory blob"), 141 SUITE(log, "logging functions"), 142 SUITE(mbr, "mbr command"), 143 SUITE(measurement, "TPM-based measured boot"), 144 SUITE(mem, "memory-related commands"), 145#ifdef CONFIG_UT_OPTEE 146 SUITE_CMD(optee, do_ut_optee, "OP-TEE"), 147#endif 148#ifdef CONFIG_UT_OVERLAY 149 SUITE_CMD(overlay, do_ut_overlay, "device tree overlays"), 150#endif 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"), 155}; 156 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 */ 166static bool has_tests(struct suite *ste) 167{ 168 int n_ents = ste->end - ste->start; 169 170 return n_ents || ste->cmd; 171} 172 173/** run_suite() - Run a suite of tests */ 174static int run_suite(struct unit_test_state *uts, struct suite *ste, 175 struct cmd_tbl *cmdtp, int flag, int argc, 176 char *const argv[]) 177{ 178 int ret; 179 180 if (ste->cmd) { 181 ret = ste->cmd(uts, cmdtp, flag, argc, argv); 182 } else { 183 int n_ents = ste->end - ste->start; 184 char prefix[30]; 185 186 /* use a standard prefix */ 187 snprintf(prefix, sizeof(prefix), "%s_test", ste->name); 188 ret = cmd_ut_category(uts, ste->name, prefix, ste->start, 189 n_ents, argc, argv); 190 } 191 192 return ret; 193} 194 195static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, 196 int flag, int argc, char *const argv[]) 197{ 198 int i; 199 int retval; 200 int any_fail = 0; 201 202 for (i = 0; i < ARRAY_SIZE(suites); i++) { 203 struct suite *ste = &suites[i]; 204 char *const argv[] = {(char *)ste->name, NULL}; 205 206 if (has_tests(ste)) { 207 printf("----Running %s tests----\n", ste->name); 208 retval = run_suite(uts, ste, cmdtp, flag, 1, argv); 209 if (!any_fail) 210 any_fail = retval; 211 } 212 } 213 ut_report(&uts->total, uts->run_count); 214 215 return any_fail; 216} 217 218static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, 219 char *const argv[]) 220{ 221 int suite_count, i; 222 const char *flags; 223 224 for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) { 225 struct suite *ste = &suites[i]; 226 227 if (has_tests(ste)) 228 suite_count++; 229 } 230 231 printf("Test suites: %d\n", suite_count); 232 printf("Total tests: %d\n", (int)UNIT_TEST_ALL_COUNT()); 233 234 flags = cmd_arg1(argc, argv); 235 if (flags && !strcmp("-s", flags)) { 236 int i; 237 238 puts("\nTests Suite Purpose"); 239 puts("\n----- ------------ -------------------------\n"); 240 for (i = 0; i < ARRAY_SIZE(suites); i++) { 241 struct suite *ste = &suites[i]; 242 long n_ent = ste->end - ste->start; 243 244 if (n_ent) 245 printf("%5ld", n_ent); 246 else if (ste->cmd) 247 printf("%5s", "?"); 248 else /* suite is not present */ 249 continue; 250 printf(" %-13.13s %s\n", ste->name, ste->help); 251 } 252 } 253 254 return 0; 255} 256 257static struct suite *find_suite(const char *name) 258{ 259 struct suite *ste; 260 int i; 261 262 for (i = 0, ste = suites; i < ARRAY_SIZE(suites); i++, ste++) { 263 if (!strcmp(ste->name, name)) 264 return ste; 265 } 266 267 return NULL; 268} 269 270static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 271{ 272 struct unit_test_state uts; 273 struct suite *ste; 274 const char *name; 275 int ret; 276 277 if (argc < 2) 278 return CMD_RET_USAGE; 279 280 /* drop initial "ut" arg */ 281 argc--; 282 argv++; 283 284 ut_init_state(&uts); 285 name = argv[0]; 286 if (!strcmp(name, "all")) { 287 ret = do_ut_all(&uts, cmdtp, flag, argc, argv); 288 } else if (!strcmp(name, "info")) { 289 ret = do_ut_info(cmdtp, flag, argc, argv); 290 } else { 291 ste = find_suite(argv[0]); 292 if (!ste) { 293 printf("Suite '%s' not found\n", argv[0]); 294 return CMD_RET_FAILURE; 295 } else if (!has_tests(ste)) { 296 /* perhaps a Kconfig option needs to be set? */ 297 printf("Suite '%s' is not enabled\n", argv[0]); 298 return CMD_RET_FAILURE; 299 } 300 301 ret = run_suite(&uts, ste, cmdtp, flag, argc, argv); 302 } 303 if (ret) 304 return ret; 305 ut_uninit_state(&uts); 306 307 return 0; 308} 309 310U_BOOT_LONGHELP(ut, 311 "[-r] [-f] [<suite>] - run unit tests\n" 312 " -r<runs> Number of times to run each test\n" 313 " -f Force 'manual' tests to run as well\n" 314 " <suite> Test suite to run, or all\n" 315 "\n" 316 "\nOptions for <suite>:" 317 "\nall - execute all enabled tests" 318 "\ninfo [-s] - show info about tests [and suites]" 319 ); 320 321U_BOOT_CMD( 322 ut, CONFIG_SYS_MAXARGS, 1, do_ut, 323 "unit tests", ut_help_text 324);