diff options
author | Tom Rini <trini@konsulko.com> | 2025-02-13 09:52:16 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-02-13 09:53:31 -0600 |
commit | f60d1163c1fe2dd409ba1af9368715c9237e567d (patch) | |
tree | 71ba35988854f486fb5270cc1dd4dddf9e3c2979 | |
parent | 87dec3078a0a36d2e6da7602b9a750010c2d111d (diff) | |
parent | 404cdf0cdaacfa8595f8ec268709612d48335f01 (diff) |
Merge patch series "test: Complete the suite migration"
Simon Glass <sjg@chromium.org> says:
This series completes the removal of test commands for suites. With this
it is possible to declare a suite (including init and uninit functions)
without needing to write a command.
It also adds timing for test suites, so we can keep track of how long
things take.
Link: https://lore.kernel.org/all/20250207183121.117663-1-sjg@chromium.org/
55 files changed, 587 insertions, 499 deletions
@@ -893,9 +893,6 @@ ifdef CONFIG_POST libs-y += post/ endif libs-$(CONFIG_$(PHASE_)UNIT_TEST) += test/ -libs-$(CONFIG_UT_ENV) += test/env/ -libs-$(CONFIG_UT_OPTEE) += test/optee/ -libs-$(CONFIG_UT_OVERLAY) += test/overlay/ libs-y += $(if $(wildcard $(srctree)/board/$(BOARDDIR)/Makefile),board/$(BOARDDIR)/) diff --git a/doc/develop/tests_writing.rst b/doc/develop/tests_writing.rst index 54efb7e1b04..5f3c43d5da2 100644 --- a/doc/develop/tests_writing.rst +++ b/doc/develop/tests_writing.rst @@ -261,7 +261,7 @@ with the suite. For example, to add a new mem_search test:: /* Test 'ms' command with 32-bit values */ static int mem_test_ms_new_thing(struct unit_test_state *uts) { - /* test code here*/ + /* test code here */ return 0; } @@ -291,32 +291,20 @@ suite. For example:: /* Declare a new wibble test */ #define WIBBLE_TEST(_name, _flags) UNIT_TEST(_name, _flags, wibble_test) - /* Tetss go here */ - - /* At the bottom of the file: */ - - int do_ut_wibble(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) - { - struct unit_test *tests = UNIT_TEST_SUITE_START(wibble_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(wibble_test); - - return cmd_ut_category("cmd_wibble", "wibble_test_", tests, n_ents, argc, argv); - } + /* Tests go here */ Then add new tests to it as above. Register this new suite in test/cmd_ut.c by adding to cmd_ut_sub[]:: - /* Within cmd_ut_sub[]... */ - - U_BOOT_CMD_MKENT(wibble, CONFIG_SYS_MAXARGS, 1, do_ut_wibble, "", ""), + /* with the other SUITE_DECL() declarations */ + SUITE_DECL(wibble); -and adding new help to ut_help_text[]:: + /* Within suites[]... */ + SUITE(wibble, "my test of wibbles"); - "ut wibble - Test the wibble feature\n" - -If your feature is conditional on a particular Kconfig, then you can use #ifdef -to control that. +If your feature is conditional on a particular Kconfig, you do not need to add +an #ifdef since the suite will automatically be compiled out in that case. Finally, add the test to the build by adding to the Makefile in the same directory:: @@ -326,17 +314,35 @@ directory:: Note that CMDLINE is never enabled in SPL, so this test will only be present in U-Boot proper. See below for how to do SPL tests. -As before, you can add an extra Kconfig check if needed:: +You can add an extra Kconfig check if needed:: ifneq ($(CONFIG_$(XPL_)WIBBLE),) obj-$(CONFIG_$(XPL_)CMDLINE) += wibble.o endif +Each suite can have an optional init and uninit function. These are run before +and after any suite tests, respectively:: + + #define WIBBLE_TEST_INIT(_name, _flags) UNIT_TEST_INIT(_name, _flags, wibble_test) + #define WIBBLE_TEST_UNINIT(_name, _flags) UNIT_TEST_UNINIT(_name, _flags, wibble_test) -Example commit: 919e7a8fb64 ("test: Add a simple test for bloblist") [1] + static int wibble_test_init(struct unit_test_state *uts) + { + /* init code here */ + + return 0; + } + WIBBLE_TEST_INIT(wibble_test_init, 0); -[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/919e7a8fb64 + static int wibble_test_uninit(struct unit_test_state *uts) + { + /* uninit code here */ + + return 0; + } + WIBBLE_TEST_INIT(wibble_test_uninit, 0); +Both functions are included in the totals for each suite. Making the test run from pytest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/usage/cmd/ut.rst b/doc/usage/cmd/ut.rst index e794922c806..1acf3126680 100644 --- a/doc/usage/cmd/ut.rst +++ b/doc/usage/cmd/ut.rst @@ -11,34 +11,44 @@ Synopsis :: - ut [-r<runs>] [-fs] [-I<n>:<one_test>] [<suite> [<test>]] - - <runs> Number of times to run each test - -f Force 'manual' tests to run as well - <n> Run <one test> after <n> other tests have run - <one_test> Name of the 'one' test to run - <suite> Test suite to run, or `all` - <test> Name of single test to run + ut [-r<runs>] [-f] [-I<n>:<one_test>] [-r<n>] [<suite> | 'all' [<test>]] + ut [-s] info Description ----------- The ut command runs unit tests written in C. +suite + Specifies the suite to run, This can be a single suite, or a comma-separated + list + +test + Speciifes a particular test to run, within a suite, or all suites + +-f + Forces running of a manual test. + +-r <n> + Specifies the number of types to run each test + +-I <n>:<one_test> + Test to run after <n> other tests have run. This is used to find which test + causes another test to fail. If the one test fails, testing stops + immediately. + Typically the command is run on :ref:`arch/sandbox/sandbox:sandbox` since it includes a near-complete set of emulators, no code-size limits, many CONFIG options enabled and runs easily in CI without needing QEMU. It is also possible to run some tests on real boards. -For a list of available test suites, type `ut info -s`. - Each test is normally run once, although those marked with `UTF_DM` are run with livetree and flattree where possible. To run a test more than once, use the `-r` flag. Manual tests are normally skipped by this command. Use `-f` to run them. See -See :ref:`develop/tests_writing:mixing python and c` for more information on -manual test. +:ref:`develop/tests_writing:mixing python and c` for more information on manual +tests. When running unit tests, some may have side effects which cause a subsequent test to break. This can sometimes be seen when using 'ut dm' or similar. To @@ -50,9 +60,22 @@ the problem. Generally all tests in the suite are run. To run just a single test from the suite, provide the <test> argument. +To specify a list of suites to run, <suites> can also be a comma-separated list. + See :ref:`develop/tests_writing:writing c tests` for more information on how to write unit tests. +ut all +~~~~~~ + +Instead of a suite name 'all' may be used to run all tests. + +ut info +~~~~~~~ + +This provides information about the total number of suites and tests. Use the +`-s` flag to show a detailed list of suites. + Example ------- @@ -97,26 +120,84 @@ List available unit-test suites:: Run one of the suites:: - => ut bloblist - Running 14 bloblist tests - Test: bloblist_test_align: bloblist.c - Test: bloblist_test_bad_blob: bloblist.c - Test: bloblist_test_blob: bloblist.c - Test: bloblist_test_blob_ensure: bloblist.c - Test: bloblist_test_blob_maxsize: bloblist.c - Test: bloblist_test_checksum: bloblist.c - Test: bloblist_test_cmd_info: bloblist.c - Test: bloblist_test_cmd_list: bloblist.c - Test: bloblist_test_grow: bloblist.c - Test: bloblist_test_init: bloblist.c - Test: bloblist_test_reloc: bloblist.c - Test: bloblist_test_resize_fail: bloblist.c - Test: bloblist_test_resize_last: bloblist.c - Test: bloblist_test_shrink: bloblist.c - Failures: 0 + => ut common + Running 14 common tests + Test: cli_ch_test: cread.c + Test: cread_test: cread.c + Test: dm_test_cyclic_running: cyclic.c + Test: print_display_buffer: print.c + Test: print_do_hex_dump: print.c + Test: print_efi_ut: print.c + Test: print_guid: print.c + Test: print_hexdump_line: print.c + Test: print_printf: print.c + Test: snprint: print.c + Test: test_autoboot: test_autoboot.c + Enter password "a" in 1 seconds to stop autoboot + Enter password "a" in 1 seconds to stop autoboot + Enter password "a" in 1 seconds to stop autoboot + Enter password "a" in 1 seconds to stop autoboot + Enter password "a" in 1 seconds to stop autoboot + Enter password "a" in 1 seconds to stop autoboot + Autoboot password unlock not successful + Test: test_event_base: event.c + Test: test_event_probe: event.c + Test: test_event_probe: event.c (flat tree) + Test: test_event_simple: event.c + Tests run: 14, 2611 ms, average 186 ms, skipped: 2, failures: 0 Run just a single test in a suite:: - => ut bloblist bloblist_test_grow - Test: bloblist_test_grow: bloblist.c - Failures: 0 + => ut fdt_overlay change_int_property + Test: fdt_overlay_init: cmd_ut_fdt_overlay.c + Test: change_int_property: cmd_ut_fdt_overlay.c + Tests run: 2, 0 ms, average 0 ms, failures: 0 + +Run a selection of three suites:: + + => ut bloblist,mem,fdt_overlay + Running 14 bloblist tests + Test: align: bloblist.c + Test: bad_blob: bloblist.c + Test: blob: bloblist.c + Test: blob_ensure: bloblist.c + Test: blob_maxsize: bloblist.c + Test: checksum: bloblist.c + Test: cmd_info: bloblist.c + Test: cmd_list: bloblist.c + Test: grow: bloblist.c + Test: init: bloblist.c + Test: reloc: bloblist.c + Test: resize_fail: bloblist.c + Test: resize_last: bloblist.c + Test: shrink: bloblist.c + Tests run: 14, 1 ms, average: 0 ms, failures: 0 + Running 13 mem tests + Test: cp_b: mem_copy.c + Test: cp_l: mem_copy.c + Test: cp_q: mem_copy.c + Test: cp_w: mem_copy.c + Test: ms_b: mem_search.c + Test: ms_cont: mem_search.c + Test: ms_cont_end: mem_search.c + Test: ms_l: mem_search.c + Test: ms_limit: mem_search.c + Test: ms_mult: mem_search.c + Test: ms_quiet: mem_search.c + Test: ms_s: mem_search.c + Test: ms_w: mem_search.c + Tests run: 13, 13 ms, average: 1 ms, failures: 0 + Running 10 fdt_overlay tests + Test: fdt_overlay_init: cmd_ut_fdt_overlay.c + Test: add_node_by_path: cmd_ut_fdt_overlay.c + Test: add_node_by_phandle: cmd_ut_fdt_overlay.c + Test: add_str_property: cmd_ut_fdt_overlay.c + Test: add_subnode_property: cmd_ut_fdt_overlay.c + Test: change_int_property: cmd_ut_fdt_overlay.c + Test: change_str_property: cmd_ut_fdt_overlay.c + Test: local_phandle: cmd_ut_fdt_overlay.c + Test: local_phandles: cmd_ut_fdt_overlay.c + Test: stacked: cmd_ut_fdt_overlay.c + Tests run: 10, 12 ms, average: 1 ms, failures: 0 + Suites run: 3, total tests run: 37, 26 ms, average: 0 ms, failures: 0 + Average test time: 0 ms, worst case 'mem' took 1 ms diff --git a/drivers/timer/sandbox_timer.c b/drivers/timer/sandbox_timer.c index e8b54a02965..c1baf3c69ec 100644 --- a/drivers/timer/sandbox_timer.c +++ b/drivers/timer/sandbox_timer.c @@ -18,6 +18,11 @@ void timer_test_add_offset(unsigned long offset) sandbox_timer_offset += offset; } +ulong timer_test_get_offset(void) +{ + return sandbox_timer_offset; +}; + u64 notrace timer_early_get_count(void) { return os_get_nsec() / 1000 + sandbox_timer_offset * 1000; diff --git a/include/test/fdt_overlay.h b/include/test/fdt_overlay.h new file mode 100644 index 00000000000..251ad0ec97a --- /dev/null +++ b/include/test/fdt_overlay.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2016 NextThing Co + * Copyright (c) 2016 Free Electrons + */ + +#ifndef __TEST_OVERLAY_H__ +#define __TEST_OVERLAY_H__ + +#include <test/test.h> + +/* Declare a new FDT-overlay test */ +#define FDT_OVERLAY_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_overlay) + +/* Declare init for FDT-overlay test */ +#define FDT_OVERLAY_TEST_INIT(_name, _flags) \ + UNIT_TEST_INIT(_name, _flags, fdt_overlay) + +#endif /* __TEST_OVERLAY_H__ */ diff --git a/include/test/optee.h b/include/test/optee.h index f4255b39ee3..0a548a59e83 100644 --- a/include/test/optee.h +++ b/include/test/optee.h @@ -8,7 +8,9 @@ #include <test/test.h> -/* Declare a new environment test */ +/* Declare a new optee test */ #define OPTEE_TEST(_name, _flags) UNIT_TEST(_name, _flags, optee) +#define OPTEE_TEST_INIT(_name, _flags) UNIT_TEST_INIT(_name, _flags, optee) +#define OPTEE_TEST_UNINIT(_name, _flags) UNIT_TEST_UNINIT(_name, _flags, optee) #endif /* __TEST_OPTEE_H__ */ diff --git a/include/test/overlay.h b/include/test/overlay.h deleted file mode 100644 index 5dc98399ce7..00000000000 --- a/include/test/overlay.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2016 NextThing Co - * Copyright (c) 2016 Free Electrons - */ - -#ifndef __TEST_OVERLAY_H__ -#define __TEST_OVERLAY_H__ - -#include <test/test.h> - -/* Declare a new environment test */ -#define OVERLAY_TEST(_name, _flags) UNIT_TEST(_name, _flags, overlay) - -#endif /* __TEST_OVERLAY_H__ */ diff --git a/include/test/suites.h b/include/test/suites.h deleted file mode 100644 index 774dd893378..00000000000 --- a/include/test/suites.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * (C) Copyright 2015 - * Joe Hershberger, National Instruments, joe.hershberger@ni.com - */ - -#ifndef __TEST_SUITES_H__ -#define __TEST_SUITES_H__ - -struct cmd_tbl; -struct unit_test; -struct unit_test_state; - -/* 'command' functions normally called do_xxx where xxx is the command name */ -typedef int (*ut_cmd_func)(struct unit_test_state *uts, struct cmd_tbl *cmd, - int flags, int argc, char *const argv[]); - -/** - * cmd_ut_category() - Run a category of unit tests - * - * @uts: Unit-test state, which must be ready for use, i.e. ut_init_state() - * has been called. The caller is responsible for calling - * ut_uninit_state() after this function returns - * @name: Category name - * @prefix: Prefix of test name - * @tests: List of tests to run - * @n_ents: Number of tests in @tests - * @argc: Argument count provided. Must be >= 1. If this is 1 then all - * tests are run, otherwise only the one named @argv[1] is run. - * @argv: Arguments: argv[1] is the test to run (if @argc >= 2) - * Return: 0 if OK, CMD_RET_FAILURE on failure - */ -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[]); - -int do_ut_bootstd(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag, - int argc, char *const argv[]); -int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); -int do_ut_overlay(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag, - int argc, char *const argv[]); - -#endif /* __TEST_SUITES_H__ */ diff --git a/include/test/test.h b/include/test/test.h index bac43c81d63..0f2b68a5dee 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -16,11 +16,15 @@ * @skip_count: Number of tests that were skipped * @test_count: Number of tests run. If a test is run muiltiple times, only one * is counted + * @start: Timer value when test started + * @duration_ms: Suite duration in milliseconds */ struct ut_stats { int fail_count; int skip_count; int test_count; + ulong start; + ulong duration_ms; }; /* @@ -29,6 +33,8 @@ struct ut_stats { * @cur: Statistics for the current run * @total: Statistics for all test runs * @run_count: Number of times ut_run_list() has been called + * @worst: Sute which had the first per-text run time + * @worst_ms: Time taken by that test * @start: Store the starting mallinfo when doing leak test * @of_live: true to use livetree if available, false to use flattree * @of_root: Record of the livetree root node (used for setting up tests) @@ -52,6 +58,8 @@ struct unit_test_state { struct ut_stats cur; struct ut_stats total; int run_count; + const struct suite *worst; + int worst_ms; struct mallinfo start; struct device_node *of_root; bool of_live; @@ -92,6 +100,8 @@ enum ut_flags { UTF_ETH_BOOTDEV = BIT(9), /* enable Ethernet bootdevs */ UTF_SF_BOOTDEV = BIT(10), /* enable SPI flash bootdevs */ UFT_BLOBLIST = BIT(11), /* test changes gd->bloblist */ + UTF_INIT = BIT(12), /* test inits a suite */ + UTF_UNINIT = BIT(13), /* test uninits a suite */ }; /** @@ -139,6 +149,24 @@ struct unit_test { .func = _name, \ } +/* init function for unit-test suite (the 'A' makes it first) */ +#define UNIT_TEST_INIT(_name, _flags, _suite) \ + ll_entry_declare(struct unit_test, A ## _name, ut_ ## _suite) = { \ + .file = __FILE__, \ + .name = #_name, \ + .flags = (_flags) | UTF_INIT, \ + .func = _name, \ + } + +/* uninit function for unit-test suite (the 'aaa' makes it last) */ +#define UNIT_TEST_UNINIT(_name, _flags, _suite) \ + ll_entry_declare(struct unit_test, zzz ## _name, ut_ ## _suite) = { \ + .file = __FILE__, \ + .name = #_name, \ + .flags = (_flags) | UTF_UNINIT, \ + .func = _name, \ + } + /* Get the start of a list of unit tests for a particular suite */ #define UNIT_TEST_SUITE_START(_suite) \ ll_entry_start(struct unit_test, ut_ ## _suite) diff --git a/include/time.h b/include/time.h index 3b2ba091247..f5b86bf70fe 100644 --- a/include/time.h +++ b/include/time.h @@ -28,7 +28,7 @@ uint64_t get_timer_us(uint64_t base); */ unsigned long get_timer_us_long(unsigned long base); -/* +/** * timer_test_add_offset() * * Allow tests to add to the time reported through lib/time.c functions @@ -36,6 +36,19 @@ unsigned long get_timer_us_long(unsigned long base); */ void timer_test_add_offset(unsigned long offset); +#ifdef CONFIG_SANDBOX +/** + * timer_test_get_offset() + * + * Get the total offset currently being added the time + * + * Return:: number of milliseconds the system time has been advanced + */ +ulong timer_test_get_offset(void); +#else +static inline ulong timer_test_get_offset(void) { return 0; } +#endif + /** * usec_to_tick() - convert microseconds to clock ticks * diff --git a/test/Kconfig b/test/Kconfig index 558a9cd49b4..31016eedbf8 100644 --- a/test/Kconfig +++ b/test/Kconfig @@ -20,9 +20,18 @@ config SPL_UNIT_TEST of-platdata and SPL handover. To run these tests with the sandbox_spl board, use the -u (unit test) option. +if UNIT_TEST + +config UNIT_TEST_DURATION + bool "Report unit-test duration" + default y + help + Enable this short the time taken by each test suite. This is reported + after the suite runs, alongside the pass/fail results. In addition, + an overall total is reported if multiple suites are run. + config UT_LIB bool "Unit tests for library functions" - depends on UNIT_TEST default y if !SANDBOX_VPL help Enables the 'ut lib' command which tests library functions like @@ -63,16 +72,15 @@ config UT_LIB_RSA Enables rsa_verify() test, currently rsa_verify_with_pkey only() only, at the 'ut lib' command. -endif +endif # UT_LIB config UT_BOOTSTD bool "Unit tests for standard boot" - depends on UNIT_TEST && BOOTSTD && SANDBOX + depends on BOOTSTD && SANDBOX default y config UT_COMPRESSION bool "Unit test for compression" - depends on UNIT_TEST depends on CMDLINE && GZIP_COMPRESSED && BZIP2 && LZMA && LZO && LZ4 && ZSTD default y help @@ -81,7 +89,6 @@ config UT_COMPRESSION config UT_LOG bool "Unit tests for logging functions" - depends on UNIT_TEST default y help Enables the 'ut log' command which tests logging functions like @@ -90,7 +97,6 @@ config UT_LOG config UT_TIME bool "Unit tests for time functions" - depends on UNIT_TEST help Enables the 'ut time' command which tests that the time functions work correctly. The test is fairly simple and will not catch all @@ -99,7 +105,6 @@ config UT_TIME config UT_UNICODE bool "Unit tests for Unicode functions" - depends on UNIT_TEST default y select CHARSET help @@ -111,7 +116,9 @@ source "test/env/Kconfig" source "test/image/Kconfig" source "test/lib/Kconfig" source "test/optee/Kconfig" -source "test/overlay/Kconfig" +source "test/fdt_overlay/Kconfig" + +endif # UNIT_TEST config POST bool "Power On Self Test support" diff --git a/test/Makefile b/test/Makefile index 47a07d653a9..99d4797d968 100644 --- a/test/Makefile +++ b/test/Makefile @@ -14,11 +14,14 @@ endif ifneq ($(CONFIG_HUSH_PARSER),) obj-$(CONFIG_$(XPL_)CMDLINE) += hush/ endif +obj-$(CONFIG_UT_OPTEE) += optee/ obj-y += ut.o ifeq ($(CONFIG_XPL_BUILD),) obj-y += boot/ obj-$(CONFIG_UNIT_TEST) += common/ +obj-$(CONFIG_UT_ENV) += env/ +obj-$(CONFIG_UT_FDT_OVERLAY) += fdt_overlay/ obj-y += log/ else obj-$(CONFIG_SPL_UT_LOAD) += image/ diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c index 8c44afd9297..5f07430714e 100644 --- a/test/boot/bootdev.c +++ b/test/boot/bootdev.c @@ -12,7 +12,6 @@ #include <bootflow.h> #include <mapmem.h> #include <os.h> -#include <test/suites.h> #include <test/ut.h> #include "bootstd_common.h" diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index a8735c1c23d..eb7f00af39a 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -21,7 +21,6 @@ #endif #include <dm/device-internal.h> #include <dm/lists.h> -#include <test/suites.h> #include <test/ut.h> #include "bootstd_common.h" #include "../../boot/bootflow_internal.h" diff --git a/test/boot/bootm.c b/test/boot/bootm.c index 7e0ccb0e23f..1d1efe71ad5 100644 --- a/test/boot/bootm.c +++ b/test/boot/bootm.c @@ -7,7 +7,6 @@ #include <bootm.h> #include <asm/global_data.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c index 18ae6d7fe13..577f259fb37 100644 --- a/test/boot/bootmeth.c +++ b/test/boot/bootmeth.c @@ -9,7 +9,6 @@ #include <bootmeth.h> #include <bootstd.h> #include <dm.h> -#include <test/suites.h> #include <test/ut.h> #include "bootstd_common.h" diff --git a/test/boot/bootstd_common.c b/test/boot/bootstd_common.c index 724e3d9bdd2..052c0fe5cc6 100644 --- a/test/boot/bootstd_common.c +++ b/test/boot/bootstd_common.c @@ -13,7 +13,6 @@ #include <mmc.h> #include <usb.h> #include <linux/log2.h> -#include <test/suites.h> #include <test/ut.h> #include <u-boot/crc.h> #include "bootstd_common.h" @@ -21,8 +20,14 @@ /* tracks whether bootstd_setup_for_tests() has been run yet */ bool vbe_setup_done; -/* set up MMC for VBE tests */ -int bootstd_setup_for_tests(void) +/** + * bootstd_setup_for_tests() - Set up MMC data for VBE tests + * + * Some data is needed for VBE tests to work. This function sets that up. + * + * @return 0 if OK, -ve on error + */ +static int bootstd_setup_for_tests(struct unit_test_state *uts) { ALLOC_CACHE_ALIGN_BUFFER(u8, buf, MMC_MAX_BLOCK_LEN); struct udevice *mmc; @@ -55,6 +60,7 @@ int bootstd_setup_for_tests(void) return 0; } +BOOTSTD_TEST_INIT(bootstd_setup_for_tests, 0); int bootstd_test_drop_bootdev_order(struct unit_test_state *uts) { @@ -93,20 +99,3 @@ void bootstd_reset_usb(void) { usb_started = false; } - -int do_ut_bootstd(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag, - int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(bootstd); - const int n_ents = UNIT_TEST_SUITE_COUNT(bootstd); - int ret; - - ret = bootstd_setup_for_tests(); - if (ret) { - printf("Failed to set up for bootstd tests (err=%d)\n", ret); - return CMD_RET_FAILURE; - } - - return cmd_ut_category(uts, "bootstd", "bootstd_", - tests, n_ents, argc, argv); -} diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h index ea3ecd1166c..c61698adc02 100644 --- a/test/boot/bootstd_common.h +++ b/test/boot/bootstd_common.h @@ -13,6 +13,7 @@ /* Declare a new bootdev test */ #define BOOTSTD_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootstd) +#define BOOTSTD_TEST_INIT(_name, _flags) UNIT_TEST_INIT(_name, _flags, bootstd) #define NVDATA_START_BLK ((0x400 + 0x400) / MMC_MAX_BLOCK_LEN) #define VERSION_START_BLK ((0x400 + 0x800) / MMC_MAX_BLOCK_LEN) @@ -36,15 +37,6 @@ struct unit_test_state; int bootstd_test_drop_bootdev_order(struct unit_test_state *uts); /** - * bootstd_setup_for_tests() - Set up MMC data for VBE tests - * - * Some data is needed for VBE tests to work. This function sets that up. - * - * @return 0 if OK, -ve on error - */ -int bootstd_setup_for_tests(void); - -/** * bootstd_test_check_mmc_hunter() - Check that the mmc bootdev hunter was used * * @uts: Unit test state to use for ut_assert...() functions diff --git a/test/boot/expo.c b/test/boot/expo.c index db14ff86f8b..1d283a2ac95 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -10,7 +10,6 @@ #include <menu.h> #include <video.h> #include <linux/input.h> -#include <test/suites.h> #include <test/ut.h> #include "bootstd_common.h" #include <test/cedit-test.h> diff --git a/test/boot/image.c b/test/boot/image.c index 0894e30587f..4df7b17ce88 100644 --- a/test/boot/image.c +++ b/test/boot/image.c @@ -7,7 +7,6 @@ */ #include <image.h> -#include <test/suites.h> #include <test/ut.h> #include "bootstd_common.h" diff --git a/test/boot/measurement.c b/test/boot/measurement.c index 5a49c7a6b23..1d38663fc0f 100644 --- a/test/boot/measurement.c +++ b/test/boot/measurement.c @@ -8,7 +8,6 @@ #include <bootm.h> #include <malloc.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> #include <asm/io.h> diff --git a/test/boot/upl.c b/test/boot/upl.c index aa58cdf083b..eec89026fc3 100644 --- a/test/boot/upl.c +++ b/test/boot/upl.c @@ -10,7 +10,6 @@ #include <mapmem.h> #include <upl.h> #include <dm/ofnode.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> #include "bootstd_common.h" diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c index 4fe4323b401..c37de627c52 100644 --- a/test/boot/vbe_simple.c +++ b/test/boot/vbe_simple.c @@ -11,7 +11,6 @@ #include <image.h> #include <of_live.h> #include <vbe.h> -#include <test/suites.h> #include <test/ut.h> #include "bootstd_common.h" @@ -33,9 +32,6 @@ static int vbe_simple_test_base(struct unit_test_state *uts) ofnode node; u32 vernum; - /* Set up the VBE info */ - ut_assertok(bootstd_setup_for_tests()); - /* Read the version back */ ut_assertok(vbe_find_by_any("firmware0", &dev)); ut_assertok(bootmeth_get_state_desc(dev, info, sizeof(info))); diff --git a/test/cmd/addrmap.c b/test/cmd/addrmap.c index 1f2deb15052..72798b96edd 100644 --- a/test/cmd/addrmap.c +++ b/test/cmd/addrmap.c @@ -6,7 +6,6 @@ */ #include <console.h> -#include <test/suites.h> #include <test/ut.h> /* Declare a new addrmap test */ diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 7408c271a30..09f44ee41ed 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -10,7 +10,6 @@ #include <mapmem.h> #include <asm/global_data.h> #include <dm/uclass.h> -#include <test/suites.h> #include <test/ut.h> #include <dm.h> #include <env.h> diff --git a/test/cmd/exit.c b/test/cmd/exit.c index 71c37edcdf6..fdde054b928 100644 --- a/test/cmd/exit.c +++ b/test/cmd/exit.c @@ -8,7 +8,6 @@ #include <console.h> #include <mapmem.h> #include <asm/global_data.h> -#include <test/suites.h> #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c index ab6dbd45e54..c11c181c807 100644 --- a/test/cmd/fdt.c +++ b/test/cmd/fdt.c @@ -10,7 +10,6 @@ #include <mapmem.h> #include <asm/global_data.h> #include <linux/libfdt.h> -#include <test/suites.h> #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/test/cmd/font.c b/test/cmd/font.c index af88d1b5459..7ae648d7395 100644 --- a/test/cmd/font.c +++ b/test/cmd/font.c @@ -8,7 +8,6 @@ #include <console.h> #include <dm.h> #include <video_console.h> -#include <test/suites.h> #include <test/ut.h> /* Declare a new fdt test */ diff --git a/test/cmd/loadm.c b/test/cmd/loadm.c index 3c623aa655f..043cd25dfb6 100644 --- a/test/cmd/loadm.c +++ b/test/cmd/loadm.c @@ -13,7 +13,6 @@ #include <mapmem.h> #include <asm/global_data.h> #include <dm/test.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> diff --git a/test/cmd/mbr.c b/test/cmd/mbr.c index 45bab04923a..e651256a4cb 100644 --- a/test/cmd/mbr.c +++ b/test/cmd/mbr.c @@ -15,7 +15,6 @@ #include <dm/device-internal.h> #include <dm/lists.h> #include <linux/sizes.h> -#include <test/suites.h> #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/test/cmd/pci_mps.c b/test/cmd/pci_mps.c index 8b3ea4a6134..6618c247d13 100644 --- a/test/cmd/pci_mps.c +++ b/test/cmd/pci_mps.c @@ -8,7 +8,6 @@ */ #include <console.h> -#include <test/suites.h> #include <test/ut.h> #define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps) diff --git a/test/cmd/seama.c b/test/cmd/seama.c index 1edc3fcac5a..39f85f1c502 100644 --- a/test/cmd/seama.c +++ b/test/cmd/seama.c @@ -7,7 +7,6 @@ #include <command.h> #include <dm.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index 5e9b577fe36..85803eb54b8 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -9,7 +9,6 @@ #include <console.h> #include <mapmem.h> #include <dm/test.h> -#include <test/suites.h> #include <test/ut.h> #define BUF_SIZE 0x100 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( diff --git a/test/common/bloblist.c b/test/common/bloblist.c index ab8f41c6808..797bde27025 100644 --- a/test/common/bloblist.c +++ b/test/common/bloblist.c @@ -6,7 +6,6 @@ #include <bloblist.h> #include <log.h> #include <mapmem.h> -#include <test/suites.h> #include <test/test.h> #include <test/ut.h> diff --git a/test/dm/Kconfig b/test/dm/Kconfig index e5b341e523a..640421c2a79 100644 --- a/test/dm/Kconfig +++ b/test/dm/Kconfig @@ -1,6 +1,6 @@ config UT_DM bool "Enable driver model unit test command" - depends on SANDBOX && UNIT_TEST + depends on SANDBOX help This enables the 'ut dm' command which runs a series of unit tests on the driver model code. Each subsystem (uclass) is tested. diff --git a/test/dm/mux-cmd.c b/test/dm/mux-cmd.c index 6eb3b283161..bd02cda84db 100644 --- a/test/dm/mux-cmd.c +++ b/test/dm/mux-cmd.c @@ -26,8 +26,6 @@ static int dm_test_cmd_mux_list(struct unit_test_state *uts) int i; unsigned long val; - sandbox_set_enable_memio(true); - ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller", &dev)); chip = dev_get_uclass_priv(dev); @@ -119,8 +117,6 @@ static int dm_test_cmd_mux_select(struct unit_test_state *uts) char cmd[BUF_SIZE]; unsigned int i, state; - sandbox_set_enable_memio(true); - ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller", &dev)); chip = dev_get_uclass_priv(dev); @@ -153,8 +149,6 @@ static int dm_test_cmd_mux_deselect(struct unit_test_state *uts) char cmd[BUF_SIZE]; unsigned int i, state; - sandbox_set_enable_memio(true); - ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller", &dev)); chip = dev_get_uclass_priv(dev); diff --git a/test/env/Kconfig b/test/env/Kconfig index 6cb82337b36..21d88f47a6d 100644 --- a/test/env/Kconfig +++ b/test/env/Kconfig @@ -1,6 +1,5 @@ config UT_ENV bool "Enable env unit tests" - depends on UNIT_TEST default y help This enables the 'ut env' command which runs a series of unit diff --git a/test/env/cmd_ut_env.c b/test/env/cmd_ut_env.c index 81d1bb2f80d..43f1b7d1cef 100644 --- a/test/env/cmd_ut_env.c +++ b/test/env/cmd_ut_env.c @@ -5,7 +5,6 @@ */ #include <test/env.h> -#include <test/suites.h> #include <test/ut.h> static int env_test_env_cmd(struct unit_test_state *uts) diff --git a/test/overlay/Kconfig b/test/fdt_overlay/Kconfig index 881848968bb..c50b8822544 100644 --- a/test/overlay/Kconfig +++ b/test/fdt_overlay/Kconfig @@ -1,6 +1,6 @@ -config UT_OVERLAY +config UT_FDT_OVERLAY bool "Enable Device Tree Overlays Unit Tests" - depends on UNIT_TEST && OF_CONTROL && SANDBOX + depends on OF_CONTROL && SANDBOX default y select OF_LIBFDT_OVERLAY help diff --git a/test/overlay/Makefile b/test/fdt_overlay/Makefile index 47937e3c108..5625c0d8885 100644 --- a/test/overlay/Makefile +++ b/test/fdt_overlay/Makefile @@ -4,7 +4,7 @@ # Copyright (c) 2016 Free Electrons # Test files -obj-y += cmd_ut_overlay.o +obj-y += cmd_ut_fdt_overlay.o DTC_FLAGS += -@ diff --git a/test/overlay/cmd_ut_overlay.c b/test/fdt_overlay/cmd_ut_fdt_overlay.c index aefa147ec04..0084033b6ca 100644 --- a/test/overlay/cmd_ut_overlay.c +++ b/test/fdt_overlay/cmd_ut_fdt_overlay.c @@ -6,6 +6,7 @@ #include <command.h> #include <errno.h> +#include <fdtdec.h> #include <fdt_support.h> #include <image.h> #include <log.h> @@ -13,9 +14,8 @@ #include <linux/sizes.h> +#include <test/fdt_overlay.h> #include <test/ut.h> -#include <test/overlay.h> -#include <test/suites.h> /* 4k ought to be enough for anybody */ #define FDT_COPY_SIZE (4 * SZ_1K) @@ -26,32 +26,61 @@ extern u32 __dtbo_test_fdt_overlay_stacked_begin; static void *fdt; -static int ut_fdt_getprop_u32_by_index(void *fdt, const char *path, - const char *name, int index, - u32 *out) +static int fdt_overlay_init(struct unit_test_state *uts) { - const fdt32_t *val; - int node_off; - int len; + void *fdt_base = &__dtb_test_fdt_base_begin; + void *fdt_overlay = &__dtbo_test_fdt_overlay_begin; + void *fdt_overlay_stacked = &__dtbo_test_fdt_overlay_stacked_begin; + void *fdt_overlay_copy, *fdt_overlay_stacked_copy; - node_off = fdt_path_offset(fdt, path); - if (node_off < 0) - return node_off; + ut_assertok(fdt_check_header(fdt_base)); + ut_assertok(fdt_check_header(fdt_overlay)); - val = fdt_getprop(fdt, node_off, name, &len); - if (!val || (len < (sizeof(uint32_t) * (index + 1)))) - return -FDT_ERR_NOTFOUND; + fdt = malloc(FDT_COPY_SIZE); + fdt_overlay_copy = malloc(FDT_COPY_SIZE); + fdt_overlay_stacked_copy = malloc(FDT_COPY_SIZE); + ut_assertnonnull(fdt); + ut_assertnonnull(fdt_overlay_copy); + ut_assertnonnull(fdt_overlay_stacked_copy); - *out = fdt32_to_cpu(*(val + index)); + /* + * Resize the FDT to 4k so that we have room to operate on + * + * (and relocate it since the memory might be mapped + * read-only) + */ + ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE)); - return 0; -} + /* + * Resize the overlay to 4k so that we have room to operate on + * + * (and relocate it since the memory might be mapped + * read-only) + */ + ut_assertok(fdt_open_into(fdt_overlay, fdt_overlay_copy, + FDT_COPY_SIZE)); -static int ut_fdt_getprop_u32(void *fdt, const char *path, const char *name, - u32 *out) -{ - return ut_fdt_getprop_u32_by_index(fdt, path, name, 0, out); + /* + * Resize the stacked overlay to 4k so that we have room to operate on + * + * (and relocate it since the memory might be mapped + * read-only) + */ + ut_assertok(fdt_open_into(fdt_overlay_stacked, fdt_overlay_stacked_copy, + FDT_COPY_SIZE)); + + /* Apply the overlay */ + ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_copy)); + + /* Apply the stacked overlay */ + ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_stacked_copy)); + + free(fdt_overlay_stacked_copy); + free(fdt_overlay_copy); + + return 0; } +FDT_OVERLAY_TEST_INIT(fdt_overlay_init, 0); static int fdt_getprop_str(void *fdt, const char *path, const char *name, const char **out) @@ -68,19 +97,20 @@ static int fdt_getprop_str(void *fdt, const char *path, const char *name, return len < 0 ? len : 0; } -static int fdt_overlay_change_int_property(struct unit_test_state *uts) +static int fdt_overlay_test_change_int_property(struct unit_test_state *uts) { - u32 val = 0; + int off; - ut_assertok(ut_fdt_getprop_u32(fdt, "/test-node", "test-int-property", - &val)); - ut_asserteq(43, val); + off = fdt_path_offset(fdt, "/test-node"); + ut_assert(off >= 0); + + ut_asserteq(43, fdtdec_get_uint(fdt, off, "test-int-property", 0)); return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_change_int_property, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_change_int_property, 0); -static int fdt_overlay_change_str_property(struct unit_test_state *uts) +static int fdt_overlay_test_change_str_property(struct unit_test_state *uts) { const char *val = NULL; @@ -90,9 +120,9 @@ static int fdt_overlay_change_str_property(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_change_str_property, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_change_str_property, 0); -static int fdt_overlay_add_str_property(struct unit_test_state *uts) +static int fdt_overlay_test_add_str_property(struct unit_test_state *uts) { const char *val = NULL; @@ -102,9 +132,9 @@ static int fdt_overlay_add_str_property(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_add_str_property, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_add_str_property, 0); -static int fdt_overlay_add_node_by_phandle(struct unit_test_state *uts) +static int fdt_overlay_test_add_node_by_phandle(struct unit_test_state *uts) { int off; @@ -115,9 +145,9 @@ static int fdt_overlay_add_node_by_phandle(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_add_node_by_phandle, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_add_node_by_phandle, 0); -static int fdt_overlay_add_node_by_path(struct unit_test_state *uts) +static int fdt_overlay_test_add_node_by_path(struct unit_test_state *uts) { int off; @@ -128,9 +158,9 @@ static int fdt_overlay_add_node_by_path(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_add_node_by_path, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_add_node_by_path, 0); -static int fdt_overlay_add_subnode_property(struct unit_test_state *uts) +static int fdt_overlay_test_add_subnode_property(struct unit_test_state *uts) { int off; @@ -142,12 +172,12 @@ static int fdt_overlay_add_subnode_property(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_add_subnode_property, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_add_subnode_property, 0); -static int fdt_overlay_local_phandle(struct unit_test_state *uts) +static int fdt_overlay_test_local_phandle(struct unit_test_state *uts) { uint32_t local_phandle; - u32 val = 0; + u32 val[2]; int off; off = fdt_path_offset(fdt, "/new-local-node"); @@ -156,22 +186,19 @@ static int fdt_overlay_local_phandle(struct unit_test_state *uts) local_phandle = fdt_get_phandle(fdt, off); ut_assert(local_phandle); - ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle", - 0, &val)); - ut_asserteq(local_phandle, val); - - ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle", - 1, &val)); - ut_asserteq(local_phandle, val); + ut_assertok(fdtdec_get_int_array(fdt, 0, "test-several-phandle", val, + ARRAY_SIZE(val))); + ut_asserteq(local_phandle, val[0]); + ut_asserteq(local_phandle, val[1]); return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_local_phandle, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_local_phandle, 0); -static int fdt_overlay_local_phandles(struct unit_test_state *uts) +static int fdt_overlay_test_local_phandles(struct unit_test_state *uts) { uint32_t local_phandle, test_phandle; - u32 val = 0; + u32 val[2]; int off; off = fdt_path_offset(fdt, "/new-local-node"); @@ -186,95 +213,25 @@ static int fdt_overlay_local_phandles(struct unit_test_state *uts) test_phandle = fdt_get_phandle(fdt, off); ut_assert(test_phandle); - ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 0, - &val)); - ut_asserteq(test_phandle, val); - - ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 1, - &val)); - ut_asserteq(local_phandle, val); - - return CMD_RET_SUCCESS; -} -OVERLAY_TEST(fdt_overlay_local_phandles, 0); - -static int fdt_overlay_stacked(struct unit_test_state *uts) -{ - u32 val = 0; - - ut_assertok(ut_fdt_getprop_u32(fdt, "/new-local-node", - "stacked-test-int-property", &val)); - ut_asserteq(43, val); + ut_assertok(fdtdec_get_int_array(fdt, 0, "test-phandle", val, + ARRAY_SIZE(val))); + ut_asserteq(test_phandle, val[0]); + ut_asserteq(local_phandle, val[1]); return CMD_RET_SUCCESS; } -OVERLAY_TEST(fdt_overlay_stacked, 0); +FDT_OVERLAY_TEST(fdt_overlay_test_local_phandles, 0); -int do_ut_overlay(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag, - int argc, char *const argv[]) +static int fdt_overlay_test_stacked(struct unit_test_state *uts) { - struct unit_test *tests = UNIT_TEST_SUITE_START(overlay); - const int n_ents = UNIT_TEST_SUITE_COUNT(overlay); - void *fdt_base = &__dtb_test_fdt_base_begin; - void *fdt_overlay = &__dtbo_test_fdt_overlay_begin; - void *fdt_overlay_stacked = &__dtbo_test_fdt_overlay_stacked_begin; - void *fdt_overlay_copy, *fdt_overlay_stacked_copy; - int ret = -ENOMEM; - - ut_assertok(fdt_check_header(fdt_base)); - ut_assertok(fdt_check_header(fdt_overlay)); - - fdt = malloc(FDT_COPY_SIZE); - if (!fdt) - goto err1; - - fdt_overlay_copy = malloc(FDT_COPY_SIZE); - if (!fdt_overlay_copy) - goto err2; - - fdt_overlay_stacked_copy = malloc(FDT_COPY_SIZE); - if (!fdt_overlay_stacked_copy) - goto err3; - - /* - * Resize the FDT to 4k so that we have room to operate on - * - * (and relocate it since the memory might be mapped - * read-only) - */ - ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE)); - - /* - * Resize the overlay to 4k so that we have room to operate on - * - * (and relocate it since the memory might be mapped - * read-only) - */ - ut_assertok(fdt_open_into(fdt_overlay, fdt_overlay_copy, - FDT_COPY_SIZE)); - - /* - * Resize the stacked overlay to 4k so that we have room to operate on - * - * (and relocate it since the memory might be mapped - * read-only) - */ - ut_assertok(fdt_open_into(fdt_overlay_stacked, fdt_overlay_stacked_copy, - FDT_COPY_SIZE)); - - /* Apply the overlay */ - ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_copy)); + int off; - /* Apply the stacked overlay */ - ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_stacked_copy)); + off = fdt_path_offset(fdt, "/new-local-node"); + ut_assert(off > 0); - ret = cmd_ut_category(uts, "overlay", "", tests, n_ents, argc, argv); + ut_asserteq(43, + fdtdec_get_uint(fdt, off, "stacked-test-int-property", 0)); - free(fdt_overlay_stacked_copy); -err3: - free(fdt_overlay_copy); -err2: - free(fdt); -err1: - return ret; + return CMD_RET_SUCCESS; } +FDT_OVERLAY_TEST(fdt_overlay_test_stacked, 0); diff --git a/test/overlay/test-fdt-base.dts b/test/fdt_overlay/test-fdt-base.dts index 38278334e4d..38278334e4d 100644 --- a/test/overlay/test-fdt-base.dts +++ b/test/fdt_overlay/test-fdt-base.dts diff --git a/test/overlay/test-fdt-overlay-stacked.dtso b/test/fdt_overlay/test-fdt-overlay-stacked.dtso index 6411adec539..6411adec539 100644 --- a/test/overlay/test-fdt-overlay-stacked.dtso +++ b/test/fdt_overlay/test-fdt-overlay-stacked.dtso diff --git a/test/overlay/test-fdt-overlay.dtso b/test/fdt_overlay/test-fdt-overlay.dtso index 5a21b346d07..5a21b346d07 100644 --- a/test/overlay/test-fdt-overlay.dtso +++ b/test/fdt_overlay/test-fdt-overlay.dtso diff --git a/test/log/cont_test.c b/test/log/cont_test.c index 32b1c792367..3b3b791f025 100644 --- a/test/log/cont_test.c +++ b/test/log/cont_test.c @@ -9,7 +9,6 @@ #include <asm/global_data.h> #include <test/log.h> #include <test/test.h> -#include <test/suites.h> #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/test/log/nolog_test.c b/test/log/nolog_test.c index 341dbfc9310..1913e6817a7 100644 --- a/test/log/nolog_test.c +++ b/test/log/nolog_test.c @@ -13,7 +13,6 @@ #include <asm/global_data.h> #include <test/log.h> #include <test/test.h> -#include <test/suites.h> #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/test/log/pr_cont_test.c b/test/log/pr_cont_test.c index 7734e927f98..67d8ac59db9 100644 --- a/test/log/pr_cont_test.c +++ b/test/log/pr_cont_test.c @@ -8,7 +8,6 @@ #include <console.h> #include <test/log.h> #include <test/test.h> -#include <test/suites.h> #include <test/ut.h> #include <asm/global_data.h> #include <linux/printk.h> diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c index c4180f775b9..98b91436580 100644 --- a/test/log/syslog_test.c +++ b/test/log/syslog_test.c @@ -15,7 +15,6 @@ #include <hexdump.h> #include <test/log.h> #include <test/test.h> -#include <test/suites.h> #include <test/ut.h> #include <asm/eth.h> #include "syslog_test.h" diff --git a/test/log/syslog_test_ndebug.c b/test/log/syslog_test_ndebug.c index b10e636812b..dfd0217c1e4 100644 --- a/test/log/syslog_test_ndebug.c +++ b/test/log/syslog_test_ndebug.c @@ -12,7 +12,6 @@ #include <hexdump.h> #include <test/log.h> #include <test/test.h> -#include <test/suites.h> #include <test/ut.h> #include <asm/eth.h> #include "syslog_test.h" diff --git a/test/optee/Kconfig b/test/optee/Kconfig index 2f6834aa3b4..63e2cbf79c7 100644 --- a/test/optee/Kconfig +++ b/test/optee/Kconfig @@ -1,6 +1,6 @@ config UT_OPTEE bool "Enable OP-TEE Unit Tests" - depends on UNIT_TEST && OF_CONTROL && OPTEE + depends on OF_CONTROL && OPTEE default y help This enables the 'ut optee' command which runs a series of unit diff --git a/test/optee/Makefile b/test/optee/Makefile index 8793fd7ad61..ec56750fa80 100644 --- a/test/optee/Makefile +++ b/test/optee/Makefile @@ -3,7 +3,7 @@ # Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH # Test files -obj-y += cmd_ut_optee.o +obj-y += optee.o DTC_FLAGS += -@ diff --git a/test/optee/cmd_ut_optee.c b/test/optee/optee.c index fc6674764f9..658621fa2fa 100644 --- a/test/optee/cmd_ut_optee.c +++ b/test/optee/optee.c @@ -14,7 +14,6 @@ #include <test/ut.h> #include <test/optee.h> -#include <test/suites.h> /* 4k ought to be enough for anybody */ #define FDT_COPY_SIZE (4 * SZ_1K) @@ -26,6 +25,41 @@ extern u32 __dtb_test_optee_no_optee_begin; static void *fdt; static bool expect_success; +static int optee_test_init(struct unit_test_state *uts) +{ + void *fdt_optee = &__dtb_test_optee_optee_begin; + void *fdt_no_optee = &__dtb_test_optee_no_optee_begin; + void *fdt_base = &__dtb_test_optee_base_begin; + int ret = -ENOMEM; + + ut_assertok(fdt_check_header(fdt_base)); + ut_assertok(fdt_check_header(fdt_optee)); + ut_assertok(fdt_check_header(fdt_no_optee)); + + fdt = malloc(FDT_COPY_SIZE); + if (!fdt) + return ret; + + /* + * Resize the FDT to 4k so that we have room to operate on + * + * (and relocate it since the memory might be mapped + * read-only) + */ + ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE)); + + return 0; +} +OPTEE_TEST_INIT(optee_test_init, 0); + +static int optee_test_uninit(struct unit_test_state *uts) +{ + free(fdt); + + return 0; +} +OPTEE_TEST_UNINIT(optee_test_uninit, 0); + static int optee_fdt_firmware(struct unit_test_state *uts) { const void *prop; @@ -46,7 +80,6 @@ static int optee_fdt_firmware(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OPTEE_TEST(optee_fdt_firmware, 0); static int optee_fdt_protected_memory(struct unit_test_state *uts) { @@ -89,60 +122,50 @@ static int optee_fdt_protected_memory(struct unit_test_state *uts) return CMD_RET_SUCCESS; } -OPTEE_TEST(optee_fdt_protected_memory, 0); -int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +/* (1) Try to copy optee nodes from empty dt */ +static int optee_fdt_copy_empty(struct unit_test_state *uts) { - struct unit_test *tests = UNIT_TEST_SUITE_START(optee); - const int n_ents = UNIT_TEST_SUITE_COUNT(optee); - struct unit_test_state *uts; - void *fdt_optee = &__dtb_test_optee_optee_begin; void *fdt_no_optee = &__dtb_test_optee_no_optee_begin; - void *fdt_base = &__dtb_test_optee_base_begin; - int ret = -ENOMEM; - - uts = calloc(1, sizeof(*uts)); - if (!uts) - return -ENOMEM; - - ut_assertok(fdt_check_header(fdt_base)); - ut_assertok(fdt_check_header(fdt_optee)); - ut_assertok(fdt_check_header(fdt_no_optee)); - - fdt = malloc(FDT_COPY_SIZE); - if (!fdt) - return ret; - /* - * Resize the FDT to 4k so that we have room to operate on - * - * (and relocate it since the memory might be mapped - * read-only) - */ - ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE)); - - /* - * (1) Try to copy optee nodes from empty dt. - * This should still run successfully. - */ + /* This should still run successfully */ ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt)); expect_success = false; - ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv); + ut_assertok(optee_fdt_firmware(uts)); + ut_assertok(optee_fdt_protected_memory(uts)); + + return 0; +} +OPTEE_TEST(optee_fdt_copy_empty, 0); + +/* (2) Try to copy optee nodes from prefilled dt */ +static int optee_fdt_copy_prefilled(struct unit_test_state *uts) +{ + void *fdt_optee = &__dtb_test_optee_optee_begin; - /* (2) Try to copy optee nodes from prefilled dt */ ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt)); expect_success = true; - ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv); + ut_assertok(optee_fdt_firmware(uts)); + ut_assertok(optee_fdt_protected_memory(uts)); + + return 0; +} +OPTEE_TEST(optee_fdt_copy_prefilled, 0); + +/* (3) Try to copy OP-TEE nodes into a already filled DT */ +static int optee_fdt_copy_already_filled(struct unit_test_state *uts) +{ + void *fdt_optee = &__dtb_test_optee_optee_begin; - /* (3) Try to copy OP-TEE nodes into a already filled DT */ ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE)); ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt)); expect_success = true; - ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv); + ut_assertok(optee_fdt_firmware(uts)); + ut_assertok(optee_fdt_protected_memory(uts)); - free(fdt); - return ret; + return 0; } +OPTEE_TEST(optee_fdt_copy_already_filled, 0); diff --git a/test/py/tests/test_suite.py b/test/py/tests/test_suite.py index 73c185349b4..9ddc883394b 100644 --- a/test/py/tests/test_suite.py +++ b/test/py/tests/test_suite.py @@ -7,10 +7,10 @@ import re # List of test suites we expect to find with 'ut info' and 'ut all' EXPECTED_SUITES = [ 'addrmap', 'bdinfo', 'bloblist', 'bootm', 'bootstd', - 'cmd', 'common', 'dm', 'env', 'exit', + 'cmd', 'common', 'dm', 'env', 'exit', 'fdt_overlay', 'fdt', 'font', 'hush', 'lib', 'loadm', 'log', 'mbr', 'measurement', 'mem', - 'overlay', 'pci_mps', 'setexpr', 'upl', + 'pci_mps', 'setexpr', 'upl', ] @@ -66,11 +66,12 @@ def collect_info(cons, output): msg = m.group(3) if DEBUG_ME: cons.log.info(f"test_name {test_name} msg '{msg}'") - if msg == ' (flat tree)' and test_name not in tests: - tests.add(test_name) + full_name = f'{cur_suite}.{test_name}' + if msg == ' (flat tree)' and full_name not in tests: + tests.add(full_name) test_count += 1 if not msg or 'skipped as it is manual' in msg: - tests.add(test_name) + tests.add(full_name) test_count += 1 if DEBUG_ME: cons.log.info(f'test_count {test_count}') @@ -134,7 +135,7 @@ def xtest_suite(u_boot_console, u_boot_config): - The number of suites matches that reported by the 'ut info' - Where available, the number of tests is each suite matches that - reported by 'ut info -s' + reported by 'ut -s info' - The total number of tests adds up to the total that are actually run with 'ut all' - All suites are run with 'ut all' @@ -166,7 +167,7 @@ def xtest_suite(u_boot_console, u_boot_config): # Run 'ut info' and compare with the log results with cons.log.section('Check suite test-counts'): - output = cons.run_command('ut info -s') + output = cons.run_command('ut -s info') suite_count, total_test_count, test_count = process_ut_info(cons, output) @@ -186,3 +187,22 @@ def xtest_suite(u_boot_console, u_boot_config): assert suite_count == len(EXPECTED_SUITES) assert total_test_count == len(all_tests) + + # Run three suites + with cons.log.section('Check multiple suites'): + output = cons.run_command('ut bloblist,setexpr,mem') + assert 'Suites run: 3' in output + + # Run a particular test + with cons.log.section('Check single test'): + output = cons.run_command('ut bloblist reloc') + assert 'Test: reloc: bloblist.c' in output + + # Run tests multiple times + with cons.log.section('Check multiple runs'): + output = cons.run_command('ut -r2 bloblist') + lines = output.splitlines() + run = len([line for line in lines if 'Test:' in line]) + count = re.search(r'Tests run: (\d*)', lines[-1]).group(1) + + assert run == 2 * int(count) diff --git a/test/test-main.c b/test/test-main.c index 22b9b46d9cd..cabc736a524 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -14,6 +14,7 @@ #include <net.h> #include <of_live.h> #include <os.h> +#include <spl.h> #include <usb.h> #include <dm/ofnode.h> #include <dm/root.h> @@ -513,11 +514,12 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, * the first call to this function. On exit, @uts->cur.fail_count is * incremented by the number of failures (0, one hopes) * @test: Test to run + * @leaf: Part of the name to show, or NULL to use test->name * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if * any failed */ static int ut_run_test_live_flat(struct unit_test_state *uts, - struct unit_test *test) + struct unit_test *test, const char *leaf) { int runs, ret; @@ -529,7 +531,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, if (CONFIG_IS_ENABLED(OF_LIVE)) { if (!(test->flags & UTF_FLAT_TREE)) { uts->of_live = true; - ret = ut_run_test(uts, test, test->name); + ret = ut_run_test(uts, test, leaf ?: test->name); if (ret != -EAGAIN) { ut_assertok(ret); runs++; @@ -557,7 +559,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, (!runs || ut_test_run_on_flattree(test)) && !(gd->flags & GD_FLG_FDT_CHANGED)) { uts->of_live = false; - ret = ut_run_test(uts, test, test->name); + ret = ut_run_test(uts, test, leaf ?: test->name); if (ret != -EAGAIN) { ut_assertok(ret); runs++; @@ -593,6 +595,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, struct unit_test *tests, int count, const char *select_name, const char *test_insert) { + int prefix_len = prefix ? strlen(prefix) : 0; struct unit_test *test, *one; int found = 0; int pos = 0; @@ -617,7 +620,8 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, const char *test_name = test->name; int ret, i, old_fail_count; - if (!test_matches(prefix, test_name, select_name)) + if (!(test->flags & (UTF_INIT | UTF_UNINIT)) && + !test_matches(prefix, test_name, select_name)) continue; if (test->flags & UTF_MANUAL) { @@ -645,7 +649,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, uts->cur.test_count++; if (one && upto == pos) { - ret = ut_run_test_live_flat(uts, one); + ret = ut_run_test_live_flat(uts, one, NULL); if (uts->cur.fail_count != old_fail_count) { printf("Test '%s' failed %d times (position %d)\n", one->name, @@ -655,8 +659,11 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, return -EBADF; } + if (prefix_len && !strncmp(test_name, prefix, prefix_len)) + test_name = test_name + prefix_len; + for (i = 0; i < uts->runs_per_test; i++) - ret = ut_run_test_live_flat(uts, test); + ret = ut_run_test_live_flat(uts, test, test_name); if (uts->cur.fail_count != old_fail_count) { printf("Test '%s' failed %d times\n", test_name, uts->cur.fail_count - old_fail_count); @@ -680,6 +687,12 @@ void ut_report(struct ut_stats *stats, int run_count) else printf("Tests"); printf(" run: %d, ", stats->test_count); + if (stats && stats->test_count) { + ulong dur = stats->duration_ms; + + printf("%ld ms, average: %ld ms, ", dur, + dur ? dur / stats->test_count : 0); + } if (stats->skip_count) printf("skipped: %d, ", stats->skip_count); printf("failures: %d\n", stats->fail_count); @@ -692,16 +705,22 @@ int ut_run_list(struct unit_test_state *uts, const char *category, { ; bool has_dm_tests = false; + ulong start_offset = 0; + ulong test_offset = 0; int ret; memset(&uts->cur, '\0', sizeof(struct ut_stats)); + if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION)) { + uts->cur.start = get_timer(0); + start_offset = timer_test_get_offset(); + } if (!CONFIG_IS_ENABLED(OF_PLATDATA) && ut_list_has_dm_tests(tests, count, prefix, select_name)) { has_dm_tests = true; /* * If we have no device tree, or it only has a root node, then - * these * tests clearly aren't going to work... + * these tests clearly aren't going to work... */ if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { puts("Please run with test device tree:\n" @@ -732,13 +751,19 @@ int ut_run_list(struct unit_test_state *uts, const char *category, if (has_dm_tests) dm_test_restore(uts->of_root); - ut_report(&uts->cur, 1); if (ret == -ENOENT) printf("Test '%s' not found\n", select_name); + if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION)) { + test_offset = timer_test_get_offset() - start_offset; + + uts->cur.duration_ms = get_timer(uts->cur.start) - test_offset; + } + ut_report(&uts->cur, 1); uts->total.skip_count += uts->cur.skip_count; uts->total.fail_count += uts->cur.fail_count; uts->total.test_count += uts->cur.test_count; + uts->total.duration_ms += uts->cur.duration_ms; uts->run_count++; return ret; |