diff options
Diffstat (limited to 'test/cmd_ut.c')
-rw-r--r-- | test/cmd_ut.c | 243 |
1 files changed, 129 insertions, 114 deletions
diff --git a/test/cmd_ut.c b/test/cmd_ut.c index fbfdaaae0b5..44e5fdfdaa6 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -7,7 +7,6 @@ #include <command.h> #include <console.h> #include <vsprintf.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> @@ -20,77 +19,31 @@ * @name: Name of suite * @start: First test in suite * @end: End test in suite (points to the first test in the next suite) - * @cmd: Command to use to run the suite * @help: Help-string to show for this suite */ struct suite { const char *name; struct unit_test *start; struct unit_test *end; - ut_cmd_func cmd; const char *help; }; -static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, - int flag, int argc, char *const argv[]); +static int do_ut_all(struct unit_test_state *uts, const char *select_name, + int runs_per_test, bool force_run, + const char *test_insert); -static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]); - -int cmd_ut_category(struct unit_test_state *uts, const char *name, - const char *prefix, struct unit_test *tests, int n_ents, - int argc, char *const argv[]) -{ - const char *test_insert = NULL; - int runs_per_text = 1; - bool force_run = false; - int ret; - - while (argc > 1 && *argv[1] == '-') { - const char *str = argv[1]; - - switch (str[1]) { - case 'r': - runs_per_text = dectoul(str + 2, NULL); - break; - case 'f': - force_run = true; - break; - case 'I': - test_insert = str + 2; - break; - } - argv++; - argc--; - } - - ret = ut_run_list(uts, name, prefix, tests, n_ents, - cmd_arg1(argc, argv), runs_per_text, force_run, - test_insert); - - return ret ? CMD_RET_FAILURE : 0; -} +static int do_ut_info(bool show_suites); /* declare linker-list symbols for the start and end of a suite */ #define SUITE_DECL(_name) \ ll_start_decl(suite_start_ ## _name, struct unit_test, ut_ ## _name); \ ll_end_decl(suite_end_ ## _name, struct unit_test, ut_ ## _name) -/* declare a test suite which uses a subcommand to run */ -#define SUITE_CMD(_name, _cmd_func, _help) { \ - #_name, \ - suite_start_ ## _name, \ - suite_end_ ## _name, \ - _cmd_func, \ - _help, \ - } - /* declare a test suite which can be run directly without a subcommand */ #define SUITE(_name, _help) { \ #_name, \ suite_start_ ## _name, \ suite_end_ ## _name, \ - NULL, \ _help, \ } @@ -105,6 +58,7 @@ SUITE_DECL(dm); SUITE_DECL(env); SUITE_DECL(exit); SUITE_DECL(fdt); +SUITE_DECL(fdt_overlay); SUITE_DECL(font); SUITE_DECL(hush); SUITE_DECL(lib); @@ -114,7 +68,6 @@ SUITE_DECL(mbr); SUITE_DECL(measurement); SUITE_DECL(mem); SUITE_DECL(optee); -SUITE_DECL(overlay); SUITE_DECL(pci_mps); SUITE_DECL(seama); SUITE_DECL(setexpr); @@ -125,15 +78,14 @@ static struct suite suites[] = { SUITE(bdinfo, "bdinfo (board info) command"), SUITE(bloblist, "bloblist implementation"), SUITE(bootm, "bootm command"), -#ifdef CONFIG_UT_BOOTSTD - SUITE_CMD(bootstd, do_ut_bootstd, "standard boot implementation"), -#endif + SUITE(bootstd, "standard boot implementation"), SUITE(cmd, "various commands"), SUITE(common, "tests for common/ directory"), SUITE(dm, "driver model"), SUITE(env, "environment"), SUITE(exit, "shell exit and variables"), SUITE(fdt, "fdt command"), + SUITE(fdt_overlay, "device tree overlays"), SUITE(font, "font command"), SUITE(hush, "hush behaviour"), SUITE(lib, "library functions"), @@ -142,12 +94,7 @@ static struct suite suites[] = { SUITE(mbr, "mbr command"), SUITE(measurement, "TPM-based measured boot"), SUITE(mem, "memory-related commands"), -#ifdef CONFIG_UT_OPTEE - SUITE_CMD(optee, do_ut_optee, "OP-TEE"), -#endif -#ifdef CONFIG_UT_OVERLAY - SUITE_CMD(overlay, do_ut_overlay, "device tree overlays"), -#endif + SUITE(optee, "OP-TEE"), SUITE(pci_mps, "PCI Express Maximum Payload Size"), SUITE(seama, "seama command parameters loading and decoding"), SUITE(setexpr, "setexpr command"), @@ -167,33 +114,59 @@ static bool has_tests(struct suite *ste) { int n_ents = ste->end - ste->start; - return n_ents || ste->cmd; + return n_ents; } /** run_suite() - Run a suite of tests */ static int run_suite(struct unit_test_state *uts, struct suite *ste, - struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) + const char *select_name, int runs_per_test, bool force_run, + const char *test_insert) { + int n_ents = ste->end - ste->start; + char prefix[30]; int ret; - if (ste->cmd) { - ret = ste->cmd(uts, cmdtp, flag, argc, argv); - } else { - int n_ents = ste->end - ste->start; - char prefix[30]; + /* use a standard prefix */ + snprintf(prefix, sizeof(prefix), "%s_test_", ste->name); - /* use a standard prefix */ - snprintf(prefix, sizeof(prefix), "%s_test", ste->name); - ret = cmd_ut_category(uts, ste->name, prefix, ste->start, - n_ents, argc, argv); - } + ret = ut_run_list(uts, ste->name, prefix, ste->start, n_ents, + select_name, runs_per_test, force_run, test_insert); return ret; } -static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, - int flag, int argc, char *const argv[]) +static void show_stats(struct unit_test_state *uts) +{ + if (uts->run_count < 2) + return; + + ut_report(&uts->total, uts->run_count); + if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION) && + uts->total.test_count && uts->worst) { + ulong avg = uts->total.duration_ms / uts->total.test_count; + + printf("Average test time: %ld ms, worst case '%s' took %d ms\n", + avg, uts->worst->name, uts->worst_ms); + } +} + +static void update_stats(struct unit_test_state *uts, const struct suite *ste) +{ + if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION) && uts->cur.test_count) { + ulong avg; + + avg = uts->cur.duration_ms ? + uts->cur.duration_ms / + uts->cur.test_count : 0; + if (avg > uts->worst_ms) { + uts->worst_ms = avg; + uts->worst = ste; + } + } +} + +static int do_ut_all(struct unit_test_state *uts, const char *select_name, + int runs_per_test, bool force_run, const char *test_insert) { int i; int retval; @@ -201,25 +174,23 @@ static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, for (i = 0; i < ARRAY_SIZE(suites); i++) { struct suite *ste = &suites[i]; - char *const argv[] = {(char *)ste->name, NULL}; if (has_tests(ste)) { printf("----Running %s tests----\n", ste->name); - retval = run_suite(uts, ste, cmdtp, flag, 1, argv); + retval = run_suite(uts, ste, select_name, runs_per_test, + force_run, test_insert); if (!any_fail) any_fail = retval; + update_stats(uts, ste); } } - ut_report(&uts->total, uts->run_count); return any_fail; } -static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int do_ut_info(bool show_suites) { int suite_count, i; - const char *flags; for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) { struct suite *ste = &suites[i]; @@ -231,24 +202,26 @@ static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, printf("Test suites: %d\n", suite_count); printf("Total tests: %d\n", (int)UNIT_TEST_ALL_COUNT()); - flags = cmd_arg1(argc, argv); - if (flags && !strcmp("-s", flags)) { - int i; + if (show_suites) { + int i, total; puts("\nTests Suite Purpose"); puts("\n----- ------------ -------------------------\n"); - for (i = 0; i < ARRAY_SIZE(suites); i++) { + for (i = 0, total = 0; i < ARRAY_SIZE(suites); i++) { struct suite *ste = &suites[i]; long n_ent = ste->end - ste->start; - if (n_ent) - printf("%5ld", n_ent); - else if (ste->cmd) - printf("%5s", "?"); - else /* suite is not present */ - continue; - printf(" %-13.13s %s\n", ste->name, ste->help); + if (n_ent) { + printf("%5ld %-13.13s %s\n", n_ent, ste->name, + ste->help); + total += n_ent; + } } + puts("----- ------------ -------------------------\n"); + printf("%5d %-13.13s\n", total, "Total"); + + if (UNIT_TEST_ALL_COUNT() != total) + puts("Error: Suite test-count does not match total\n"); } return 0; @@ -269,37 +242,77 @@ static struct suite *find_suite(const char *name) static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + const char *test_insert = NULL, *select_name; struct unit_test_state uts; + bool show_suites = false; + bool force_run = false; + int runs_per_text = 1; struct suite *ste; - const char *name; + char *name; int ret; - if (argc < 2) - return CMD_RET_USAGE; - /* drop initial "ut" arg */ argc--; argv++; + while (argc > 0 && *argv[0] == '-') { + const char *str = argv[0]; + + switch (str[1]) { + case 'r': + runs_per_text = dectoul(str + 2, NULL); + break; + case 'f': + force_run = true; + break; + case 'I': + test_insert = str + 2; + if (!strchr(test_insert, ':')) + return CMD_RET_USAGE; + break; + case 's': + show_suites = true; + break; + } + argv++; + argc--; + } + + if (argc < 1) + return CMD_RET_USAGE; + ut_init_state(&uts); name = argv[0]; + select_name = cmd_arg1(argc, argv); if (!strcmp(name, "all")) { - ret = do_ut_all(&uts, cmdtp, flag, argc, argv); + ret = do_ut_all(&uts, select_name, runs_per_text, force_run, + test_insert); } else if (!strcmp(name, "info")) { - ret = do_ut_info(cmdtp, flag, argc, argv); + ret = do_ut_info(show_suites); } else { - ste = find_suite(argv[0]); - if (!ste) { - printf("Suite '%s' not found\n", argv[0]); - return CMD_RET_FAILURE; - } else if (!has_tests(ste)) { - /* perhaps a Kconfig option needs to be set? */ - printf("Suite '%s' is not enabled\n", argv[0]); - return CMD_RET_FAILURE; + int any_fail = 0; + const char *p; + + for (; p = strsep(&name, ","), p; name = NULL) { + ste = find_suite(p); + if (!ste) { + printf("Suite '%s' not found\n", p); + return CMD_RET_FAILURE; + } else if (!has_tests(ste)) { + /* perhaps a Kconfig option needs to be set? */ + printf("Suite '%s' is not enabled\n", p); + return CMD_RET_FAILURE; + } + + ret = run_suite(&uts, ste, select_name, runs_per_text, + force_run, test_insert); + if (!any_fail) + any_fail = ret; + update_stats(&uts, ste); } - - ret = run_suite(&uts, ste, cmdtp, flag, argc, argv); + ret = any_fail; } + show_stats(&uts); if (ret) return ret; ut_uninit_state(&uts); @@ -308,14 +321,16 @@ static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } U_BOOT_LONGHELP(ut, - "[-r] [-f] [<suite>] - run unit tests\n" + "[-rs] [-f] [-I<n>:<one_test>][<suites>] - run unit tests\n" " -r<runs> Number of times to run each test\n" " -f Force 'manual' tests to run as well\n" - " <suite> Test suite to run, or all\n" + " -I Test to run after <n> other tests have run\n" + " -s Show all suites with ut info\n" + " <suites> Comma-separated list of suites to run\n" "\n" - "\nOptions for <suite>:" - "\nall - execute all enabled tests" - "\ninfo [-s] - show info about tests [and suites]" + "Options for <suite>:\n" + "all - execute all enabled tests\n" + "info - show info about tests [and suites]" ); U_BOOT_CMD( |