diff options
Diffstat (limited to 'test')
62 files changed, 1423 insertions, 592 deletions
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index e33b08aa8cd..a8735c1c23d 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -15,6 +15,7 @@ #include <efi.h> #include <efi_loader.h> #include <expo.h> +#include <mapmem.h> #ifdef CONFIG_SANDBOX #include <asm/test.h> #endif @@ -77,6 +78,14 @@ static int bootflow_cmd(struct unit_test_state *uts) ut_assert_nextline("(1 bootflow, 1 valid)"); ut_assert_console_end(); + ut_assertok(run_command("bootstd images", 0)); + ut_assert_nextlinen("Seq"); + ut_assert_nextlinen("---"); + ut_assert_nextlinen(" 0 mmc1.bootdev.part_1 extlinux_cfg"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(1 image)"); + ut_assert_console_end(); + return 0; } BOOTSTD_TEST(bootflow_cmd, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); @@ -1193,6 +1202,19 @@ static int bootflow_cros(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_skip_to_line("(3 bootflows, 3 valid)"); + ut_assertok(run_command("bootstd images", 0)); + ut_assert_nextlinen("Seq"); + ut_assert_nextlinen("---"); + ut_assert_nextlinen(" 0 mmc1.bootdev.part_1 extlinux_cfg"); + ut_assert_nextlinen(" 1 mmc5.bootdev.part_2 x86_setup"); + ut_assert_nextlinen(" 1 mmc5.bootdev.part_2 cmdline"); + ut_assert_nextlinen(" 1 mmc5.bootdev.part_2 kernel - 4000 kernel"); + ut_assert_nextlinen(" 2 mmc5.bootdev.part_4 x86_setup"); + ut_assert_nextlinen(" 2 mmc5.bootdev.part_4 cmdline"); + ut_assert_nextlinen(" 2 mmc5.bootdev.part_4 kernel - 4000 kernel"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(7 images)"); + ut_assert_console_end(); return 0; @@ -1307,3 +1329,87 @@ static int bootflow_efi(struct unit_test_state *uts) return 0; } BOOTSTD_TEST(bootflow_efi, UTF_CONSOLE); + +/* Check 'bootflow scan' provides a list of images */ +static int bootstd_images(struct unit_test_state *uts) +{ + static const char *order[] = {"mmc2", "mmc1", "mmc4", "mmc5", NULL}; + const struct legacy_img_hdr *hdr; + const struct bootflow_img *img; + const struct bootflow *bflow; + struct bootstd_priv *std; + const char **old_order; + struct udevice *dev; + ofnode root, node; + ulong data, len; + char *ptr; + + /* get access to the current bootflow */ + ut_assertok(bootstd_get_priv(&std)); + + ut_assertok(prep_mmc_bootdev(uts, "mmc4", true, &old_order)); + + /* bind mmc5 too, for cros */ + root = oftree_root(oftree_default()); + node = ofnode_find_subnode(root, "mmc5"); + ut_assert(ofnode_valid(node)); + ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false)); + + std->bootdev_order = order; + ut_assertok(run_command("bootflow scan", 0)); + ut_assert_console_end(); + std->bootdev_order = old_order; + + ut_assertok(run_command("bootflow list", 0)); + ut_assert_skip_to_line("(4 bootflows, 4 valid)"); + + ut_assertok(run_command("bootstd images", 0)); + ut_assert_nextlinen("Seq"); + ut_assert_nextlinen("---"); + ut_assert_nextlinen(" 0 mmc1.bootdev.part_1 extlinux_cfg"); + ut_assert_nextlinen(" 1 mmc4.bootdev.part_1 script"); + ut_assert_nextlinen(" 1 mmc4.bootdev.part_1 logo"); + ut_assert_nextlinen(" 2 mmc5.bootdev.part_2 x86_setup"); + ut_assert_nextlinen(" 2 mmc5.bootdev.part_2 cmdline"); + ut_assert_nextlinen(" 2 mmc5.bootdev.part_2 kernel -"); + ut_assert_nextlinen(" 3 mmc5.bootdev.part_4 x86_setup"); + ut_assert_nextlinen(" 3 mmc5.bootdev.part_4 cmdline"); + ut_assert_nextlinen(" 3 mmc5.bootdev.part_4 kernel -"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(9 images)"); + + /* check the first image */ + bflow = alist_get(&std->bootflows, 0, struct bootflow); + img = alist_get(&bflow->images, 0, struct bootflow_img); + ut_asserteq_strn("# extlinux.conf", map_sysmem(img->addr, 0)); + + /* check the second image */ + bflow = alist_get(&std->bootflows, 1, struct bootflow); + img = alist_get(&bflow->images, 0, struct bootflow_img); + + /* this is the length of the script in bytes */ + hdr = map_sysmem(img->addr, 0); + image_multi_getimg(hdr, 0, &data, &len); + ptr = (void *)data; + ut_asserteq_strn("# DO NOT EDIT THIS FILE", ptr); + + /* check the ChromiumOS images */ + bflow = alist_get(&std->bootflows, 2, struct bootflow); + img = alist_get(&bflow->images, 1, struct bootflow_img); + ptr = map_sysmem(img->addr, 0); + ut_asserteq_strn("BOOT_IMAGE=/vmlinuz-5.15.0-121-generic root=", ptr); + + /* + * the x86 setup is not a real binary, so just check that it is empty, + * so that if this changes in the future someone will notice and update + * this test + */ + img = alist_get(&bflow->images, 0, struct bootflow_img); + ptr = map_sysmem(img->addr, 0); + ut_asserteq(0, *(ulong *)ptr); + + ut_assert_console_end(); + + return 0; +} +BOOTSTD_TEST(bootstd_images, UTF_CONSOLE); diff --git a/test/boot/bootm.c b/test/boot/bootm.c index 9455f44884c..7e0ccb0e23f 100644 --- a/test/boot/bootm.c +++ b/test/boot/bootm.c @@ -13,7 +13,7 @@ DECLARE_GLOBAL_DATA_PTR; -#define BOOTM_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootm_test) +#define BOOTM_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootm) enum { BUF_SIZE = 1024, @@ -249,12 +249,3 @@ static int bootm_test_subst_both(struct unit_test_state *uts) return 0; } BOOTM_TEST(bootm_test_subst_both, 0); - -int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(bootm_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(bootm_test); - - return cmd_ut_category("bootm", "bootm_test_", tests, n_ents, - argc, argv); -} diff --git a/test/boot/bootstd_common.c b/test/boot/bootstd_common.c index ff8ed2303b3..724e3d9bdd2 100644 --- a/test/boot/bootstd_common.c +++ b/test/boot/bootstd_common.c @@ -94,10 +94,11 @@ void bootstd_reset_usb(void) usb_started = false; } -int do_ut_bootstd(struct cmd_tbl *cmdtp, int flag, 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[]) { - struct unit_test *tests = UNIT_TEST_SUITE_START(bootstd_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(bootstd_test); + 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(); @@ -106,6 +107,6 @@ int do_ut_bootstd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_FAILURE; } - return cmd_ut_category("bootstd", "bootstd_test_", + 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 e29036c897c..ea3ecd1166c 100644 --- a/test/boot/bootstd_common.h +++ b/test/boot/bootstd_common.h @@ -12,8 +12,7 @@ #include <version_string.h> /* Declare a new bootdev test */ -#define BOOTSTD_TEST(_name, _flags) \ - UNIT_TEST(_name, _flags, bootstd_test) +#define BOOTSTD_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootstd) #define NVDATA_START_BLK ((0x400 + 0x400) / MMC_MAX_BLOCK_LEN) #define VERSION_START_BLK ((0x400 + 0x800) / MMC_MAX_BLOCK_LEN) diff --git a/test/boot/measurement.c b/test/boot/measurement.c index 29be495412d..5a49c7a6b23 100644 --- a/test/boot/measurement.c +++ b/test/boot/measurement.c @@ -14,7 +14,7 @@ #include <asm/io.h> #define MEASUREMENT_TEST(_name, _flags) \ - UNIT_TEST(_name, _flags, measurement_test) + UNIT_TEST(_name, _flags, measurement) static int measure(struct unit_test_state *uts) { @@ -53,13 +53,3 @@ static int measure(struct unit_test_state *uts) return 0; } MEASUREMENT_TEST(measure, 0); - -int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(measurement_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(measurement_test); - - return cmd_ut_category("measurement", "measurement_test_", tests, - n_ents, argc, argv); -} diff --git a/test/boot/upl.c b/test/boot/upl.c index 99f02b7951b..aa58cdf083b 100644 --- a/test/boot/upl.c +++ b/test/boot/upl.c @@ -16,7 +16,7 @@ #include "bootstd_common.h" /* Declare a new upl test */ -#define UPL_TEST(_name, _flags) UNIT_TEST(_name, _flags, upl_test) +#define UPL_TEST(_name, _flags) UNIT_TEST(_name, _flags, upl) static int add_region(struct unit_test_state *uts, struct alist *lst, ulong base, ulong size) @@ -426,12 +426,3 @@ static int upl_test_info_norun(struct unit_test_state *uts) return 0; } UPL_TEST(upl_test_info_norun, UTF_CONSOLE | UTF_MANUAL); - -int do_ut_upl(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(upl_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(upl_test); - - return cmd_ut_category("cmd_upl", "cmd_upl_", tests, n_ents, argc, - argv); -} diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 583e7c2eec4..d8a5e77402d 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2013 Google, Inc # Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> -obj-y += cmd_ut_cmd.o - obj-$(CONFIG_$(XPL_)CMDLINE) += command.o ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o @@ -12,7 +10,7 @@ endif ifdef CONFIG_CONSOLE_RECORD obj-$(CONFIG_CMD_PAUSE) += test_pause.o endif -obj-y += exit.o mem.o +obj-y += exit.o obj-$(CONFIG_X86) += cpuid.o msr.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_BDI) += bdinfo.o diff --git a/test/cmd/addrmap.c b/test/cmd/addrmap.c index b34be895f5d..1f2deb15052 100644 --- a/test/cmd/addrmap.c +++ b/test/cmd/addrmap.c @@ -10,7 +10,7 @@ #include <test/ut.h> /* Declare a new addrmap test */ -#define ADDRMAP_TEST(_name, _flags) UNIT_TEST(_name, _flags, addrmap_test) +#define ADDRMAP_TEST(_name, _flags) UNIT_TEST(_name, _flags, addrmap) /* Test 'addrmap' command output */ static int addrmap_test_basic(struct unit_test_state *uts) @@ -24,12 +24,3 @@ static int addrmap_test_basic(struct unit_test_state *uts) return 0; } ADDRMAP_TEST(addrmap_test_basic, UTF_CONSOLE); - -int do_ut_addrmap(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(addrmap_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(addrmap_test); - - return cmd_ut_category("cmd_addrmap", "cmd_addrmap_", tests, n_ents, - argc, argv); -} diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 76429485708..7408c271a30 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -26,7 +26,7 @@ DECLARE_GLOBAL_DATA_PTR; /* Declare a new bdinfo test */ -#define BDINFO_TEST(_name, _flags) UNIT_TEST(_name, _flags, bdinfo_test) +#define BDINFO_TEST(_name, _flags) UNIT_TEST(_name, _flags, bdinfo) static int test_num_l(struct unit_test_state *uts, const char *name, ulong value) @@ -282,11 +282,3 @@ static int bdinfo_test_eth(struct unit_test_state *uts) return 0; } BDINFO_TEST(bdinfo_test_eth, UTF_CONSOLE); - -int do_ut_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(bdinfo_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(bdinfo_test); - - return cmd_ut_category("bdinfo", "bdinfo_test_", tests, n_ents, argc, argv); -} diff --git a/test/cmd/cmd_ut_cmd.c b/test/cmd/cmd_ut_cmd.c deleted file mode 100644 index e77fa1c7f01..00000000000 --- a/test/cmd/cmd_ut_cmd.c +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright 2023 Google LLC - * Written by Simon Glass <sjg@chromium.org> - * - * Unit tests for command functions - */ - -#include <command.h> -#include <test/cmd.h> -#include <test/suites.h> -#include <test/ut.h> - -int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(cmd_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(cmd_test); - - return cmd_ut_category("cmd", "cmd_test_", tests, n_ents, argc, argv); -} diff --git a/test/cmd/exit.c b/test/cmd/exit.c index af58a57fca7..71c37edcdf6 100644 --- a/test/cmd/exit.c +++ b/test/cmd/exit.c @@ -14,7 +14,7 @@ DECLARE_GLOBAL_DATA_PTR; /* Declare a new exit test */ -#define EXIT_TEST(_name, _flags) UNIT_TEST(_name, _flags, exit_test) +#define EXIT_TEST(_name, _flags) UNIT_TEST(_name, _flags, exit) /* Test 'exit addr' getting/setting address */ static int cmd_exit_test(struct unit_test_state *uts) @@ -110,12 +110,3 @@ static int cmd_exit_test(struct unit_test_state *uts) return 0; } EXIT_TEST(cmd_exit_test, UTF_CONSOLE); - -int do_ut_exit(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(exit_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(exit_test); - - return cmd_ut_category("cmd_exit", "exit_test_", tests, n_ents, - argc, argv); -} diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c index e64785101cd..ab6dbd45e54 100644 --- a/test/cmd/fdt.c +++ b/test/cmd/fdt.c @@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR; */ /* Declare a new fdt test */ -#define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_test) +#define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt) /** * make_test_fdt() - Create an FDT with just a root node @@ -1462,11 +1462,3 @@ static int fdt_test_apply(struct unit_test_state *uts) return 0; } FDT_TEST(fdt_test_apply, UTF_CONSOLE); - -int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(fdt_test); - - return cmd_ut_category("fdt", "fdt_test_", tests, n_ents, argc, argv); -} diff --git a/test/cmd/font.c b/test/cmd/font.c index 3335dd65bea..af88d1b5459 100644 --- a/test/cmd/font.c +++ b/test/cmd/font.c @@ -12,7 +12,7 @@ #include <test/ut.h> /* Declare a new fdt test */ -#define FONT_TEST(_name, _flags) UNIT_TEST(_name, _flags, font_test) +#define FONT_TEST(_name, _flags) UNIT_TEST(_name, _flags, font) /* Test 'fdt addr' resizing an fdt */ static int font_test_base(struct unit_test_state *uts) @@ -85,11 +85,3 @@ static int font_test_base(struct unit_test_state *uts) } FONT_TEST(font_test_base, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE | UTF_DM); - -int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(font_Test); - const int n_ents = UNIT_TEST_SUITE_COUNT(font_test); - - return cmd_ut_category("font", "font_test_", tests, n_ents, argc, argv); -} diff --git a/test/cmd/loadm.c b/test/cmd/loadm.c index dedb4f7683e..3c623aa655f 100644 --- a/test/cmd/loadm.c +++ b/test/cmd/loadm.c @@ -19,7 +19,7 @@ #define BUF_SIZE 0x100 -#define LOADM_TEST(_name, _flags) UNIT_TEST(_name, _flags, loadm_test) +#define LOADM_TEST(_name, _flags) UNIT_TEST(_name, _flags, loadm) static int loadm_test_params(struct unit_test_state *uts) { @@ -58,12 +58,3 @@ static int loadm_test_load (struct unit_test_state *uts) return 0; } LOADM_TEST(loadm_test_load, UTF_CONSOLE); - -int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(loadm_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(loadm_test); - - return cmd_ut_category("loadm", "loadm_test_", tests, n_ents, argc, - argv); -} diff --git a/test/cmd/mbr.c b/test/cmd/mbr.c index d137378a3be..45bab04923a 100644 --- a/test/cmd/mbr.c +++ b/test/cmd/mbr.c @@ -470,12 +470,4 @@ static int mbr_test_run(struct unit_test_state *uts) } /* Declare mbr test */ -UNIT_TEST(mbr_test_run, UTF_CONSOLE, mbr_test); - -int do_ut_mbr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(mbr_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(mbr_test); - - return cmd_ut_category("mbr", "mbr_test_", tests, n_ents, argc, argv); -} +UNIT_TEST(mbr_test_run, UTF_CONSOLE, mbr); diff --git a/test/cmd/mem.c b/test/cmd/mem.c deleted file mode 100644 index f1bbab6055b..00000000000 --- a/test/cmd/mem.c +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Executes tests for memory-related commands - * - * Copyright 2020 Google LLC - */ - -#include <command.h> -#include <test/suites.h> -#include <test/test.h> - -int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(mem_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(mem_test); - - return cmd_ut_category("cmd_mem", "mem_test_", tests, n_ents, argc, - argv); -} diff --git a/test/cmd/mem_copy.c b/test/cmd/mem_copy.c index 67eca328777..3e904fc4e4b 100644 --- a/test/cmd/mem_copy.c +++ b/test/cmd/mem_copy.c @@ -12,7 +12,7 @@ #define BUF_SIZE 256 /* Declare a new mem test */ -#define MEM_TEST(_name) UNIT_TEST(_name, 0, mem_test) +#define MEM_TEST(_name) UNIT_TEST(_name, 0, mem) struct param { int d, s, count; diff --git a/test/cmd/mem_search.c b/test/cmd/mem_search.c index 3a031eed7ed..df8938bdb6c 100644 --- a/test/cmd/mem_search.c +++ b/test/cmd/mem_search.c @@ -14,7 +14,7 @@ #define BUF_SIZE 0x100 /* Declare a new mem test */ -#define MEM_TEST(_name, _flags) UNIT_TEST(_name, _flags, mem_test) +#define MEM_TEST(_name, _flags) UNIT_TEST(_name, _flags, mem) /* Test 'ms' command with bytes */ static int mem_test_ms_b(struct unit_test_state *uts) diff --git a/test/cmd/pci_mps.c b/test/cmd/pci_mps.c index a265105600c..8b3ea4a6134 100644 --- a/test/cmd/pci_mps.c +++ b/test/cmd/pci_mps.c @@ -11,7 +11,7 @@ #include <test/suites.h> #include <test/ut.h> -#define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps_test) +#define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps) /* Test "pci_mps" command in safe "s" mode */ static int test_pci_mps_safe(struct unit_test_state *uts) @@ -28,13 +28,3 @@ static int test_pci_mps_safe(struct unit_test_state *uts) return 0; } PCI_MPS_TEST(test_pci_mps_safe, UTF_CONSOLE); - -int do_ut_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, - char * const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(pci_mps_test); - const int n = UNIT_TEST_SUITE_COUNT(pci_mps_test); - - return cmd_ut_category("cmd_pci_mps", "pci_mps_test_", tests, n, - argc, argv); -} diff --git a/test/cmd/seama.c b/test/cmd/seama.c index 28d6b9ab517..1edc3fcac5a 100644 --- a/test/cmd/seama.c +++ b/test/cmd/seama.c @@ -11,7 +11,7 @@ #include <test/test.h> #include <test/ut.h> -#define SEAMA_TEST(_name, _flags) UNIT_TEST(_name, _flags, seama_test) +#define SEAMA_TEST(_name, _flags) UNIT_TEST(_name, _flags, seama) static int seama_test_noargs(struct unit_test_state *uts) { @@ -56,12 +56,3 @@ static int seama_test_index(struct unit_test_state *uts) return 0; } SEAMA_TEST(seama_test_index, UTF_CONSOLE); - -int do_ut_seama(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(seama_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(seama_test); - - return cmd_ut_category("seama", "seama_test_", tests, n_ents, argc, - argv); -} diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index 21a3268bd81..5e9b577fe36 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -15,7 +15,7 @@ #define BUF_SIZE 0x100 /* Declare a new setexpr test */ -#define SETEXPR_TEST(_name, _flags) UNIT_TEST(_name, _flags, setexpr_test) +#define SETEXPR_TEST(_name, _flags) UNIT_TEST(_name, _flags, setexpr) /* Test 'setexpr' command with simply setting integers */ static int setexpr_test_int(struct unit_test_state *uts) @@ -297,31 +297,19 @@ SETEXPR_TEST(setexpr_test_backref, UTF_CONSOLE); /* Test 'setexpr' command with setting strings */ static int setexpr_test_str(struct unit_test_state *uts) { - ulong start_mem; char *buf; buf = map_sysmem(0, BUF_SIZE); memset(buf, '\xff', BUF_SIZE); - /* - * Set 'fred' to the same length as we expect to get below, to avoid a - * new allocation in 'setexpr'. That way we can check for memory leaks. - */ ut_assertok(env_set("fred", "x")); - start_mem = ut_check_free(); - strcpy(buf, "hello"); - ut_asserteq(1, run_command("setexpr.s fred 0", 0)); - ut_assertok(ut_check_delta(start_mem)); + ut_asserteq(0, run_command("setexpr.s fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); + strcpy(buf, "hello"); ut_assertok(env_set("fred", "12345")); - start_mem = ut_check_free(); ut_assertok(run_command("setexpr.s fred *0", 0)); ut_asserteq_str("hello", env_get("fred")); - /* - * This fails in CI at present. - * - * ut_assertok(ut_check_delta(start_mem)); - */ unmap_sysmem(buf); @@ -332,45 +320,25 @@ SETEXPR_TEST(setexpr_test_str, UTF_CONSOLE); /* Test 'setexpr' command with concatenating strings */ static int setexpr_test_str_oper(struct unit_test_state *uts) { - ulong start_mem; char *buf; + /* Test concatenation of strings */ + ut_assertok(run_command("setexpr.s fred '1' + '3'", 0)); + ut_asserteq_str("13", env_get("fred")); + buf = map_sysmem(0, BUF_SIZE); memset(buf, '\xff', BUF_SIZE); strcpy(buf, "hello"); strcpy(buf + 0x10, " there"); - start_mem = ut_check_free(); ut_asserteq(1, run_command("setexpr.s fred *0 * *10", 0)); - ut_assertok(ut_check_delta(start_mem)); ut_assert_nextline("invalid op"); ut_assert_console_end(); - /* - * Set 'fred' to the same length as we expect to get below, to avoid a - * new allocation in 'setexpr'. That way we can check for memory leaks. - */ ut_assertok(env_set("fred", "12345012345")); - start_mem = ut_check_free(); ut_assertok(run_command("setexpr.s fred *0 + *10", 0)); ut_asserteq_str("hello there", env_get("fred")); - /* - * This check does not work with sandbox_flattree, apparently due to - * memory allocations in env_set(). - * - * The truetype console produces lots of memory allocations even though - * the LCD display is not visible. But even without these, it does not - * work. - * - * A better test would be for dlmalloc to record the allocs and frees - * for a particular caller, but that is not supported. - * - * For now, drop this test. - * - * ut_assertok(ut_check_delta(start_mem)); - */ - unmap_sysmem(buf); return 0; @@ -479,12 +447,3 @@ static int setexpr_test_fmt(struct unit_test_state *uts) } SETEXPR_TEST(setexpr_test_fmt, UTF_CONSOLE); #endif - -int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(setexpr_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(setexpr_test); - - return cmd_ut_category("cmd_setexpr", "setexpr_test_", tests, n_ents, - argc, argv); -} diff --git a/test/cmd/wget.c b/test/cmd/wget.c index b020d20ad70..445750660c2 100644 --- a/test/cmd/wget.c +++ b/test/cmd/wget.c @@ -217,28 +217,26 @@ static int net_test_wget(struct unit_test_state *uts) { char *prev_ethact = env_get("ethact"); char *prev_ethrotate = env_get("ethrotate"); - char *prev_loadaddr = env_get("loadaddr"); sandbox_eth_set_tx_handler(0, sb_http_handler); sandbox_eth_set_priv(0, uts); env_set("ethact", "eth@10002000"); env_set("ethrotate", "no"); - env_set("loadaddr", "0x20000"); - ut_assertok(run_command("wget ${loadaddr} 1.1.2.2:/index.html", 0)); + env_set("wgetaddr", "0x20000"); + ut_assertok(run_command("wget ${wgetaddr} 1.1.2.2:/index.html", 0)); ut_assert_nextline_empty(); ut_assert_nextline("Packets received 5, Transfer Successful"); ut_assert_nextline("Bytes transferred = 29 (1d hex)"); sandbox_eth_set_tx_handler(0, NULL); - run_command("md5sum ${loadaddr} ${filesize}", 0); + run_command("md5sum ${wgetaddr} ${filesize}", 0); ut_assert_nextline("md5 for 00020000 ... 0002001c ==> 847d5e7320a27462e90bc1ed75eb8cd8"); ut_assert_console_end(); env_set("ethact", prev_ethact); env_set("ethrotate", prev_ethrotate); - env_set("loadaddr", prev_loadaddr); return 0; } diff --git a/test/cmd_ut.c b/test/cmd_ut.c index a14dbf4ca5e..fbfdaaae0b5 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -11,14 +11,34 @@ #include <test/test.h> #include <test/ut.h> -static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]); +/** + * struct suite - A set of tests for a certain topic + * + * All tests end up in a single 'struct unit_test' linker-list array, in order + * of the suite they are in + * + * @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_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); -int cmd_ut_category(const char *name, const char *prefix, - struct unit_test *tests, int n_ents, +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; @@ -44,105 +64,153 @@ int cmd_ut_category(const char *name, const char *prefix, argc--; } - ret = ut_run_list(name, prefix, tests, n_ents, + 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 struct cmd_tbl cmd_ut_sub[] = { - U_BOOT_CMD_MKENT(all, CONFIG_SYS_MAXARGS, 1, do_ut_all, "", ""), - U_BOOT_CMD_MKENT(info, 1, 1, do_ut_info, "", ""), -#ifdef CONFIG_CMD_BDI - U_BOOT_CMD_MKENT(bdinfo, CONFIG_SYS_MAXARGS, 1, do_ut_bdinfo, "", ""), -#endif +/* 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, \ + } + +SUITE_DECL(addrmap); +SUITE_DECL(bdinfo); +SUITE_DECL(bloblist); +SUITE_DECL(bootm); +SUITE_DECL(bootstd); +SUITE_DECL(cmd); +SUITE_DECL(common); +SUITE_DECL(dm); +SUITE_DECL(env); +SUITE_DECL(exit); +SUITE_DECL(fdt); +SUITE_DECL(font); +SUITE_DECL(hush); +SUITE_DECL(lib); +SUITE_DECL(loadm); +SUITE_DECL(log); +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); +SUITE_DECL(upl); + +static struct suite suites[] = { + SUITE(addrmap, "very basic test of addrmap command"), + SUITE(bdinfo, "bdinfo (board info) command"), + SUITE(bloblist, "bloblist implementation"), + SUITE(bootm, "bootm command"), #ifdef CONFIG_UT_BOOTSTD - U_BOOT_CMD_MKENT(bootstd, CONFIG_SYS_MAXARGS, 1, do_ut_bootstd, - "", ""), -#endif -#ifdef CONFIG_CMDLINE - U_BOOT_CMD_MKENT(cmd, CONFIG_SYS_MAXARGS, 1, do_ut_cmd, "", ""), -#endif - U_BOOT_CMD_MKENT(common, CONFIG_SYS_MAXARGS, 1, do_ut_common, "", ""), -#if defined(CONFIG_UT_DM) - U_BOOT_CMD_MKENT(dm, CONFIG_SYS_MAXARGS, 1, do_ut_dm, "", ""), -#endif -#if defined(CONFIG_UT_ENV) - U_BOOT_CMD_MKENT(env, CONFIG_SYS_MAXARGS, 1, do_ut_env, "", ""), -#endif - U_BOOT_CMD_MKENT(exit, CONFIG_SYS_MAXARGS, 1, do_ut_exit, "", ""), -#ifdef CONFIG_CMD_FDT - U_BOOT_CMD_MKENT(fdt, CONFIG_SYS_MAXARGS, 1, do_ut_fdt, "", ""), -#endif -#ifdef CONFIG_CONSOLE_TRUETYPE - U_BOOT_CMD_MKENT(font, CONFIG_SYS_MAXARGS, 1, do_ut_font, "", ""), -#endif + SUITE_CMD(bootstd, do_ut_bootstd, "standard boot implementation"), +#endif + 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(font, "font command"), + SUITE(hush, "hush behaviour"), + SUITE(lib, "library functions"), + SUITE(loadm, "loadm command parameters and loading memory blob"), + SUITE(log, "logging functions"), + SUITE(mbr, "mbr command"), + SUITE(measurement, "TPM-based measured boot"), + SUITE(mem, "memory-related commands"), #ifdef CONFIG_UT_OPTEE - U_BOOT_CMD_MKENT(optee, CONFIG_SYS_MAXARGS, 1, do_ut_optee, "", ""), + SUITE_CMD(optee, do_ut_optee, "OP-TEE"), #endif #ifdef CONFIG_UT_OVERLAY - U_BOOT_CMD_MKENT(overlay, CONFIG_SYS_MAXARGS, 1, do_ut_overlay, "", ""), -#endif -#ifdef CONFIG_UT_LIB - U_BOOT_CMD_MKENT(lib, CONFIG_SYS_MAXARGS, 1, do_ut_lib, "", ""), -#endif -#ifdef CONFIG_UT_LOG - U_BOOT_CMD_MKENT(log, CONFIG_SYS_MAXARGS, 1, do_ut_log, "", ""), -#endif -#if defined(CONFIG_SANDBOX) && defined(CONFIG_CMD_MBR) && defined(CONFIG_CMD_MMC) \ - && defined(CONFIG_MMC_SANDBOX) && defined(CONFIG_MMC_WRITE) - U_BOOT_CMD_MKENT(mbr, CONFIG_SYS_MAXARGS, 1, do_ut_mbr, "", ""), -#endif - U_BOOT_CMD_MKENT(mem, CONFIG_SYS_MAXARGS, 1, do_ut_mem, "", ""), -#if defined(CONFIG_SANDBOX) && defined(CONFIG_CMD_SETEXPR) - U_BOOT_CMD_MKENT(setexpr, CONFIG_SYS_MAXARGS, 1, do_ut_setexpr, "", - ""), -#endif -#ifdef CONFIG_MEASURED_BOOT - U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1, do_ut_measurement, - "", ""), -#endif -#ifdef CONFIG_SANDBOX -#if CONFIG_IS_ENABLED(BLOBLIST) - U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist, - "", ""), - U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "", ""), -#endif -#endif -#ifdef CONFIG_CMD_ADDRMAP - U_BOOT_CMD_MKENT(addrmap, CONFIG_SYS_MAXARGS, 1, do_ut_addrmap, "", ""), -#endif -#if CONFIG_IS_ENABLED(HUSH_PARSER) - U_BOOT_CMD_MKENT(hush, CONFIG_SYS_MAXARGS, 1, do_ut_hush, "", ""), -#endif -#ifdef CONFIG_CMD_LOADM - U_BOOT_CMD_MKENT(loadm, CONFIG_SYS_MAXARGS, 1, do_ut_loadm, "", ""), -#endif -#ifdef CONFIG_CMD_PCI_MPS - U_BOOT_CMD_MKENT(pci_mps, CONFIG_SYS_MAXARGS, 1, do_ut_pci_mps, "", ""), -#endif -#ifdef CONFIG_CMD_SEAMA - U_BOOT_CMD_MKENT(seama, CONFIG_SYS_MAXARGS, 1, do_ut_seama, "", ""), -#endif -#ifdef CONFIG_CMD_UPL - U_BOOT_CMD_MKENT(upl, CONFIG_SYS_MAXARGS, 1, do_ut_upl, "", ""), + SUITE_CMD(overlay, do_ut_overlay, "device tree overlays"), #endif + SUITE(pci_mps, "PCI Express Maximum Payload Size"), + SUITE(seama, "seama command parameters loading and decoding"), + SUITE(setexpr, "setexpr command"), + SUITE(upl, "Universal payload support"), }; -static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc, +/** + * has_tests() - Check if a suite has tests, i.e. is supported in this build + * + * If the suite is run using a command, we have to assume that tests may be + * present, since we have no visibility + * + * @ste: Suite to check + * Return: true if supported, false if not + */ +static bool has_tests(struct suite *ste) +{ + int n_ents = ste->end - ste->start; + + return n_ents || ste->cmd; +} + +/** 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[]) { + 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); + ret = cmd_ut_category(uts, ste->name, prefix, ste->start, + n_ents, argc, argv); + } + + return ret; +} + +static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp, + int flag, int argc, char *const argv[]) +{ int i; int retval; int any_fail = 0; - for (i = 1; i < ARRAY_SIZE(cmd_ut_sub); i++) { - printf("----Running %s tests----\n", cmd_ut_sub[i].name); - retval = cmd_ut_sub[i].cmd(cmdtp, flag, 1, &cmd_ut_sub[i].name); - if (!any_fail) - any_fail = retval; + 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); + if (!any_fail) + any_fail = retval; + } } + ut_report(&uts->total, uts->run_count); return any_fail; } @@ -150,15 +218,61 @@ static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc, static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - printf("Test suites: %d\n", (int)ARRAY_SIZE(cmd_ut_sub)); + int suite_count, i; + const char *flags; + + for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) { + struct suite *ste = &suites[i]; + + if (has_tests(ste)) + suite_count++; + } + + 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; + + puts("\nTests Suite Purpose"); + puts("\n----- ------------ -------------------------\n"); + for (i = 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); + } + } + return 0; } +static struct suite *find_suite(const char *name) +{ + struct suite *ste; + int i; + + for (i = 0, ste = suites; i < ARRAY_SIZE(suites); i++, ste++) { + if (!strcmp(ste->name, name)) + return ste; + } + + return NULL; +} + static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - struct cmd_tbl *cp; + struct unit_test_state uts; + struct suite *ste; + const char *name; + int ret; if (argc < 2) return CMD_RET_USAGE; @@ -167,12 +281,30 @@ static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) argc--; argv++; - cp = find_cmd_tbl(argv[0], cmd_ut_sub, ARRAY_SIZE(cmd_ut_sub)); + ut_init_state(&uts); + name = argv[0]; + if (!strcmp(name, "all")) { + ret = do_ut_all(&uts, cmdtp, flag, argc, argv); + } else if (!strcmp(name, "info")) { + ret = do_ut_info(cmdtp, flag, argc, argv); + } 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; + } - if (cp) - return cp->cmd(cmdtp, flag, argc, argv); + ret = run_suite(&uts, ste, cmdtp, flag, argc, argv); + } + if (ret) + return ret; + ut_uninit_state(&uts); - return CMD_RET_USAGE; + return 0; } U_BOOT_LONGHELP(ut, @@ -183,61 +315,7 @@ U_BOOT_LONGHELP(ut, "\n" "\nOptions for <suite>:" "\nall - execute all enabled tests" - "\ninfo - show info about tests" -#ifdef CONFIG_CMD_ADDRMAP - "\naddrmap - very basic test of addrmap command" -#endif -#ifdef CONFIG_CMD_BDI - "\nbdinfo - bdinfo command" -#endif -#ifdef CONFIG_SANDBOX - "\nbloblist - bloblist implementation" -#endif -#ifdef CONFIG_BOOTSTD - "\nbootstd - standard boot implementation" -#endif -#ifdef CONFIG_CMDLINE - "\ncmd - test various commands" -#endif - "\ncommon - tests for common/ directory" -#ifdef CONFIG_UT_DM - "\ndm - driver model" -#endif -#ifdef CONFIG_UT_ENV - "\nenv - environment" -#endif -#ifdef CONFIG_CMD_FDT - "\nfdt - fdt command" -#endif -#ifdef CONFIG_CONSOLE_TRUETYPE - "\nfont - font command" -#endif -#if CONFIG_IS_ENABLED(HUSH_PARSER) - "\nhush - Test hush behavior" -#endif -#ifdef CONFIG_CMD_LOADM - "\nloadm - loadm command parameters and loading memory blob" -#endif -#ifdef CONFIG_UT_LIB - "\nlib - library functions" -#endif -#ifdef CONFIG_UT_LOG - "\nlog - logging functions" -#endif - "\nmem - memory-related commands" -#ifdef CONFIG_UT_OPTEE - "\noptee - test OP-TEE" -#endif -#ifdef CONFIG_UT_OVERLAY - "\noverlay - device tree overlays" -#endif -#ifdef CONFIG_CMD_PCI_MPS - "\npci_mps - PCI Express Maximum Payload Size" -#endif - "\nsetexpr - setexpr command" -#ifdef CONFIG_CMD_SEAMA - "\nseama - seama command parameters loading and decoding" -#endif + "\ninfo [-s] - show info about tests [and suites]" ); U_BOOT_CMD( diff --git a/test/common/Makefile b/test/common/Makefile index 53c4f16164d..1ad6c24b7e2 100644 --- a/test/common/Makefile +++ b/test/common/Makefile @@ -1,9 +1,12 @@ # SPDX-License-Identifier: GPL-2.0+ -obj-y += cmd_ut_common.o obj-$(CONFIG_AUTOBOOT) += test_autoboot.o + ifneq ($(CONFIG_$(XPL_)BLOBLIST),) +ifdef CONFIG_BLOBLIST_FIXED obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o endif +endif + obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_EVENT_DYNAMIC) += event.o obj-y += cread.o diff --git a/test/common/bloblist.c b/test/common/bloblist.c index 4bca62110a5..ab8f41c6808 100644 --- a/test/common/bloblist.c +++ b/test/common/bloblist.c @@ -12,7 +12,7 @@ /* Declare a new bloblist test */ #define BLOBLIST_TEST(_name, _flags) \ - UNIT_TEST(_name, _flags, bloblist_test) + UNIT_TEST(_name, _flags, bloblist) enum { TEST_TAG = BLOBLISTT_U_BOOT_SPL_HANDOFF, @@ -98,10 +98,12 @@ static int bloblist_test_blob(struct unit_test_state *uts) struct bloblist_hdr *hdr; struct bloblist_rec *rec, *rec2; char *data; + int size = 0; /* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); + ut_assertnull(bloblist_get_blob(TEST_TAG, &size)); ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size()); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size()); @@ -114,6 +116,8 @@ static int bloblist_test_blob(struct unit_test_state *uts) ut_asserteq_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); ut_asserteq_addr(rec + 1, data); + ut_asserteq_addr(bloblist_get_blob(TEST_TAG, &size), data); + ut_asserteq(size, TEST_SIZE); /* Check the data is zeroed */ ut_assertok(check_zero(data, TEST_SIZE)); @@ -602,13 +606,3 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts) return 0; } BLOBLIST_TEST(bloblist_test_blob_maxsize, UFT_BLOBLIST); - -int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(bloblist_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(bloblist_test); - - return cmd_ut_category("bloblist", "bloblist_test_", - tests, n_ents, argc, argv); -} diff --git a/test/common/cmd_ut_common.c b/test/common/cmd_ut_common.c deleted file mode 100644 index 2f03a58af47..00000000000 --- a/test/common/cmd_ut_common.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de> - * Copyright (c) 2021 Steffen Jaeckel <jaeckel-floss@eyet-services.de> - * - * Unit tests for common functions - */ - -#include <command.h> -#include <test/common.h> -#include <test/suites.h> -#include <test/ut.h> - -int do_ut_common(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(common_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(common_test); - - return cmd_ut_category("common", "common_test_", tests, n_ents, argc, - argv); -} diff --git a/test/dm/Makefile b/test/dm/Makefile index bcb52ef1067..e44f3d89e77 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2013 Google, Inc # Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> -obj-$(CONFIG_UT_DM) += test-dm.o - # Tests for particular subsystems - when enabling driver model for a new # subsystem you must add sandbox tests here. ifeq ($(CONFIG_XPL_BUILD),y) diff --git a/test/dm/core.c b/test/dm/core.c index c59ffc6f611..959b834576f 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -186,10 +186,30 @@ static int dm_test_compare_node_name(struct unit_test_state *uts) ut_assert(ofnode_valid(node)); ut_assert(ofnode_name_eq(node, "mmio-bus")); + ut_assert(!ofnode_name_eq(node, "mmio-bus@0")); + return 0; } DM_TEST(dm_test_compare_node_name, UTF_SCAN_PDATA); +/* compare node names ignoring the unit address */ +static int dm_test_compare_node_name_unit(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/mmio-bus@0"); + ut_assert(ofnode_valid(node)); + ut_assert(ofnode_name_eq_unit(node, "mmio-bus")); + + ut_assert(ofnode_name_eq_unit(node, "mmio-bus@0")); + ut_assert(!ofnode_name_eq_unit(node, "mmio-bus@1")); + ut_assert(!ofnode_name_eq_unit(node, "mmio-bu")); + ut_assert(!ofnode_name_eq_unit(node, "mmio-buss@0")); + + return 0; +} +DM_TEST(dm_test_compare_node_name_unit, UTF_SCAN_PDATA); + /* Test that binding with uclass plat setting occurs correctly */ static int dm_test_autobind_uclass_pdata_valid(struct unit_test_state *uts) { diff --git a/test/dm/led.c b/test/dm/led.c index e5b86326c3a..36652c2833a 100644 --- a/test/dm/led.c +++ b/test/dm/led.c @@ -20,7 +20,12 @@ static int dm_test_led_base(struct unit_test_state *uts) ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev)); ut_assertok(uclass_get_device(UCLASS_LED, 2, &dev)); ut_assertok(uclass_get_device(UCLASS_LED, 3, &dev)); - ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 4, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 4, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 5, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 6, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 7, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 8, &dev)); + ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 9, &dev)); return 0; } @@ -110,6 +115,21 @@ static int dm_test_led_label(struct unit_test_state *uts) ut_asserteq(-ENODEV, led_get_by_label("sandbox:blue", &dev)); + /* Test if function, color and function-enumerator naming works */ + ut_assertok(led_get_by_label("red:status-20", &dev)); + + /* Test if function, color naming works */ + ut_assertok(led_get_by_label("green:status", &dev)); + + /* Test if function, without color naming works */ + ut_assertok(led_get_by_label(":status", &dev)); + + /* Test if color without function naming works */ + ut_assertok(led_get_by_label("green:", &dev)); + + /* Test if function, color naming is ignored if label is found */ + ut_assertok(led_get_by_label("sandbox:function", &dev)); + return 0; } DM_TEST(dm_test_led_label, UTF_SCAN_PDATA | UTF_SCAN_FDT); diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f16b643fa3f..cc8b444ff9a 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -1303,6 +1303,25 @@ static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_find_subnode, UTF_SCAN_FDT); +/* check ofnode_find_subnode() with unit addresses */ +static int dm_test_ofnode_find_subnode_unit(struct unit_test_state *uts) +{ + ofnode node, subnode; + + node = ofnode_path("/some-bus"); + ut_assert(ofnode_valid(node)); + subnode = ofnode_find_subnode_unit(node, "c-test@5"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("c-test@5", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode_unit(node, "c-test"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("c-test@5", ofnode_get_name(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode_unit, UTF_SCAN_FDT); + /* test ofnode_find_subnode() on the 'other' tree */ static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts) { @@ -1580,7 +1599,7 @@ static int dm_test_ofnode_delete(struct unit_test_state *uts) ut_assert(!ofnode_valid(node)); ut_assert(!ofnode_valid(ofnode_path("/leds/default_on"))); - ut_asserteq(2, ofnode_get_child_count(ofnode_path("/leds"))); + ut_asserteq(7, ofnode_get_child_count(ofnode_path("/leds"))); return 0; } diff --git a/test/dm/sysinfo.c b/test/dm/sysinfo.c index 6c0d2d7e4df..14ebe6b42e7 100644 --- a/test/dm/sysinfo.c +++ b/test/dm/sysinfo.c @@ -19,6 +19,9 @@ static int dm_test_sysinfo(struct unit_test_state *uts) bool called_detect = false; char str[64]; int i; + void *data = NULL; + size_t data_size = 0; + u32 gdata[] = {0xabcdabcd, 0xdeadbeef}; ut_assertok(sysinfo_get(&sysinfo)); ut_assert(sysinfo); @@ -57,6 +60,9 @@ static int dm_test_sysinfo(struct unit_test_state *uts) str)); ut_assertok(strcmp(str, "Yuggoth")); + ut_assertok(sysinfo_get_data(sysinfo, DATA_TEST, &data, &data_size)); + ut_assertok(memcmp(gdata, data, data_size)); + return 0; } DM_TEST(dm_test_sysinfo, UTF_SCAN_PDATA | UTF_SCAN_FDT); diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c deleted file mode 100644 index 4bc2c45db61..00000000000 --- a/test/dm/test-dm.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2013 Google, Inc - */ - -#include <test/suites.h> -#include <test/test.h> - -int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(dm_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(dm_test); - - return cmd_ut_category("driver model", "dm_test_", tests, n_ents, argc, - argv); -} diff --git a/test/dm/test-driver.c b/test/dm/test-driver.c index 851177c3018..759de3a5f77 100644 --- a/test/dm/test-driver.c +++ b/test/dm/test-driver.c @@ -35,7 +35,7 @@ static const struct test_ops test_ops = { static int test_bind(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); /* Private data should not be allocated */ ut_assert(!dev_get_priv(dev)); @@ -46,7 +46,7 @@ static int test_bind(struct udevice *dev) static int test_probe(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); struct dm_test_priv *priv = dev_get_priv(dev); /* Private data should be allocated */ @@ -59,7 +59,7 @@ static int test_probe(struct udevice *dev) static int test_remove(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); /* Private data should still be allocated */ ut_assert(dev_get_priv(dev)); @@ -70,7 +70,7 @@ static int test_remove(struct udevice *dev) static int test_unbind(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); /* Private data should not be allocated */ ut_assert(!dev_get_priv(dev)); @@ -121,7 +121,7 @@ static int test_manual_bind(struct udevice *dev) static int test_manual_probe(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); dm_testdrv_op_count[DM_TEST_OP_PROBE]++; if (!uts->force_fail_alloc) diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c index 9a80cc63667..be4108bbecb 100644 --- a/test/dm/test-uclass.c +++ b/test/dm/test-uclass.c @@ -28,7 +28,7 @@ int test_ping(struct udevice *dev, int pingval, int *pingret) static int test_post_bind(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); struct dm_test_perdev_uc_pdata *uc_pdata; dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++; @@ -54,7 +54,7 @@ static int test_pre_unbind(struct udevice *dev) static int test_pre_probe(struct udevice *dev) { struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++; ut_assert(priv); @@ -65,7 +65,7 @@ static int test_pre_probe(struct udevice *dev) static int test_post_probe(struct udevice *dev) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); struct udevice *prev = list_entry(dev->uclass_node.prev, struct udevice, uclass_node); @@ -100,7 +100,7 @@ static int test_pre_remove(struct udevice *dev) static int test_init(struct uclass *uc) { - struct unit_test_state *uts = test_get_state(); + struct unit_test_state *uts = ut_get_state(); dm_testdrv_op_count[DM_TEST_OP_INIT]++; ut_assert(uclass_get_priv(uc)); diff --git a/test/env/cmd_ut_env.c b/test/env/cmd_ut_env.c index 9f16a978f2a..81d1bb2f80d 100644 --- a/test/env/cmd_ut_env.c +++ b/test/env/cmd_ut_env.c @@ -4,7 +4,6 @@ * Joe Hershberger, National Instruments, joe.hershberger@ni.com */ -#include <command.h> #include <test/env.h> #include <test/suites.h> #include <test/ut.h> @@ -74,12 +73,3 @@ static int env_test_env_cmd(struct unit_test_state *uts) return 0; } ENV_TEST(env_test_env_cmd, UTF_CONSOLE); - -int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(env_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(env_test); - - return cmd_ut_category("environment", "env_test_", - tests, n_ents, argc, argv); -} diff --git a/test/hush/Makefile b/test/hush/Makefile index 4c3a0be857a..febdc82e8aa 100644 --- a/test/hush/Makefile +++ b/test/hush/Makefile @@ -3,7 +3,6 @@ # (C) Copyright 2021 # Francis Laniel, Amarula Solutions, francis.laniel@amarulasolutions.com -obj-y += cmd_ut_hush.o obj-y += if.o ifdef CONFIG_CONSOLE_RECORD obj-y += dollar.o diff --git a/test/hush/cmd_ut_hush.c b/test/hush/cmd_ut_hush.c deleted file mode 100644 index abad44f3216..00000000000 --- a/test/hush/cmd_ut_hush.c +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * (C) Copyright 2021 - * Francis Laniel, Amarula Solutions, francis.laniel@amarulasolutions.com - */ - -#include <command.h> -#include <test/hush.h> -#include <test/suites.h> -#include <test/ut.h> - -int do_ut_hush(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(hush_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(hush_test); - - return cmd_ut_category("hush", "hush_test_", - tests, n_ents, argc, argv); -} diff --git a/test/hush/dollar.c b/test/hush/dollar.c index 077dcd62c0e..820110799a2 100644 --- a/test/hush/dollar.c +++ b/test/hush/dollar.c @@ -108,7 +108,7 @@ static int hush_test_simple_dollar(struct unit_test_state *uts) /* Reset local variable. */ ut_assertok(run_command("dollar_foo=", 0)); } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - puts("Beware: this test set local variable dollar_foo and it cannot be unset!"); + puts("Beware: this test set local variable dollar_foo and it cannot be unset!\n"); } return 0; @@ -140,7 +140,7 @@ static int hush_test_env_dollar(struct unit_test_state *uts) /* Reset local variable. */ ut_assertok(run_command("env_foo=", 0)); } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - puts("Beware: this test set local variable env_foo and it cannot be unset!"); + puts("Beware: this test set local variable env_foo and it cannot be unset!\n"); } return 0; @@ -206,7 +206,8 @@ static int hush_test_command_dollar(struct unit_test_state *uts) ut_assertok(run_command("dollar_bar=", 0)); ut_assertok(run_command("dollar_quux=", 0)); } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - puts("Beware: this test sets local variable dollar_bar and dollar_quux and they cannot be unset!"); + puts("Beware: this test sets local variable dollar_bar and " + "dollar_quux and they cannot be unset!\n"); } return 0; diff --git a/test/hush/loop.c b/test/hush/loop.c index a9b6a8edf24..7154b9bc0ae 100644 --- a/test/hush/loop.c +++ b/test/hush/loop.c @@ -25,7 +25,7 @@ static int hush_test_for(struct unit_test_state *uts) /* Reset local variable. */ ut_assertok(run_command("loop_i=", 0)); } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - puts("Beware: this test set local variable loop_i and it cannot be unset!"); + puts("Beware: this test set local variable loop_i and it cannot be unset!\n"); } return 0; @@ -56,7 +56,7 @@ static int hush_test_while(struct unit_test_state *uts) /* Reset local variable. */ ut_assertok(run_command("loop_foo=", 0)); } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - puts("Beware: this test set local variable loop_foo and it cannot be unset!"); + puts("Beware: this test set local variable loop_foo and it cannot be unset!\n"); } return 0; diff --git a/test/lib/Makefile b/test/lib/Makefile index f516d001747..0e4cb8e3dfd 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o ifeq ($(CONFIG_XPL_BUILD),) -obj-y += cmd_ut_lib.o obj-y += abuf.o obj-y += alist.o obj-$(CONFIG_EFI_LOADER) += efi_device_path.o @@ -17,13 +16,15 @@ obj-y += lmb.o obj-$(CONFIG_HAVE_SETJMP) += longjmp.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o -obj-$(CONFIG_$(XPL_)CMDLINE) += str.o +obj-$(CONFIG_$(PHASE_)STRTO) += str.o obj-y += string.o obj-y += strlcat.o obj-$(CONFIG_ERRNO_STR) += test_errno_str.o obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o obj-$(CONFIG_AES) += test_aes.o +obj-$(CONFIG_SHA256) += test_sha256_hmac.o +obj-$(CONFIG_HKDF_MBEDTLS) += test_sha256_hkdf.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o diff --git a/test/lib/abuf.c b/test/lib/abuf.c index 7c0481ab610..b38690fe1a9 100644 --- a/test/lib/abuf.c +++ b/test/lib/abuf.c @@ -46,7 +46,29 @@ static int lib_test_abuf_set(struct unit_test_state *uts) } LIB_TEST(lib_test_abuf_set, 0); -/* Test abuf_map_sysmem() */ +/* Test abuf_init_const() */ +static int lib_test_abuf_init_const(struct unit_test_state *uts) +{ + struct abuf buf; + ulong start; + void *ptr; + + start = ut_check_free(); + + ptr = map_sysmem(0x100, 0); + + abuf_init_const(&buf, ptr, 10); + ut_asserteq_ptr(ptr, buf.data); + ut_asserteq(10, buf.size); + + /* No memory should have been allocated */ + ut_assertok(ut_check_delta(start)); + + return 0; +} +LIB_TEST(lib_test_abuf_init_const, 0); + +/* Test abuf_map_sysmem() and abuf_addr() */ static int lib_test_abuf_map_sysmem(struct unit_test_state *uts) { struct abuf buf; @@ -60,6 +82,8 @@ static int lib_test_abuf_map_sysmem(struct unit_test_state *uts) ut_asserteq(TEST_DATA_LEN, buf.size); ut_asserteq(false, buf.alloced); + ut_asserteq(addr, abuf_addr(&buf)); + return 0; } LIB_TEST(lib_test_abuf_map_sysmem, 0); diff --git a/test/lib/cmd_ut_lib.c b/test/lib/cmd_ut_lib.c deleted file mode 100644 index f98cb9b3c57..00000000000 --- a/test/lib/cmd_ut_lib.c +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de> - * - * Unit tests for library functions - */ - -#include <command.h> -#include <test/lib.h> -#include <test/suites.h> -#include <test/ut.h> - -int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(lib_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(lib_test); - - return cmd_ut_category("lib", "lib_test_", tests, n_ents, argc, argv); -} diff --git a/test/lib/test_sha256_hkdf.c b/test/lib/test_sha256_hkdf.c new file mode 100644 index 00000000000..5277b44eba5 --- /dev/null +++ b/test/lib/test_sha256_hkdf.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Philippe Reynes <philippe.reynes@softathome.com> + * + * Unit tests for sha256_hkdf functions + */ + +#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <u-boot/sha256.h> + +struct test_sha256_hkdf_s { + const unsigned char *salt; + int saltlen; + const unsigned char *ikm; + int ikmlen; + const unsigned char *info; + int infolen; + const unsigned char *expected; + int expectedlen; +}; + +/* + * data comes from: + * https://www.rfc-editor.org/rfc/rfc5869 + */ +static unsigned char salt_test1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; + +static unsigned char ikm_test1[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b +}; + +static unsigned char info_test1[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 +}; + +static unsigned char expected_test1[] = { + 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, + 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, + 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, + 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, + 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, + 0x58, 0x65 +}; + +static unsigned char salt_test2[] = { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, +}; + +static unsigned char ikm_test2[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +}; + +static unsigned char info_test2[] = { + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static unsigned char expected_test2[] = { + 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, + 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34, + 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, + 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, + 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72, + 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09, + 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, + 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71, + 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, + 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, + 0x1d, 0x87, +}; + +static unsigned char salt_test3[] = { +}; + +static unsigned char ikm_test3[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, +}; + +static unsigned char info_test3[] = { +}; + +static unsigned char expected_test3[] = { + 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, + 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31, + 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, + 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, + 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, + 0x96, 0xc8, +}; + +static struct test_sha256_hkdf_s test_sha256_hkdf[] = { + { + .salt = salt_test1, + .saltlen = sizeof(salt_test1), + .ikm = ikm_test1, + .ikmlen = sizeof(ikm_test1), + .info = info_test1, + .infolen = sizeof(info_test1), + .expected = expected_test1, + .expectedlen = sizeof(expected_test1), + }, + { + .salt = salt_test2, + .saltlen = sizeof(salt_test2), + .ikm = ikm_test2, + .ikmlen = sizeof(ikm_test2), + .info = info_test2, + .infolen = sizeof(info_test2), + .expected = expected_test2, + .expectedlen = sizeof(expected_test2), + }, + { + .salt = salt_test3, + .saltlen = sizeof(salt_test3), + .ikm = ikm_test3, + .ikmlen = sizeof(ikm_test3), + .info = info_test3, + .infolen = sizeof(info_test3), + .expected = expected_test3, + .expectedlen = sizeof(expected_test3), + }, +}; + +static int _lib_test_sha256_hkdf_run(struct unit_test_state *uts, + const unsigned char *salt, int saltlen, + const unsigned char *ikm, int ikmlen, + const unsigned char *info, int infolen, + const unsigned char *expected, + int expectedlen) +{ + unsigned char output[256]; + int ret; + + ut_assert(expectedlen <= sizeof(output)); + ret = sha256_hkdf(salt, saltlen, ikm, ikmlen, info, infolen, output, expectedlen); + ut_assert(!ret); + ut_asserteq_mem(expected, output, expectedlen); + + return 0; +} + +static int lib_test_sha256_hkdf_run(struct unit_test_state *uts, + struct test_sha256_hkdf_s *test) +{ + return _lib_test_sha256_hkdf_run(uts, test->salt, test->saltlen, + test->ikm, test->ikmlen, + test->info, test->infolen, + test->expected, test->expectedlen); +} + +static int lib_test_sha256_hkdf(struct unit_test_state *uts) +{ + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(test_sha256_hkdf); i++) { + ret = lib_test_sha256_hkdf_run(uts, &test_sha256_hkdf[i]); + if (ret) + return ret; + } + + return 0; +} + +LIB_TEST(lib_test_sha256_hkdf, 0); diff --git a/test/lib/test_sha256_hmac.c b/test/lib/test_sha256_hmac.c new file mode 100644 index 00000000000..5279dd78e0f --- /dev/null +++ b/test/lib/test_sha256_hmac.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Philippe Reynes <philippe.reynes@softathome.com> + * + * Unit tests for sha256_hmac functions + */ + +#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <u-boot/sha256.h> + +struct test_sha256_hmac_s { + const unsigned char *key; + int keylen; + const unsigned char *input; + int ilen; + const unsigned char *expected; + int elen; +}; + +/* + * data comes from: + * https://datatracker.ietf.org/doc/html/rfc4231 + */ +static unsigned char key_test1[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; + +static unsigned char input_test1[] = { + 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }; + +static unsigned char expected_test1[] = { + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, + 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, + 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, + 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 }; + +static unsigned char key_test2[] = { 0x4a, 0x65, 0x66, 0x65 }; + +static unsigned char input_test2[] = { + 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, + 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x3f }; + +static unsigned char expected_test2[] = { + 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, + 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, + 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, + 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 }; + +static unsigned char key_test3[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa }; + +static unsigned char input_test3[] = { + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd }; + +static unsigned char expected_test3[] = { + 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, + 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, + 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, + 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe }; + +static unsigned char key_test4[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, +}; + +static unsigned char input_test4[] = { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, +}; + +static unsigned char expected_test4[] = { + 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, + 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, + 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, + 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b, +}; + +static unsigned char key_test5[] = { + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, +}; + +static unsigned char input_test5[] = { + 0x54, 0x65, 0x73, 0x74, 0x20, 0x57, 0x69, 0x74, + 0x68, 0x20, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, +}; + +static unsigned char expected_test5[] = { + 0xa3, 0xb6, 0x16, 0x74, 0x73, 0x10, 0x0e, 0xe0, + 0x6e, 0x0c, 0x79, 0x6c, 0x29, 0x55, 0x55, 0x2b, +}; + +static unsigned char key_test6[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa }; + +static unsigned char input_test6[] = { + 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, + 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, + 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, + 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, + 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }; + +static unsigned char expected_test6[] = { + 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, + 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, + 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, + 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 }; + +static unsigned char key_test7[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, +}; + +static unsigned char input_test7[] = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, + 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, + 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, + 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, + 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, + 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, + 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, + 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, +}; + +static unsigned char expected_test7[] = { + 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, + 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, + 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, + 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2, +}; + +static struct test_sha256_hmac_s test_sha256_hmac[] = { + { + .key = key_test1, + .keylen = sizeof(key_test1), + .input = input_test1, + .ilen = sizeof(input_test1), + .expected = expected_test1, + .elen = sizeof(expected_test1), + }, + { + .key = key_test2, + .keylen = sizeof(key_test2), + .input = input_test2, + .ilen = sizeof(input_test2), + .expected = expected_test2, + .elen = sizeof(expected_test2), + }, + { + .key = key_test3, + .keylen = sizeof(key_test3), + .input = input_test3, + .ilen = sizeof(input_test3), + .expected = expected_test3, + .elen = sizeof(expected_test3), + }, + { + .key = key_test4, + .keylen = sizeof(key_test4), + .input = input_test4, + .ilen = sizeof(input_test4), + .expected = expected_test4, + .elen = sizeof(expected_test4), + }, + { + .key = key_test5, + .keylen = sizeof(key_test5), + .input = input_test5, + .ilen = sizeof(input_test5), + .expected = expected_test5, + .elen = sizeof(expected_test5), + }, + { + .key = key_test6, + .keylen = sizeof(key_test6), + .input = input_test6, + .ilen = sizeof(input_test6), + .expected = expected_test6, + .elen = sizeof(expected_test6), + }, + { + .key = key_test7, + .keylen = sizeof(key_test7), + .input = input_test7, + .ilen = sizeof(input_test7), + .expected = expected_test7, + .elen = sizeof(expected_test7), + }, +}; + +static int _lib_test_sha256_hmac_run(struct unit_test_state *uts, + const unsigned char *key, int keylen, + const unsigned char *input, int ilen, + const unsigned char *expected, int elen) +{ + unsigned char output[SHA256_SUM_LEN]; + int ret; + + ut_assert(elen <= sizeof(output)); + ret = sha256_hmac(key, keylen, input, ilen, output); + ut_assert(!ret); + ut_asserteq_mem(expected, output, elen); + + return 0; +} + +static int lib_test_sha256_hmac_run(struct unit_test_state *uts, + struct test_sha256_hmac_s *test) +{ + return _lib_test_sha256_hmac_run(uts, test->key, test->keylen, + test->input, test->ilen, + test->expected, test->elen); +} + +static int lib_test_sha256_hmac(struct unit_test_state *uts) +{ + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(test_sha256_hmac); i++) { + ret = lib_test_sha256_hmac_run(uts, &test_sha256_hmac[i]); + if (ret) + return ret; + } + + return 0; +} + +LIB_TEST(lib_test_sha256_hmac, 0); diff --git a/test/log/Makefile b/test/log/Makefile index 08eea70e344..24b7c46786d 100644 --- a/test/log/Makefile +++ b/test/log/Makefile @@ -7,8 +7,6 @@ obj-$(CONFIG_CMD_LOG) += log_filter.o ifdef CONFIG_UT_LOG -obj-y += log_ut.o - ifdef CONFIG_SANDBOX obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o obj-$(CONFIG_LOG_SYSLOG) += syslog_test_ndebug.o diff --git a/test/log/log_filter.c b/test/log/log_filter.c index d36e9d9714e..8622dcf2913 100644 --- a/test/log/log_filter.c +++ b/test/log/log_filter.c @@ -39,7 +39,6 @@ static int log_test_filter(struct unit_test_state *uts) #define create_filter(args, filter_num) do {\ ut_assertok(run_command("log filter-add -p " args, 0)); \ - ut_assert_skipline(); \ ut_assertok(strict_strtoul(uts->actual_str, 10, &(filter_num))); \ ut_assert_console_end(); \ } while (0) diff --git a/test/log/log_test.c b/test/log/log_test.c index 1c89df4ef18..00b442252f0 100644 --- a/test/log/log_test.c +++ b/test/log/log_test.c @@ -15,7 +15,8 @@ DECLARE_GLOBAL_DATA_PTR; /* emit some sample log records in different ways, for testing */ -static int do_log_run(struct unit_test_state *uts, int cat, const char *file) +static int do_log_run(struct unit_test_state *uts, int cat, const char *file, + const char *func) { int i; int ret, expected_ret; @@ -30,13 +31,13 @@ static int do_log_run(struct unit_test_state *uts, int cat, const char *file) for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { log(cat, i, "log %d\n", i); ret = _log(log_uc_cat(cat), i, file, 100 + i, - "func", "_log %d\n", i); + func, "_log %d\n", i); ut_asserteq(ret, expected_ret); } /* test with LOGL_COUNT flag */ for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { ret = _log(log_uc_cat(cat), i | LOGL_FORCE_DEBUG, file, 100 + i, - "func", "_log force %d\n", i); + func, "_log force %d\n", i); ut_asserteq(ret, expected_ret); } @@ -44,9 +45,10 @@ static int do_log_run(struct unit_test_state *uts, int cat, const char *file) return 0; } -#define log_run_cat(cat) do_log_run(uts, cat, "file") -#define log_run_file(file) do_log_run(uts, UCLASS_SPI, file) -#define log_run() do_log_run(uts, UCLASS_SPI, "file") +#define log_run_cat(cat) do_log_run(uts, cat, "file", "func") +#define log_run_file(file) do_log_run(uts, UCLASS_SPI, file, "func") +#define log_run_func(func) do_log_run(uts, UCLASS_SPI, "file", func) +#define log_run() do_log_run(uts, UCLASS_SPI, "file", "func") #define EXPECT_LOG BIT(0) #define EXPECT_DIRECT BIT(1) @@ -55,7 +57,7 @@ static int do_log_run(struct unit_test_state *uts, int cat, const char *file) #define EXPECT_DEBUG BIT(4) static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, - int max) + int max, const char *func) { int i; @@ -63,7 +65,8 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, if (flags & EXPECT_LOG) ut_assert_nextline(" do_log_run() log %d", i); if (flags & EXPECT_DIRECT) - ut_assert_nextline(" func() _log %d", i); + ut_assert_nextline(" %s() _log %d", func, + i); if (flags & EXPECT_DEBUG) { ut_assert_nextline("log %d", i); ut_assert_nextline("_log %d", i); @@ -71,12 +74,13 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, } if (flags & EXPECT_EXTRA) for (; i <= LOGL_MAX ; i++) - ut_assert_nextline(" func() _log %d", i); + ut_assert_nextline(" %s() _log %d", func, + i); for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { if (flags & EXPECT_FORCE) - ut_assert_nextline(" func() _log force %d", - i); + ut_assert_nextline(" %s() _log force %d", + func, i); if (flags & EXPECT_DEBUG) ut_assert_nextline("_log force %d", i); } @@ -86,7 +90,7 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, } #define check_log_entries_flags_levels(flags, min, max) do {\ - int ret = do_check_log_entries(uts, flags, min, max); \ + int ret = do_check_log_entries(uts, flags, min, max, "func"); \ if (ret) \ return ret; \ } while (0) @@ -192,6 +196,46 @@ int log_test_file_mid(struct unit_test_state *uts) } LOG_TEST_FLAGS(log_test_file_mid, UTF_CONSOLE); +/* Check passing and failing function filters */ +int log_test_func(struct unit_test_state *uts) +{ + int filt; + + filt = log_add_filter_flags("console", NULL, LOGL_MAX, "file", "func", + 0); + ut_assert(filt >= 0); + + log_run_func("func"); + check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE); + + log_run_func("fnc2"); + do_check_log_entries(uts, EXPECT_FORCE, LOGL_FIRST, _LOG_MAX_LEVEL, + "fnc2"); + + ut_assertok(log_remove_filter("console", filt)); + + return 0; +} +LOG_TEST_FLAGS(log_test_func, UTF_CONSOLE); + +/* Check a passing function filter (middle of list) */ +int log_test_func_mid(struct unit_test_state *uts) +{ + int filt; + + filt = log_add_filter_flags("console", NULL, LOGL_MAX, "file", + "bad1,func,bad2", 0); + ut_assert(filt >= 0); + + log_run_func("func"); + check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE); + + ut_assertok(log_remove_filter("console", filt)); + + return 0; +} +LOG_TEST_FLAGS(log_test_func_mid, UTF_CONSOLE); + /* Check a log level filter */ int log_test_level(struct unit_test_state *uts) { @@ -320,7 +364,7 @@ int log_test_cat_deny(struct unit_test_state *uts) filt1 = log_add_filter("console", cat_list, LOGL_MAX, NULL); ut_assert(filt1 >= 0); filt2 = log_add_filter_flags("console", cat_list, LOGL_MAX, NULL, - LOGFF_DENY); + NULL, LOGFF_DENY); ut_assert(filt2 >= 0); log_run_cat(UCLASS_SPI); @@ -340,7 +384,7 @@ int log_test_file_deny(struct unit_test_state *uts) filt1 = log_add_filter("console", NULL, LOGL_MAX, "file"); ut_assert(filt1 >= 0); filt2 = log_add_filter_flags("console", NULL, LOGL_MAX, "file", - LOGFF_DENY); + NULL, LOGFF_DENY); ut_assert(filt2 >= 0); log_run_file("file"); @@ -360,7 +404,7 @@ int log_test_level_deny(struct unit_test_state *uts) filt1 = log_add_filter("console", NULL, LOGL_INFO, NULL); ut_assert(filt1 >= 0); filt2 = log_add_filter_flags("console", NULL, LOGL_WARNING, NULL, - LOGFF_DENY); + NULL, LOGFF_DENY); ut_assert(filt2 >= 0); log_run(); @@ -380,10 +424,10 @@ int log_test_min(struct unit_test_state *uts) int filt1, filt2; filt1 = log_add_filter_flags("console", NULL, LOGL_WARNING, NULL, - LOGFF_LEVEL_MIN); + NULL, LOGFF_LEVEL_MIN); ut_assert(filt1 >= 0); filt2 = log_add_filter_flags("console", NULL, LOGL_INFO, NULL, - LOGFF_DENY | LOGFF_LEVEL_MIN); + NULL, LOGFF_DENY | LOGFF_LEVEL_MIN); ut_assert(filt2 >= 0); log_run(); diff --git a/test/log/log_ut.c b/test/log/log_ut.c deleted file mode 100644 index 6617ed8b152..00000000000 --- a/test/log/log_ut.c +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> - * - * Logging function tests. - */ - -#include <console.h> -#include <log.h> -#include <test/log.h> -#include <test/suites.h> - -int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(log_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(log_test); - - return cmd_ut_category("log", "log_test_", - tests, n_ents, argc, argv); -} diff --git a/test/optee/cmd_ut_optee.c b/test/optee/cmd_ut_optee.c index c6f50e0995a..fc6674764f9 100644 --- a/test/optee/cmd_ut_optee.c +++ b/test/optee/cmd_ut_optee.c @@ -93,8 +93,8 @@ OPTEE_TEST(optee_fdt_protected_memory, 0); int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - struct unit_test *tests = UNIT_TEST_SUITE_START(optee_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(optee_test); + 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; diff --git a/test/overlay/cmd_ut_overlay.c b/test/overlay/cmd_ut_overlay.c index 256afd115d2..aefa147ec04 100644 --- a/test/overlay/cmd_ut_overlay.c +++ b/test/overlay/cmd_ut_overlay.c @@ -210,21 +210,17 @@ static int fdt_overlay_stacked(struct unit_test_state *uts) } OVERLAY_TEST(fdt_overlay_stacked, 0); -int do_ut_overlay(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[]) { - struct unit_test *tests = UNIT_TEST_SUITE_START(overlay_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(overlay_test); - 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; - uts = calloc(1, sizeof(*uts)); - if (!uts) - return -ENOMEM; - ut_assertok(fdt_check_header(fdt_base)); ut_assertok(fdt_check_header(fdt_overlay)); @@ -272,7 +268,7 @@ int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Apply the stacked overlay */ ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_stacked_copy)); - ret = cmd_ut_category("overlay", "", tests, n_ents, argc, argv); + ret = cmd_ut_category(uts, "overlay", "", tests, n_ents, argc, argv); free(fdt_overlay_stacked_copy); err3: diff --git a/test/py/conftest.py b/test/py/conftest.py index 509d19b449d..31043a697e2 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -25,6 +25,7 @@ import re from _pytest.runner import runtestprotocol import subprocess import sys +import time from u_boot_spawn import BootFail, Timeout, Unexpected, handle_exception # Globals: The HTML log file, and the connection to the U-Boot console. @@ -33,6 +34,9 @@ console = None TEST_PY_DIR = os.path.dirname(os.path.abspath(__file__)) +# Regex for test-function symbols +RE_UT_TEST_LIST = re.compile(r'[^a-zA-Z0-9_]_u_boot_list_2_ut_(.*)_2_(.*)\s*$') + def mkdir_p(path): """Create a directory path. @@ -88,6 +92,9 @@ def pytest_addoption(parser): parser.addoption('--role', help='U-Boot board role (for Labgrid-sjg)') parser.addoption('--use-running-system', default=False, action='store_true', help="Assume that U-Boot is ready and don't wait for a prompt") + parser.addoption('--timing', default=False, action='store_true', + help='Show info on test timing') + def run_build(config, source_dir, build_dir, board_type, log): """run_build: Build U-Boot @@ -158,10 +165,15 @@ def get_details(config): env['U_BOOT_BUILD_DIR'] = build_dir if build_dir_extra: env['U_BOOT_BUILD_DIR_EXTRA'] = build_dir_extra - proc = subprocess.run(cmd, capture_output=True, encoding='utf-8', + + # Make sure the script sees that it is being run from pytest + env['U_BOOT_SOURCE_DIR'] = source_dir + + proc = subprocess.run(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, encoding='utf-8', env=env) if proc.returncode: - raise ValueError(proc.stderr) + raise ValueError(f"Error {proc.returncode} running {cmd}: '{proc.stderr} '{proc.stdout}'") # For debugging # print('conftest: lab:', proc.stdout) vals = {} @@ -314,6 +326,7 @@ def pytest_configure(config): ubconfig.use_running_system = config.getoption('use_running_system') ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb' ubconfig.connection_ok = True + ubconfig.timing = config.getoption('timing') env_vars = ( 'board_type', @@ -336,7 +349,7 @@ def pytest_configure(config): import u_boot_console_exec_attach console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig) -re_ut_test_list = re.compile(r'[^a-zA-Z0-9_]_u_boot_list_2_ut_(.*)_test_2_(.*)\s*$') + def generate_ut_subtest(metafunc, fixture_name, sym_path): """Provide parametrization for a ut_subtest fixture. @@ -363,7 +376,7 @@ def generate_ut_subtest(metafunc, fixture_name, sym_path): vals = [] for l in lines: - m = re_ut_test_list.search(l) + m = RE_UT_TEST_LIST.search(l) if not m: continue suite, name = m.groups() @@ -508,6 +521,12 @@ tests_skipped = [] tests_warning = [] tests_passed = [] +# Duration of each test: +# key (string): test name +# value (float): duration in ms +test_durations = {} + + def pytest_itemcollected(item): """pytest hook: Called once for each test found during collection. @@ -523,6 +542,73 @@ def pytest_itemcollected(item): tests_not_run.append(item.name) + +def show_timings(): + """Write timings for each test, along with a histogram""" + + def get_time_delta(msecs): + """Convert milliseconds into a user-friendly string""" + if msecs >= 1000: + return f'{msecs / 1000:.1f}s' + else: + return f'{msecs:.0f}ms' + + def show_bar(key, msecs, value): + """Show a single bar (line) of the histogram + + Args: + key (str): Key to write on the left + value (int): Value to display, i.e. the relative length of the bar + """ + if value: + bar_length = int((value / max_count) * max_bar_length) + print(f"{key:>8} : {get_time_delta(msecs):>7} |{'#' * bar_length} {value}", file=buf) + + # Create the buckets we will use, each has a count and a total time + bucket = {} + for power in range(5): + for i in [1, 2, 3, 4, 5, 7.5]: + bucket[i * 10 ** power] = {'count': 0, 'msecs': 0.0} + max_dur = max(bucket.keys()) + + # Collect counts for each bucket; if outside the range, add to too_long + # Also show a sorted list of test timings from longest to shortest + too_long = 0 + too_long_msecs = 0.0 + max_count = 0 + with log.section('Timing Report', 'timing_report'): + for name, dur in sorted(test_durations.items(), key=lambda kv: kv[1], + reverse=True): + log.info(f'{get_time_delta(dur):>8} {name}') + greater = [k for k in bucket.keys() if dur <= k] + if greater: + buck = bucket[min(greater)] + buck['count'] += 1 + max_count = max(max_count, buck['count']) + buck['msecs'] += dur + else: + too_long += 1 + too_long_msecs += dur + + # Set the maximum length of a histogram bar, in characters + max_bar_length = 40 + + # Show a a summary with histogram + buf = io.StringIO() + with log.section('Timing Summary', 'timing_summary'): + print('Duration : Total | Number of tests', file=buf) + print(f'{"=" * 8} : {"=" * 7} |{"=" * max_bar_length}', file=buf) + for dur, buck in bucket.items(): + if buck['count']: + label = get_time_delta(dur) + show_bar(f'<{label}', buck['msecs'], buck['count']) + if too_long: + show_bar(f'>{get_time_delta(max_dur)}', too_long_msecs, too_long) + log.info(buf.getvalue()) + if ubconfig.timing: + print(buf.getvalue(), end='') + + def cleanup(): """Clean up all global state. @@ -572,6 +658,7 @@ def cleanup(): for test in tests_not_run: anchor = anchors.get(test, None) log.status_fail('... ' + test, anchor) + show_timings() log.close() atexit.register(cleanup) @@ -705,7 +792,9 @@ def pytest_runtest_protocol(item, nextitem): log.get_and_reset_warning() ihook = item.ihook ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location) + start = time.monotonic() reports = runtestprotocol(item, nextitem=nextitem) + duration = round((time.monotonic() - start) * 1000, 1) ihook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location) was_warning = log.get_and_reset_warning() @@ -718,6 +807,7 @@ def pytest_runtest_protocol(item, nextitem): start_test_section(item) failure_cleanup = False + record_duration = True if not was_warning: test_list = tests_passed msg = 'OK' @@ -748,6 +838,11 @@ def pytest_runtest_protocol(item, nextitem): test_list = tests_skipped msg = 'SKIPPED:\n' + str(report.longrepr) msg_log = log.status_skipped + record_duration = False + + msg += f' {duration} ms' + if record_duration: + test_durations[item.name] = duration if failure_cleanup: console.drain_console() diff --git a/test/py/tests/test_extension.py b/test/py/tests/test_extension.py index 267cf2ff27c..2a3c5116171 100644 --- a/test/py/tests/test_extension.py +++ b/test/py/tests/test_extension.py @@ -26,7 +26,9 @@ def test_extension(u_boot_console): load_dtb(u_boot_console) output = u_boot_console.run_command('extension list') - assert('No extension' in output) + # extension_bootdev_hunt may have already run. + # Without reboot we cannot make any assumption here. + # assert('No extension' in output) output = u_boot_console.run_command('extension scan') assert output == 'Found 2 extension board(s).' diff --git a/test/py/tests/test_smbios.py b/test/py/tests/test_smbios.py index 82b0b689830..0405a9b9d38 100644 --- a/test/py/tests/test_smbios.py +++ b/test/py/tests/test_smbios.py @@ -32,10 +32,26 @@ def test_cmd_smbios_sandbox(u_boot_console): """Run the smbios command on the sandbox""" output = u_boot_console.run_command('smbios') assert 'DMI type 0,' in output - assert 'String 1: U-Boot' in output + assert 'Vendor: U-Boot' in output assert 'DMI type 1,' in output assert 'Manufacturer: sandbox' in output assert 'DMI type 2,' in output assert 'DMI type 3,' in output assert 'DMI type 4,' in output assert 'DMI type 127,' in output + +@pytest.mark.buildconfigspec('cmd_smbios') +@pytest.mark.buildconfigspec('sysinfo_smbios') +@pytest.mark.buildconfigspec('generate_smbios_table_verbose') +def test_cmd_smbios_sysinfo_verbose(u_boot_console): + """Run the smbios command""" + output = u_boot_console.run_command('smbios') + assert 'DMI type 0,' in output + assert 'Vendor: U-Boot' in output + assert 'DMI type 1,' in output + assert 'Manufacturer: linux' in output + assert 'DMI type 2,' in output + assert 'DMI type 3,' in output + assert 'DMI type 7,' in output + assert 'DMI type 4,' in output + assert 'DMI type 127,' in output diff --git a/test/py/tests/test_spl.py b/test/py/tests/test_spl.py index 42e4c4342b2..474f430a344 100644 --- a/test/py/tests/test_spl.py +++ b/test/py/tests/test_spl.py @@ -36,7 +36,7 @@ def test_spl(u_boot_console, ut_spl_subtest): cons = u_boot_console cons.restart_uboot_with_flags(['-u', '-k', ut_spl_subtest.split()[1]]) output = cons.get_spawn_output().replace('\r', '') - assert 'Failures: 0' in output + assert 'failures: 0' in output finally: # Restart afterward in case a non-SPL test is run next. This should not # happen since SPL tests are run in their own invocation of test.py, but diff --git a/test/py/tests/test_suite.py b/test/py/tests/test_suite.py new file mode 100644 index 00000000000..73c185349b4 --- /dev/null +++ b/test/py/tests/test_suite.py @@ -0,0 +1,188 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright 2024 Google LLC + +import pytest +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', + 'fdt', 'font', 'hush', 'lib', + 'loadm', 'log', 'mbr', 'measurement', 'mem', + 'overlay', 'pci_mps', 'setexpr', 'upl', + ] + + +# Set this to True to aid debugging of tests +DEBUG_ME = False + + +def collect_info(cons, output): + """Process the output from 'ut all' + + Args: + cons: U-Boot console object + output: Output from running 'ut all' + + Returns: + tuple: + set: suite names that were found in output + set: test names that were found in output + dict: test count for each suite: + key: suite name + value: number of tests for the suite found in output + set: missing suites (compared to EXPECTED_SUITES) + set: extra suites (compared to EXPECTED_SUITES) + """ + suites = set() + tests = set() + cur_suite = None + test_count = None + exp_test_count = {} + + # Collect suites{} + for line in output.splitlines(): + line = line.rstrip() + if DEBUG_ME: + cons.log.info(f'line: {line}') + m = re.search('----Running ([^ ]*) tests----', line) + if m: + if DEBUG_ME and cur_suite and cur_suite != 'info': + cons.log.info(f'suite: {cur_suite} expected {exp_test_count[cur_suite]} found {test_count}') + + cur_suite = m.group(1) + if DEBUG_ME: + cons.log.info(f'cur_suite: {cur_suite}') + suites.add(cur_suite) + + test_count = 0 + m = re.match(rf'Running (\d+) {cur_suite} tests', line) + if m: + exp_test_count[cur_suite] = int(m.group(1)) + m = re.search(r'Test: (\w*): ([-a-z0-9_]*\.c)?( .*)?', line) + if m: + test_name = m.group(1) + 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) + test_count += 1 + if not msg or 'skipped as it is manual' in msg: + tests.add(test_name) + test_count += 1 + if DEBUG_ME: + cons.log.info(f'test_count {test_count}') + if DEBUG_ME: + cons.log.info(f'suite: {cur_suite} expected {exp_test_count[cur_suite]} found {test_count}') + cons.log.info(f"Tests: {' '.join(sorted(list(tests)))}") + + # Figure out what is missing, or extra + missing = set() + extra = set(suites) + for suite in EXPECTED_SUITES: + if suite in extra: + extra.remove(suite) + else: + missing.add(suite) + + return suites, tests, exp_test_count, missing, extra + + +def process_ut_info(cons, output): + """Process the output of the 'ut info' command + + Args: + cons: U-Boot console object + output: Output from running 'ut all' + + Returns: + tuple: + int: Number of suites reported + int: Number of tests reported + dict: test count for each suite: + key: suite name + value: number of tests reported for the suite + + """ + suite_count = None + total_test_count = None + test_count = {} + for line in output.splitlines(): + line = line.rstrip() + if DEBUG_ME: + cons.log.info(f'line: {line}') + m = re.match(r'Test suites: (.*)', line) + if m: + suite_count = int(m.group(1)) + m = re.match(r'Total tests: (.*)', line) + if m: + total_test_count = int(m.group(1)) + m = re.match(r' *([0-9?]*) (\w*)', line) + if m: + test_count[m.group(2)] = m.group(1) + return suite_count, total_test_count, test_count + + +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.notbuildconfigspec('sandbox_spl') +@pytest.mark.notbuildconfigspec('sandbox64') +# This test is disabled since it fails; remove the leading 'x' to try it +def xtest_suite(u_boot_console, u_boot_config): + """Perform various checks on the unit tests, including: + + - 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' + - The total number of tests adds up to the total that are actually run + with 'ut all' + - All suites are run with 'ut all' + - The expected set of suites is run (the list is hard-coded in this test) + + """ + cons = u_boot_console + buildconfig = u_boot_config.buildconfig + with cons.log.section('Run all unit tests'): + # ut hush hush_test_simple_dollar prints "Unknown command" on purpose. + with u_boot_console.disable_check('unknown_command'): + output = cons.run_command('ut all') + + # Process the output from the run + with cons.log.section('Check output'): + suites, all_tests, exp_test_count, missing, extra = collect_info(cons, + output) + cons.log.info(f'missing {missing}') + cons.log.info(f'extra {extra}') + + # Make sure we got a test count for each suite + assert not (suites - exp_test_count.keys()) + + # Deal with missing suites + with cons.log.section('Check missing suites'): + if 'config_cmd_seama' not in buildconfig: + cons.log.info("CMD_SEAMA not enabled: Ignoring suite 'seama'") + missing.discard('seama') + + # Run 'ut info' and compare with the log results + with cons.log.section('Check suite test-counts'): + output = cons.run_command('ut info -s') + + suite_count, total_test_count, test_count = process_ut_info(cons, + output) + + if missing or extra: + cons.log.info(f"suites: {' '.join(sorted(list(suites)))}") + cons.log.error(f'missing: {sorted(list(missing))}') + cons.log.error(f'extra: {sorted(list(extra))}') + + assert not missing, f'Missing suites {missing}' + assert not extra, f'Extra suites {extra}' + + cons.log.info(str(exp_test_count)) + for suite in EXPECTED_SUITES: + assert test_count[suite] in ['?', str(exp_test_count[suite])], \ + f'suite {suite} expected {exp_test_count[suite]}' + + assert suite_count == len(EXPECTED_SUITES) + assert total_test_count == len(all_tests) diff --git a/test/py/tests/test_upl.py b/test/py/tests/test_upl.py index 3164bda6b71..a1ccc8df233 100644 --- a/test/py/tests/test_upl.py +++ b/test/py/tests/test_upl.py @@ -17,7 +17,7 @@ def test_upl_handoff(u_boot_console): proper and runs a test to check that the parameters are correct. The entire FIT is loaded into memory in SPL (in upl_load_from_image()) so - that it can be inpected in upl_test_info_norun + that it can be inspected in upl_test_info_norun """ cons = u_boot_console ram = os.path.join(cons.config.build_dir, 'ram.bin') @@ -35,4 +35,4 @@ def test_upl_handoff(u_boot_console): # Check the FIT offsets look correct output = cons.run_command('ut upl -f upl_test_info_norun') - assert 'Failures: 0' in output + assert 'failures: 0' in output diff --git a/test/py/tests/test_usb.py b/test/py/tests/test_usb.py index e1f203b5cbc..566d73b7c64 100644 --- a/test/py/tests/test_usb.py +++ b/test/py/tests/test_usb.py @@ -242,7 +242,7 @@ def test_usb_part(u_boot_console): elif part_type == '83': print('ext(2/4) detected') output = u_boot_console.run_command( - 'fstype usb %d:%d' % i, part_id + 'fstype usb %d:%d' % (i, part_id) ) if 'ext2' in output: part_ext2.append(part_id) diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 10ec7e582e0..d2d8ce10755 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -343,9 +343,10 @@ def setup_cros_image(cons): start, size, num, name = line.split(maxsplit=3) parts[int(num)] = Partition(int(start), int(size), name) + # Set up the kernel command-line dummy = os.path.join(cons.config.result_dir, 'dummy.txt') with open(dummy, 'wb') as outf: - outf.write(b'dummy\n') + outf.write(b'BOOT_IMAGE=/vmlinuz-5.15.0-121-generic root=/dev/nvme0n1p1 ro quiet splash vt.handoff=7') # For now we just use dummy kernels. This limits testing to just detecting # a signed kernel. We could add support for the x86 data structures so that @@ -606,4 +607,4 @@ def test_ut(u_boot_console, ut_subtest): assert 'Unknown command \'quux\' - try \'help\'' in output else: output = u_boot_console.run_command('ut ' + ut_subtest) - assert output.endswith('Failures: 0') + assert output.endswith('failures: 0') diff --git a/test/py/tests/test_vbe.py b/test/py/tests/test_vbe.py index 50b6c1cd911..861df3f8266 100644 --- a/test/py/tests/test_vbe.py +++ b/test/py/tests/test_vbe.py @@ -117,4 +117,4 @@ def test_vbe(u_boot_console): with cons.log.section('Kernel load'): output = cons.run_command_list(cmd.splitlines()) - assert 'Failures: 0' in output[-1] + assert 'failures: 0' in output[-1] diff --git a/test/py/tests/test_vpl.py b/test/py/tests/test_vpl.py index 4af578b9173..8c472ca7a92 100644 --- a/test/py/tests/test_vpl.py +++ b/test/py/tests/test_vpl.py @@ -26,7 +26,7 @@ def test_vpl(u_boot_console, ut_vpl_subtest): cons = u_boot_console cons.restart_uboot_with_flags(['-u', '-k', ut_vpl_subtest.split()[1]]) output = cons.get_spawn_output().replace('\r', '') - assert 'Failures: 0' in output + assert 'failures: 0' in output finally: # Restart afterward in case a non-VPL test is run next. This should not # happen since VPL tests are run in their own invocation of test.py, but diff --git a/test/test-main.c b/test/test-main.c index 8d764892fa6..22b9b46d9cd 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -63,16 +63,29 @@ static enum fdtchk_t fdt_action(void) /* This is valid when a test is running, NULL otherwise */ static struct unit_test_state *cur_test_state; -struct unit_test_state *test_get_state(void) +struct unit_test_state *ut_get_state(void) { return cur_test_state; } -void test_set_state(struct unit_test_state *uts) +void ut_set_state(struct unit_test_state *uts) { cur_test_state = uts; } +void ut_init_state(struct unit_test_state *uts) +{ + memset(uts, '\0', sizeof(*uts)); +} + +void ut_uninit_state(struct unit_test_state *uts) +{ + if (IS_ENABLED(CONFIG_SANDBOX)) { + os_free(uts->fdt_copy); + os_free(uts->other_fdt); + } +} + /** * dm_test_pre_run() - Get ready to run a driver model test * @@ -435,7 +448,7 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test) */ static int skip_test(struct unit_test_state *uts) { - uts->skip_count++; + uts->cur.skip_count++; return -EAGAIN; } @@ -447,7 +460,7 @@ static int skip_test(struct unit_test_state *uts) * the name of each test before running it. * * @uts: Test state to update. The caller should ensure that this is zeroed for - * the first call to this function. On exit, @uts->fail_count is + * the first call to this function. On exit, @uts->cur.fail_count is * incremented by the number of failures (0, one hopes) * @test_name: Test to run * @name: Name of test, possibly skipping a prefix that should not be displayed @@ -466,7 +479,7 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, printf("Test: %s: %s%s\n", test_name, fname, note); /* Allow access to test state from drivers */ - test_set_state(uts); + ut_set_state(uts); ret = test_pre_run(uts, test); if (ret == -EAGAIN) @@ -482,7 +495,7 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, if (ret) return ret; - test_set_state( NULL); + ut_set_state(NULL); return 0; } @@ -497,7 +510,7 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, * SPL. * * @uts: Test state to update. The caller should ensure that this is zeroed for - * the first call to this function. On exit, @uts->fail_count is + * 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 * Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if @@ -561,7 +574,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, * the name of each test before running it. * * @uts: Test state to update. The caller should ensure that this is zeroed for - * the first call to this function. On exit, @uts->fail_count is + * the first call to this function. On exit, @uts->cur.fail_count is * incremented by the number of failures (0, one hopes) * @prefix: String prefix for the tests. Any tests that have this prefix will be * printed without the prefix, so that it is easier to see the unique part @@ -619,34 +632,34 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, if (len < 6 || strcmp(test_name + len - 6, "_norun")) { printf("Test '%s' is manual so must have a name ending in _norun\n", test_name); - uts->fail_count++; + uts->cur.fail_count++; return -EBADF; } if (!uts->force_run) { - if (select_name) { - printf("Test '%s' skipped as it is manual (use -f to run it)\n", - test_name); - } + printf("Test: %s: skipped as it is manual (use -f to run it)\n", + test_name); continue; } } - old_fail_count = uts->fail_count; + old_fail_count = uts->cur.fail_count; + uts->cur.test_count++; if (one && upto == pos) { ret = ut_run_test_live_flat(uts, one); - if (uts->fail_count != old_fail_count) { + if (uts->cur.fail_count != old_fail_count) { printf("Test '%s' failed %d times (position %d)\n", one->name, - uts->fail_count - old_fail_count, pos); + uts->cur.fail_count - old_fail_count, + pos); } return -EBADF; } for (i = 0; i < uts->runs_per_test; i++) ret = ut_run_test_live_flat(uts, test); - if (uts->fail_count != old_fail_count) { + if (uts->cur.fail_count != old_fail_count) { printf("Test '%s' failed %d times\n", test_name, - uts->fail_count - old_fail_count); + uts->cur.fail_count - old_fail_count); } found++; if (ret == -EAGAIN) @@ -657,17 +670,32 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, if (select_name && !found) return -ENOENT; - return uts->fail_count ? -EBADF : 0; + return uts->cur.fail_count ? -EBADF : 0; } -int ut_run_list(const char *category, const char *prefix, - struct unit_test *tests, int count, const char *select_name, - int runs_per_test, bool force_run, const char *test_insert) +void ut_report(struct ut_stats *stats, int run_count) { - struct unit_test_state uts = { .fail_count = 0 }; + if (run_count > 1) + printf("Suites run: %d, total tests", run_count); + else + printf("Tests"); + printf(" run: %d, ", stats->test_count); + if (stats->skip_count) + printf("skipped: %d, ", stats->skip_count); + printf("failures: %d\n", stats->fail_count); +} + +int ut_run_list(struct unit_test_state *uts, const char *category, + const char *prefix, struct unit_test *tests, int count, + const char *select_name, int runs_per_test, bool force_run, + const char *test_insert) +{ + ; bool has_dm_tests = false; int ret; + memset(&uts->cur, '\0', sizeof(struct ut_stats)); + if (!CONFIG_IS_ENABLED(OF_PLATDATA) && ut_list_has_dm_tests(tests, count, prefix, select_name)) { has_dm_tests = true; @@ -685,35 +713,33 @@ int ut_run_list(const char *category, const char *prefix, if (!select_name) printf("Running %d %s tests\n", count, category); - uts.of_root = gd_of_root(); - uts.runs_per_test = runs_per_test; + uts->of_root = gd_of_root(); + uts->runs_per_test = runs_per_test; if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) { - uts.fdt_size = fdt_totalsize(gd->fdt_blob); - uts.fdt_copy = os_malloc(uts.fdt_size); - if (!uts.fdt_copy) { + uts->fdt_size = fdt_totalsize(gd->fdt_blob); + uts->fdt_copy = os_malloc(uts->fdt_size); + if (!uts->fdt_copy) { printf("Out of memory for device tree copy\n"); return -ENOMEM; } - memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size); + memcpy(uts->fdt_copy, gd->fdt_blob, uts->fdt_size); } - uts.force_run = force_run; - ret = ut_run_tests(&uts, prefix, tests, count, select_name, + uts->force_run = force_run; + ret = ut_run_tests(uts, prefix, tests, count, select_name, test_insert); /* Best efforts only...ignore errors */ if (has_dm_tests) - dm_test_restore(uts.of_root); - if (IS_ENABLED(CONFIG_SANDBOX)) { - os_free(uts.fdt_copy); - os_free(uts.other_fdt); - } + dm_test_restore(uts->of_root); - if (uts.skip_count) - printf("Skipped: %d, ", uts.skip_count); + ut_report(&uts->cur, 1); if (ret == -ENOENT) printf("Test '%s' not found\n", select_name); - else - printf("Failures: %d\n", uts.fail_count); + + 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->run_count++; return ret; } diff --git a/test/ut.c b/test/ut.c index 7454da3e001..a16fdfb3a93 100644 --- a/test/ut.c +++ b/test/ut.c @@ -21,7 +21,7 @@ void ut_fail(struct unit_test_state *uts, const char *fname, int line, { gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); printf("%s:%d, %s(): %s\n", fname, line, func, cond); - uts->fail_count++; + uts->cur.fail_count++; } void ut_failf(struct unit_test_state *uts, const char *fname, int line, @@ -35,7 +35,7 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, vprintf(fmt, args); va_end(args); putc('\n'); - uts->fail_count++; + uts->cur.fail_count++; } ulong ut_check_free(void) |