summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile10
-rw-r--r--test/boot/Makefile3
-rw-r--r--test/boot/bootdev.c18
-rw-r--r--test/boot/bootflow.c80
-rw-r--r--test/boot/bootm.c (renamed from test/bootm.c)21
-rw-r--r--test/cmd/Makefile3
-rw-r--r--test/cmd/command.c108
-rw-r--r--test/cmd/coreboot.c119
-rw-r--r--test/cmd/hash.c101
-rw-r--r--test/cmd_ut.c25
-rw-r--r--test/command_ut.c104
-rw-r--r--test/common.sh20
-rw-r--r--test/common/Makefile4
-rw-r--r--test/common/bloblist.c (renamed from test/bloblist.c)31
-rw-r--r--test/common/print.c (renamed from test/print_ut.c)27
-rw-r--r--test/dm/core.c22
-rw-r--r--test/lib/Makefile8
-rw-r--r--test/lib/alist.c253
-rw-r--r--test/lib/compression.c (renamed from test/compression.c)39
-rw-r--r--test/lib/str.c (renamed from test/str_ut.c)31
-rw-r--r--test/lib/time.c (renamed from test/time_ut.c)60
-rw-r--r--test/lib/unicode.c (renamed from test/unicode_ut.c)70
-rw-r--r--test/py/conftest.py73
-rw-r--r--test/py/tests/bootstd/flash1.img.xzbin0 -> 4924 bytes
-rw-r--r--test/py/tests/test_spi.py2
-rw-r--r--test/py/tests/test_usb.py171
-rw-r--r--test/py/tests/test_ut.py55
-rw-r--r--test/py/u_boot_console_base.py123
-rw-r--r--test/py/u_boot_console_exec_attach.py31
-rw-r--r--test/py/u_boot_spawn.py44
-rw-r--r--test/test-main.c39
-rwxr-xr-xtest/trace/test-trace.sh64
32 files changed, 1201 insertions, 558 deletions
diff --git a/test/Makefile b/test/Makefile
index 145c952d2c3..47a07d653a9 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -4,14 +4,8 @@
obj-y += test-main.o
-ifneq ($(CONFIG_$(XPL_)BLOBLIST),)
-obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o
-endif
obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/
obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_ut.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += command_ut.o
-obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o
obj-y += dm/
obj-$(CONFIG_FUZZ) += fuzz/
ifndef CONFIG_SANDBOX_VPL
@@ -20,16 +14,12 @@ endif
ifneq ($(CONFIG_HUSH_PARSER),)
obj-$(CONFIG_$(XPL_)CMDLINE) += hush/
endif
-obj-$(CONFIG_$(XPL_)CMDLINE) += print_ut.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += str_ut.o
-obj-$(CONFIG_UT_TIME) += time_ut.o
obj-y += ut.o
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += boot/
obj-$(CONFIG_UNIT_TEST) += common/
obj-y += log/
-obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode_ut.o
else
obj-$(CONFIG_SPL_UT_LOAD) += image/
endif
diff --git a/test/boot/Makefile b/test/boot/Makefile
index d8eded20d4f..63487e8d29e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -10,6 +10,9 @@ obj-$(CONFIG_EXPO) += expo.o
obj-$(CONFIG_CEDIT) += cedit.o
endif
+ifdef CONFIG_SANDBOX
+obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o
+endif
obj-$(CONFIG_MEASURED_BOOT) += measurement.o
ifdef CONFIG_OF_LIVE
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 369c611d924..8c44afd9297 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -221,6 +221,10 @@ static int bootdev_test_order(struct unit_test_state *uts)
/* Use the environment variable to override it */
ut_assertok(env_set("boot_targets", "mmc1 mmc2 usb"));
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
+
+ /* get the usb device which has a backing file (flash1.img) */
+ ut_asserteq(0, bootflow_scan_next(&iter, &bflow));
+
ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
ut_asserteq(5, iter.num_devs);
ut_asserteq_str("mmc1.bootdev", iter.dev_used[0]->name);
@@ -260,7 +264,11 @@ static int bootdev_test_order(struct unit_test_state *uts)
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
ut_asserteq(2, iter.num_devs);
- /* Now scan past mmc1 and make sure that the 3 USB devices show up */
+ /*
+ * Now scan past mmc1 and make sure that the 3 USB devices show up. The
+ * first one has a backing file so returns success
+ */
+ ut_asserteq(0, bootflow_scan_next(&iter, &bflow));
ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
ut_asserteq(6, iter.num_devs);
ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
@@ -322,6 +330,10 @@ static int bootdev_test_prio(struct unit_test_state *uts)
/* 3 MMC and 3 USB bootdevs: MMC should come before USB */
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
+
+ /* get the usb device which has a backing file (flash1.img) */
+ ut_asserteq(0, bootflow_scan_next(&iter, &bflow));
+
ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
ut_asserteq(6, iter.num_devs);
ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
@@ -339,6 +351,10 @@ static int bootdev_test_prio(struct unit_test_state *uts)
bootflow_iter_uninit(&iter);
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWIF_HUNT,
&bflow));
+
+ /* get the usb device which has a backing file (flash1.img) */
+ ut_asserteq(0, bootflow_scan_next(&iter, &bflow));
+
ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
ut_asserteq(7, iter.num_devs);
ut_asserteq_str("usb_mass_storage.lun0.bootdev",
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 0d4e966892e..9397328609d 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -12,7 +12,8 @@
#include <bootstd.h>
#include <cli.h>
#include <dm.h>
-#include <efi_default_filename.h>
+#include <efi.h>
+#include <efi_loader.h>
#include <expo.h>
#ifdef CONFIG_SANDBOX
#include <asm/test.h>
@@ -31,6 +32,9 @@ extern U_BOOT_DRIVER(bootmeth_android);
extern U_BOOT_DRIVER(bootmeth_cros);
extern U_BOOT_DRIVER(bootmeth_2script);
+/* Use this as the vendor for EFI to tell the app to exit boot services */
+static u16 __efi_runtime_data test_vendor[] = u"U-Boot testing";
+
static int inject_response(struct unit_test_state *uts)
{
/*
@@ -184,8 +188,9 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts)
ut_assert_nextline(" 3 efi media mmc 0 mmc1.bootdev.whole ");
ut_assert_nextline(" ** No partition found, err=-2: No such file or directory");
ut_assert_nextline(" 4 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
- ut_assert_nextline(" 5 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/"
- BOOTEFI_NAME);
+ ut_assert_nextline(
+ " 5 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/%s",
+ efi_get_basename());
ut_assert_skip_to_line("Scanning bootdev 'mmc0.bootdev':");
ut_assert_skip_to_line(
@@ -370,7 +375,7 @@ static int bootflow_iter(struct unit_test_state *uts)
return 0;
}
-BOOTSTD_TEST(bootflow_iter, UTF_DM | UTF_SCAN_FDT);
+BOOTSTD_TEST(bootflow_iter, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
#if defined(CONFIG_SANDBOX) && defined(CONFIG_BOOTMETH_GLOBAL)
/* Check using the system bootdev */
@@ -533,7 +538,7 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
order[2] = mmc_dev;
- /* Enable the mmc4 node since we need a second bootflow */
+ /* Enable the requested mmc node since we need a second bootflow */
root = oftree_root(oftree_default());
node = ofnode_find_subnode(root, mmc_dev);
ut_assert(ofnode_valid(node));
@@ -542,7 +547,7 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
/* Enable the script bootmeth too */
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_2script),
- "bootmeth_script", 0, ofnode_null(), &dev));
+ "script", 0, ofnode_null(), &dev));
/* Enable the cros bootmeth if needed */
if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros_android) {
@@ -1216,3 +1221,66 @@ static int bootflow_android(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(bootflow_android, UTF_CONSOLE);
+
+/* Test EFI bootmeth */
+static int bootflow_efi(struct unit_test_state *uts)
+{
+ static const char *order[] = {"mmc1", "usb", NULL};
+ struct bootstd_priv *std;
+ struct udevice *bootstd;
+ const char **old_order;
+
+ ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
+ std = dev_get_priv(bootstd);
+ old_order = std->bootdev_order;
+ std->bootdev_order = order;
+
+ /* disable ethernet since the hunter will run dhcp */
+ test_set_eth_enable(false);
+
+ /* make USB scan without delays */
+ test_set_skip_delays(true);
+
+ bootstd_reset_usb();
+
+ ut_assertok(run_command("bootflow scan", 0));
+ ut_assert_skip_to_line(
+ "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+
+ ut_assertok(run_command("bootflow list", 0));
+
+ ut_assert_nextlinen("Showing all");
+ ut_assert_nextlinen("Seq");
+ ut_assert_nextlinen("---");
+ ut_assert_nextlinen(" 0 extlinux");
+ ut_assert_nextlinen(
+ " 1 efi ready usb_mass_ 1 usb_mass_storage.lun0.boo /EFI/BOOT/BOOTSBOX.EFI");
+ ut_assert_nextlinen("---");
+ ut_assert_skip_to_line("(2 bootflows, 2 valid)");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootflow select 1", 0));
+ ut_assert_console_end();
+
+ systab.fw_vendor = test_vendor;
+
+ ut_asserteq(1, run_command("bootflow boot", 0));
+ ut_assert_nextline(
+ "** Booting bootflow 'usb_mass_storage.lun0.bootdev.part_1' with efi");
+ if (IS_ENABLED(CONFIG_LOGF_FUNC))
+ ut_assert_skip_to_line(" efi_run_image() Booting /\\EFI\\BOOT\\BOOTSBOX.EFI");
+ else
+ ut_assert_skip_to_line("Booting /\\EFI\\BOOT\\BOOTSBOX.EFI");
+
+ /* TODO: Why the \r ? */
+ ut_assert_nextline("U-Boot test app for EFI_LOADER\r");
+ ut_assert_nextline("Exiting test app");
+ ut_assert_nextline("Boot failed (err=-14)");
+
+ ut_assert_console_end();
+
+ ut_assertok(bootstd_test_drop_bootdev_order(uts));
+
+ return 0;
+}
+BOOTSTD_TEST(bootflow_efi, UTF_CONSOLE);
diff --git a/test/bootm.c b/test/boot/bootm.c
index 26c15552bf6..52b83f149cb 100644
--- a/test/bootm.c
+++ b/test/boot/bootm.c
@@ -26,12 +26,15 @@ static int bootm_test_nop(struct unit_test_state *uts)
{
char buf[BUF_SIZE];
+ /* This tests relies on GD_FLG_SILENT not being set */
+ gd->flags &= ~GD_FLG_SILENT;
+
*buf = '\0';
- ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
+ ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
ut_asserteq_str("", buf);
strcpy(buf, "test");
- ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
+ ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
ut_asserteq_str("test", buf);
return 0;
@@ -43,23 +46,26 @@ static int bootm_test_nospace(struct unit_test_state *uts)
{
char buf[BUF_SIZE];
+ /* This tests relies on GD_FLG_SILENT not being set */
+ gd->flags &= ~GD_FLG_SILENT;
+
/* Zero buffer size */
*buf = '\0';
- ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 0, true));
+ ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 0, BOOTM_CL_ALL));
/* Buffer string not terminated */
memset(buf, 'a', BUF_SIZE);
- ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true));
+ ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
/* Not enough space to copy string */
memset(buf, '\0', BUF_SIZE);
memset(buf, 'a', BUF_SIZE / 2);
- ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true));
+ ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
/* Just enough space */
memset(buf, '\0', BUF_SIZE);
memset(buf, 'a', BUF_SIZE / 2 - 1);
- ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
+ ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
return 0;
}
@@ -70,6 +76,9 @@ static int bootm_test_silent(struct unit_test_state *uts)
{
char buf[BUF_SIZE];
+ /* This tests relies on GD_FLG_SILENT not being set */
+ gd->flags &= ~GD_FLG_SILENT;
+
/* 'silent_linux' not set should do nothing */
env_set("silent_linux", NULL);
strcpy(buf, CONSOLE_STR);
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index fe7a2165af2..583e7c2eec4 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -5,6 +5,7 @@
obj-y += cmd_ut_cmd.o
+obj-$(CONFIG_$(XPL_)CMDLINE) += command.o
ifdef CONFIG_HUSH_PARSER
obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o
endif
@@ -15,8 +16,10 @@ obj-y += exit.o mem.o
obj-$(CONFIG_X86) += cpuid.o msr.o
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
+obj-$(CONFIG_COREBOOT_SYSINFO) += coreboot.o
obj-$(CONFIG_CMD_FDT) += fdt.o
obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o
+obj-$(CONFIG_CMD_HASH) += hash.o
obj-$(CONFIG_CMD_HISTORY) += history.o
obj-$(CONFIG_CMD_LOADM) += loadm.o
obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
diff --git a/test/cmd/command.c b/test/cmd/command.c
new file mode 100644
index 00000000000..5ec93d490ba
--- /dev/null
+++ b/test/cmd/command.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2012, The Chromium Authors
+ */
+
+#define DEBUG
+
+#include <command.h>
+#include <env.h>
+#include <log.h>
+#include <string.h>
+#include <linux/errno.h>
+#include <test/cmd.h>
+#include <test/ut.h>
+
+static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; "
+ "setenv list ${list}3\0"
+ "setenv list ${list}4";
+
+static int command_test(struct unit_test_state *uts)
+{
+ char long_str[CONFIG_SYS_CBSIZE + 42];
+
+ printf("%s: Testing commands\n", __func__);
+ run_command("env default -f -a", 0);
+
+ /* commands separated by \n */
+ run_command_list("setenv list 1\n setenv list ${list}1", -1, 0);
+ ut_assert(!strcmp("11", env_get("list")));
+
+ /* command followed by \n and nothing else */
+ run_command_list("setenv list 1${list}\n", -1, 0);
+ ut_assert(!strcmp("111", env_get("list")));
+
+ /* a command string with \0 in it. Stuff after \0 should be ignored */
+ run_command("setenv list", 0);
+ run_command_list(test_cmd, sizeof(test_cmd), 0);
+ ut_assert(!strcmp("123", env_get("list")));
+
+ /*
+ * a command list where we limit execution to only the first command
+ * using the length parameter.
+ */
+ run_command_list("setenv list 1\n setenv list ${list}2; "
+ "setenv list ${list}3", strlen("setenv list 1"), 0);
+ ut_assert(!strcmp("1", env_get("list")));
+
+ ut_asserteq(1, run_command("false", 0));
+ ut_assertok(run_command("echo", 0));
+ ut_asserteq(1, run_command_list("false", -1, 0));
+ ut_assertok(run_command_list("echo", -1, 0));
+
+#ifdef CONFIG_HUSH_PARSER
+ run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
+ run_command("run foo", 0);
+ ut_assertnonnull(env_get("black"));
+ ut_asserteq(0, strcmp("1", env_get("black")));
+ ut_assertnonnull(env_get("adder"));
+ ut_asserteq(0, strcmp("2", env_get("adder")));
+#endif
+
+ ut_assertok(run_command("", 0));
+ ut_assertok(run_command(" ", 0));
+
+ ut_asserteq(1, run_command("'", 0));
+
+ /* Variadic function test-cases */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-zero-length"
+ ut_assertok(run_commandf(""));
+#pragma GCC diagnostic pop
+ ut_assertok(run_commandf(" "));
+ ut_asserteq(1, run_commandf("'"));
+
+ ut_assertok(run_commandf("env %s %s", "delete -f", "list"));
+ /*
+ * Expected: "## Error: "list" not defined"
+ * (disabled to avoid pytest bailing out)
+ *
+ * ut_asserteq(1, run_commandf("printenv list"));
+ */
+
+ memset(long_str, 'x', sizeof(long_str));
+ ut_asserteq(-ENOSPC, run_commandf("Truncation case: %s", long_str));
+
+ if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
+ ut_assertok(run_commandf("env %s %s %s %s", "delete -f",
+ "adder", "black", "foo"));
+ ut_assertok(run_commandf(
+ "setenv foo 'setenv %s 1\nsetenv %s 2'",
+ "black", "adder"));
+ ut_assertok(run_command("run foo", 0));
+ ut_assertnonnull(env_get("black"));
+ ut_asserteq(0, strcmp("1", env_get("black")));
+ ut_assertnonnull(env_get("adder"));
+ ut_asserteq(0, strcmp("2", env_get("adder")));
+ }
+
+ /* Clean up before exit */
+ ut_assertok(run_command("env default -f -a", 0));
+
+ /* put back the FDT environment */
+ ut_assertok(env_set("from_fdt", "yes"));
+
+ printf("%s: Everything went swimmingly\n", __func__);
+ return 0;
+}
+CMD_TEST(command_test, 0);
diff --git a/test/cmd/coreboot.c b/test/cmd/coreboot.c
new file mode 100644
index 00000000000..a99898d15c4
--- /dev/null
+++ b/test/cmd/coreboot.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for coreboot commands
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <cedit.h>
+#include <command.h>
+#include <dm.h>
+#include <expo.h>
+#include <rtc.h>
+#include <test/cedit-test.h>
+#include <test/cmd.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include "../../boot/scene_internal.h"
+
+enum {
+ CSUM_LOC = 0x3f0 / 8,
+};
+
+/**
+ * test_cmd_cbsysinfo() - test the cbsysinfo command produces expected output
+ *
+ * This includes ensuring that the coreboot build has the expected options
+ * enabled
+ */
+static int test_cmd_cbsysinfo(struct unit_test_state *uts)
+{
+ ut_assertok(run_command("cbsysinfo", 0));
+ ut_assert_nextlinen("Coreboot table at");
+
+ /* Make sure CMOS options are enabled */
+ ut_assert_skip_to_line(
+ " 1c0 1 e 1 power_on_after_fail 0:Disable 1:Enable");
+ ut_assert_skip_to_line("CMOS start : 1c0");
+ ut_assert_nextline(" CMOS end : 1cf");
+ ut_assert_nextline(" CMOS csum loc: 3f0");
+
+ /* Make sure the linear frame buffer is enabled */
+ ut_assert_skip_to_linen("Framebuffer");
+ ut_assert_nextlinen(" Phys addr");
+
+ ut_assert_skip_to_line("Chrome OS VPD: 00000000");
+ ut_assert_nextlinen("RSDP");
+ ut_assert_nextlinen("Unimpl.");
+ ut_assert_console_end();
+
+ return 0;
+}
+CMD_TEST(test_cmd_cbsysinfo, UTF_CONSOLE);
+
+/* test cbcmos command */
+static int test_cmd_cbcmos(struct unit_test_state *uts)
+{
+ u16 old_csum, new_csum;
+ struct udevice *dev;
+
+ /* initially the checksum should be correct */
+ ut_assertok(run_command("cbcmos check", 0));
+ ut_assert_console_end();
+
+ /* make a change to the checksum */
+ ut_assertok(uclass_first_device_err(UCLASS_RTC, &dev));
+ ut_assertok(rtc_read16(dev, CSUM_LOC, &old_csum));
+ ut_assertok(rtc_write16(dev, CSUM_LOC, old_csum + 1));
+
+ /* now the command should fail */
+ ut_asserteq(1, run_command("cbcmos check", 0));
+ ut_assert_nextline("Checksum %04x error: calculated %04x",
+ old_csum + 1, old_csum);
+ ut_assert_console_end();
+
+ /* now get it to fix the checksum */
+ ut_assertok(run_command("cbcmos update", 0));
+ ut_assert_nextline("Checksum %04x written", old_csum);
+ ut_assert_console_end();
+
+ /* check the RTC looks right */
+ ut_assertok(rtc_read16(dev, CSUM_LOC, &new_csum));
+ ut_asserteq(old_csum, new_csum);
+ ut_assert_console_end();
+
+ return 0;
+}
+CMD_TEST(test_cmd_cbcmos, UTF_CONSOLE);
+
+/* test 'cedit cb_load' command */
+static int test_cmd_cedit_cb_load(struct unit_test_state *uts)
+{
+ struct scene_obj_menu *menu;
+ struct video_priv *vid_priv;
+ struct scene_obj_txt *txt;
+ struct scene *scn;
+ struct expo *exp;
+ int scn_id;
+
+ ut_assertok(run_command("cedit cb_load", 0));
+ ut_assertok(run_command("cedit read_cmos", 0));
+ ut_assert_console_end();
+
+ exp = cur_exp;
+ scn_id = cedit_prepare(exp, &vid_priv, &scn);
+ ut_assert(scn_id > 0);
+ ut_assertnonnull(scn);
+
+ /* just do a very basic test that the first menu is present */
+ menu = scene_obj_find(scn, scn->highlight_id, SCENEOBJT_NONE);
+ ut_assertnonnull(menu);
+
+ txt = scene_obj_find(scn, menu->title_id, SCENEOBJT_NONE);
+ ut_assertnonnull(txt);
+ ut_asserteq_str("Boot option", expo_get_str(exp, txt->str_id));
+
+ return 0;
+}
+CMD_TEST(test_cmd_cedit_cb_load, UTF_CONSOLE);
diff --git a/test/cmd/hash.c b/test/cmd/hash.c
new file mode 100644
index 00000000000..2fcec9cadcd
--- /dev/null
+++ b/test/cmd/hash.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Tests for hash command
+ *
+ * Copyright 2024, Heinrich Schuchardt <heinrich.schuchardt@canoncal.com>
+ */
+
+#include <command.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int dm_test_cmd_hash_md5(struct unit_test_state *uts)
+{
+ if (!CONFIG_IS_ENABLED(MD5)) {
+ ut_assert(run_command("hash md5 $loadaddr 0", 0));
+
+ return 0;
+ }
+
+ ut_assertok(run_command("hash md5 $loadaddr 0", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "md5 for "));
+ ut_assert(strstr(uts->actual_str,
+ "d41d8cd98f00b204e9800998ecf8427e"));
+ ut_assert_console_end();
+
+ ut_assertok(run_command("hash md5 $loadaddr 0 foo; echo $foo", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "md5 for "));
+ ut_assert(strstr(uts->actual_str,
+ "d41d8cd98f00b204e9800998ecf8427e"));
+ ut_check_console_line(uts, "d41d8cd98f00b204e9800998ecf8427e");
+
+ if (!CONFIG_IS_ENABLED(HASH_VERIFY)) {
+ ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+ ut_check_console_line(uts, "hash - compute hash message digest");
+
+ return 0;
+ }
+
+ ut_assertok(run_command("hash -v md5 $loadaddr 0 foo", 0));
+ ut_assert_console_end();
+
+ env_set("foo", "ffffffffffffffffffffffffffffffff");
+ ut_assert(run_command("hash -v md5 $loadaddr 0 foo", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_assert(strstr(uts->actual_str, "!="));
+ ut_assert_console_end();
+
+ return 0;
+}
+DM_TEST(dm_test_cmd_hash_md5, UTF_CONSOLE);
+
+static int dm_test_cmd_hash_sha256(struct unit_test_state *uts)
+{
+ if (!CONFIG_IS_ENABLED(SHA256)) {
+ ut_assert(run_command("hash sha256 $loadaddr 0", 0));
+
+ return 0;
+ }
+
+ ut_assertok(run_command("hash sha256 $loadaddr 0", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "sha256 for "));
+ ut_assert(strstr(uts->actual_str,
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+ ut_assert_console_end();
+
+ ut_assertok(run_command("hash sha256 $loadaddr 0 foo; echo $foo", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "sha256 for "));
+ ut_assert(strstr(uts->actual_str,
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+ ut_check_console_line(uts,
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+
+ if (!CONFIG_IS_ENABLED(HASH_VERIFY)) {
+ ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+ ut_check_console_line(uts, "hash - compute hash message digest");
+
+ return 0;
+ }
+
+ ut_assertok(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+ ut_assert_console_end();
+
+ env_set("foo", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+ ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_assert(strstr(uts->actual_str, "!="));
+ ut_assert_console_end();
+
+ return 0;
+}
+DM_TEST(dm_test_cmd_hash_sha256, UTF_CONSOLE);
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 53fddebd49d..195b7ea50ac 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -99,25 +99,15 @@ static struct cmd_tbl cmd_ut_sub[] = {
U_BOOT_CMD_MKENT(setexpr, CONFIG_SYS_MAXARGS, 1, do_ut_setexpr, "",
""),
#endif
- U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_ut_print, "", ""),
-#ifdef CONFIG_UT_TIME
- U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),
-#endif
-#if CONFIG_IS_ENABLED(UT_UNICODE) && !defined(API_BUILD)
- U_BOOT_CMD_MKENT(unicode, CONFIG_SYS_MAXARGS, 1, do_ut_unicode, "", ""),
-#endif
#ifdef CONFIG_MEASURED_BOOT
U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1, do_ut_measurement,
"", ""),
#endif
#ifdef CONFIG_SANDBOX
- U_BOOT_CMD_MKENT(compression, CONFIG_SYS_MAXARGS, 1, do_ut_compression,
- "", ""),
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
- U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""),
#ifdef CONFIG_CMD_ADDRMAP
U_BOOT_CMD_MKENT(addrmap, CONFIG_SYS_MAXARGS, 1, do_ut_addrmap, "", ""),
#endif
@@ -207,9 +197,7 @@ U_BOOT_LONGHELP(ut,
#ifdef CONFIG_CMDLINE
"\ncmd - test various commands"
#endif
-#ifdef CONFIG_SANDBOX
- "\ncompression - compressors and bootm decompression"
-#endif
+ "\ncommon - tests for common/ directory"
#ifdef CONFIG_UT_DM
"\ndm - driver model"
#endif
@@ -244,21 +232,10 @@ U_BOOT_LONGHELP(ut,
#ifdef CONFIG_CMD_PCI_MPS
"\npci_mps - PCI Express Maximum Payload Size"
#endif
- "\nprint - printing things to the console"
"\nsetexpr - setexpr command"
-#ifdef CONFIG_SANDBOX
- "\nstr - basic test of string functions"
-#endif
#ifdef CONFIG_CMD_SEAMA
"\nseama - seama command parameters loading and decoding"
#endif
-#ifdef CONFIG_UT_TIME
- "\ntime - very basic test of time functions"
-#endif
-#if defined(CONFIG_UT_UNICODE) && \
- !defined(CONFIG_XPL_BUILD) && !defined(API_BUILD)
- "\nunicode - Unicode functions"
-#endif
);
U_BOOT_CMD(
diff --git a/test/command_ut.c b/test/command_ut.c
deleted file mode 100644
index 2b8d28d7ae3..00000000000
--- a/test/command_ut.c
+++ /dev/null
@@ -1,104 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2012, The Chromium Authors
- */
-
-#define DEBUG
-
-#include <command.h>
-#include <env.h>
-#include <log.h>
-#include <string.h>
-#include <linux/errno.h>
-
-static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; "
- "setenv list ${list}3\0"
- "setenv list ${list}4";
-
-static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
-{
- char long_str[CONFIG_SYS_CBSIZE + 42];
-
- printf("%s: Testing commands\n", __func__);
- run_command("env default -f -a", 0);
-
- /* commands separated by \n */
- run_command_list("setenv list 1\n setenv list ${list}1", -1, 0);
- assert(!strcmp("11", env_get("list")));
-
- /* command followed by \n and nothing else */
- run_command_list("setenv list 1${list}\n", -1, 0);
- assert(!strcmp("111", env_get("list")));
-
- /* a command string with \0 in it. Stuff after \0 should be ignored */
- run_command("setenv list", 0);
- run_command_list(test_cmd, sizeof(test_cmd), 0);
- assert(!strcmp("123", env_get("list")));
-
- /*
- * a command list where we limit execution to only the first command
- * using the length parameter.
- */
- run_command_list("setenv list 1\n setenv list ${list}2; "
- "setenv list ${list}3", strlen("setenv list 1"), 0);
- assert(!strcmp("1", env_get("list")));
-
- assert(run_command("false", 0) == 1);
- assert(run_command("echo", 0) == 0);
- assert(run_command_list("false", -1, 0) == 1);
- assert(run_command_list("echo", -1, 0) == 0);
-
-#ifdef CONFIG_HUSH_PARSER
- run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
- run_command("run foo", 0);
- assert(env_get("black") != NULL);
- assert(!strcmp("1", env_get("black")));
- assert(env_get("adder") != NULL);
- assert(!strcmp("2", env_get("adder")));
-#endif
-
- assert(run_command("", 0) == 0);
- assert(run_command(" ", 0) == 0);
-
- assert(run_command("'", 0) == 1);
-
- /* Variadic function test-cases */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-zero-length"
- assert(run_commandf("") == 0);
-#pragma GCC diagnostic pop
- assert(run_commandf(" ") == 0);
- assert(run_commandf("'") == 1);
-
- assert(run_commandf("env %s %s", "delete -f", "list") == 0);
- /* Expected: "Error: "list" not defined" */
- assert(run_commandf("printenv list") == 1);
-
- memset(long_str, 'x', sizeof(long_str));
- assert(run_commandf("Truncation case: %s", long_str) == -ENOSPC);
-
- if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
- assert(run_commandf("env %s %s %s %s", "delete -f", "adder",
- "black", "foo") == 0);
- assert(run_commandf("setenv foo 'setenv %s 1\nsetenv %s 2'",
- "black", "adder") == 0);
- run_command("run foo", 0);
- assert(env_get("black"));
- assert(!strcmp("1", env_get("black")));
- assert(env_get("adder"));
- assert(!strcmp("2", env_get("adder")));
- }
-
- /* Clean up before exit */
- run_command("env default -f -a", 0);
-
- printf("%s: Everything went swimmingly\n", __func__);
- return 0;
-}
-
-U_BOOT_CMD(
- ut_cmd, 5, 1, do_ut_cmd,
- "Very basic test of command parsers",
- ""
-);
diff --git a/test/common.sh b/test/common.sh
deleted file mode 100644
index 904d579b7bf..00000000000
--- a/test/common.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-OUTPUT_DIR=sandbox
-
-fail() {
- echo "Test failed: $1"
- if [ -n ${tmp} ]; then
- rm ${tmp}
- fi
- exit 1
-}
-
-build_uboot() {
- echo "Build sandbox"
- OPTS="O=${OUTPUT_DIR} $1"
- NUM_CPUS=$(nproc)
- echo ${OPTS}
- make ${OPTS} sandbox_config
- make ${OPTS} -s -j${NUM_CPUS}
-}
diff --git a/test/common/Makefile b/test/common/Makefile
index 12c65f8c951..53c4f16164d 100644
--- a/test/common/Makefile
+++ b/test/common/Makefile
@@ -1,6 +1,10 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += cmd_ut_common.o
obj-$(CONFIG_AUTOBOOT) += test_autoboot.o
+ifneq ($(CONFIG_$(XPL_)BLOBLIST),)
+obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o
+endif
obj-$(CONFIG_CYCLIC) += cyclic.o
obj-$(CONFIG_EVENT_DYNAMIC) += event.o
obj-y += cread.o
+obj-$(CONFIG_$(XPL_)CMDLINE) += print.o
diff --git a/test/bloblist.c b/test/common/bloblist.c
index fd85c7ab79e..4bca62110a5 100644
--- a/test/bloblist.c
+++ b/test/common/bloblist.c
@@ -6,13 +6,10 @@
#include <bloblist.h>
#include <log.h>
#include <mapmem.h>
-#include <asm/global_data.h>
#include <test/suites.h>
#include <test/test.h>
#include <test/ut.h>
-DECLARE_GLOBAL_DATA_PTR;
-
/* Declare a new bloblist test */
#define BLOBLIST_TEST(_name, _flags) \
UNIT_TEST(_name, _flags, bloblist_test)
@@ -94,7 +91,7 @@ static int bloblist_test_init(struct unit_test_state *uts)
return 1;
}
-BLOBLIST_TEST(bloblist_test_init, 0);
+BLOBLIST_TEST(bloblist_test_init, UFT_BLOBLIST);
static int bloblist_test_blob(struct unit_test_state *uts)
{
@@ -134,7 +131,7 @@ static int bloblist_test_blob(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_blob, 0);
+BLOBLIST_TEST(bloblist_test_blob, UFT_BLOBLIST);
/* Check bloblist_ensure_size_ret() */
static int bloblist_test_blob_ensure(struct unit_test_state *uts)
@@ -168,7 +165,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
+BLOBLIST_TEST(bloblist_test_blob_ensure, UFT_BLOBLIST);
static int bloblist_test_bad_blob(struct unit_test_state *uts)
{
@@ -184,7 +181,7 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_bad_blob, 0);
+BLOBLIST_TEST(bloblist_test_bad_blob, UFT_BLOBLIST);
static int bloblist_test_checksum(struct unit_test_state *uts)
{
@@ -257,7 +254,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_checksum, 0);
+BLOBLIST_TEST(bloblist_test_checksum, UFT_BLOBLIST);
/* Test the 'bloblist info' command */
static int bloblist_test_cmd_info(struct unit_test_state *uts)
@@ -278,7 +275,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_cmd_info, UTF_CONSOLE);
+BLOBLIST_TEST(bloblist_test_cmd_info, UFT_BLOBLIST | UTF_CONSOLE);
/* Test the 'bloblist list' command */
static int bloblist_test_cmd_list(struct unit_test_state *uts)
@@ -300,7 +297,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_cmd_list, UTF_CONSOLE);
+BLOBLIST_TEST(bloblist_test_cmd_list, UFT_BLOBLIST | UTF_CONSOLE);
/* Test alignment of bloblist blobs */
static int bloblist_test_align(struct unit_test_state *uts)
@@ -358,7 +355,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_align, 0);
+BLOBLIST_TEST(bloblist_test_align, UFT_BLOBLIST);
/* Test relocation of a bloblist */
static int bloblist_test_reloc(struct unit_test_state *uts)
@@ -392,7 +389,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_reloc, 0);
+BLOBLIST_TEST(bloblist_test_reloc, UFT_BLOBLIST);
/* Test expansion of a blob */
static int bloblist_test_grow(struct unit_test_state *uts)
@@ -445,7 +442,7 @@ static int bloblist_test_grow(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_grow, 0);
+BLOBLIST_TEST(bloblist_test_grow, UFT_BLOBLIST);
/* Test shrinking of a blob */
static int bloblist_test_shrink(struct unit_test_state *uts)
@@ -495,7 +492,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_shrink, 0);
+BLOBLIST_TEST(bloblist_test_shrink, UFT_BLOBLIST);
/* Test failing to adjust a blob size */
static int bloblist_test_resize_fail(struct unit_test_state *uts)
@@ -530,7 +527,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_resize_fail, 0);
+BLOBLIST_TEST(bloblist_test_resize_fail, UFT_BLOBLIST);
/* Test expanding the last blob in a bloblist */
static int bloblist_test_resize_last(struct unit_test_state *uts)
@@ -581,7 +578,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_resize_last, 0);
+BLOBLIST_TEST(bloblist_test_resize_last, UFT_BLOBLIST);
/* Check a completely full bloblist */
static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
@@ -604,7 +601,7 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
return 0;
}
-BLOBLIST_TEST(bloblist_test_blob_maxsize, 0);
+BLOBLIST_TEST(bloblist_test_blob_maxsize, UFT_BLOBLIST);
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
diff --git a/test/print_ut.c b/test/common/print.c
index f5e607b21a3..f1eb9072d97 100644
--- a/test/print_ut.c
+++ b/test/common/print.c
@@ -11,7 +11,7 @@
#include <version_string.h>
#include <stdio.h>
#include <vsprintf.h>
-#include <test/suites.h>
+#include <test/common.h>
#include <test/test.h>
#include <test/ut.h>
@@ -20,9 +20,6 @@
#define FAKE_BUILD_TAG "jenkins-u-boot-denx_uboot_dm-master-build-aarch64" \
"and a lot more text to come"
-/* Declare a new print test */
-#define PRINT_TEST(_name, _flags) UNIT_TEST(_name, _flags, print_test)
-
#if CONFIG_IS_ENABLED(LIB_UUID)
/* Test printing GUIDs */
static int print_guid(struct unit_test_state *uts)
@@ -59,7 +56,7 @@ static int print_guid(struct unit_test_state *uts)
return 0;
}
-PRINT_TEST(print_guid, 0);
+COMMON_TEST(print_guid, 0);
#endif
#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
@@ -95,7 +92,7 @@ static int print_efi_ut(struct unit_test_state *uts)
return 0;
}
-PRINT_TEST(print_efi_ut, 0);
+COMMON_TEST(print_efi_ut, 0);
#endif
static int print_printf(struct unit_test_state *uts)
@@ -163,7 +160,7 @@ static int print_printf(struct unit_test_state *uts)
return 0;
}
-PRINT_TEST(print_printf, 0);
+COMMON_TEST(print_printf, 0);
static int print_display_buffer(struct unit_test_state *uts)
{
@@ -238,7 +235,7 @@ static int print_display_buffer(struct unit_test_state *uts)
return 0;
}
-PRINT_TEST(print_display_buffer, UTF_CONSOLE);
+COMMON_TEST(print_display_buffer, UTF_CONSOLE);
static int print_hexdump_line(struct unit_test_state *uts)
{
@@ -264,7 +261,7 @@ static int print_hexdump_line(struct unit_test_state *uts)
return 0;
}
-PRINT_TEST(print_hexdump_line, UTF_CONSOLE);
+COMMON_TEST(print_hexdump_line, UTF_CONSOLE);
static int print_do_hex_dump(struct unit_test_state *uts)
{
@@ -350,7 +347,7 @@ static int print_do_hex_dump(struct unit_test_state *uts)
return 0;
}
-PRINT_TEST(print_do_hex_dump, UTF_CONSOLE);
+COMMON_TEST(print_do_hex_dump, UTF_CONSOLE);
static int snprint(struct unit_test_state *uts)
{
@@ -376,12 +373,4 @@ static int snprint(struct unit_test_state *uts)
ut_asserteq(8, ret);
return 0;
}
-PRINT_TEST(snprint, 0);
-
-int do_ut_print(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- struct unit_test *tests = UNIT_TEST_SUITE_START(print_test);
- const int n_ents = UNIT_TEST_SUITE_COUNT(print_test);
-
- return cmd_ut_category("print", "print_", tests, n_ents, argc, argv);
-}
+COMMON_TEST(snprint, 0);
diff --git a/test/dm/core.c b/test/dm/core.c
index e0c5b9e0017..7371d3ff426 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -1351,3 +1351,25 @@ static int dm_test_dev_get_mem(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_dev_get_mem, UTF_SCAN_FDT);
+
+/* Test uclass_try_first_device() */
+static int dm_test_try_first_device(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+
+ /* Check that it doesn't create a device or uclass */
+ ut_assertnull(uclass_find(UCLASS_TEST));
+ ut_assertnull(uclass_try_first_device(UCLASS_TEST));
+ ut_assertnull(uclass_try_first_device(UCLASS_TEST));
+ ut_assertnull(uclass_find(UCLASS_TEST));
+
+ /* Create a test device */
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
+ &dev));
+ dev = uclass_try_first_device(UCLASS_TEST);
+ ut_assertnonnull(dev);
+ ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev));
+
+ return 0;
+}
+DM_TEST(dm_test_try_first_device, 0);
diff --git a/test/lib/Makefile b/test/lib/Makefile
index a54387a058e..f516d001747 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -2,6 +2,9 @@
#
# (C) Copyright 2018
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+
+obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o
+
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += cmd_ut_lib.o
obj-y += abuf.o
@@ -11,9 +14,10 @@ obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
obj-y += hexdump.o
obj-$(CONFIG_SANDBOX) += kconfig.o
obj-y += lmb.o
-obj-y += longjmp.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-y += string.o
obj-y += strlcat.o
obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
@@ -23,6 +27,8 @@ obj-$(CONFIG_AES) += test_aes.o
obj-$(CONFIG_GETOPT) += getopt.o
obj-$(CONFIG_CRC8) += test_crc8.o
obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o
+obj-$(CONFIG_UT_TIME) += time.o
+obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode.o
obj-$(CONFIG_LIB_UUID) += uuid.o
else
obj-$(CONFIG_SANDBOX) += kconfig_spl.o
diff --git a/test/lib/alist.c b/test/lib/alist.c
index d41845c7e6c..0bf24578d2e 100644
--- a/test/lib/alist.c
+++ b/test/lib/alist.c
@@ -240,3 +240,256 @@ static int lib_test_alist_add(struct unit_test_state *uts)
return 0;
}
LIB_TEST(lib_test_alist_add, 0);
+
+/* Test alist_next() */
+static int lib_test_alist_next(struct unit_test_state *uts)
+{
+ const struct my_struct *ptr;
+ struct my_struct data, *ptr2;
+ struct alist lst;
+ ulong start;
+
+ start = ut_check_free();
+
+ ut_assert(alist_init_struct(&lst, struct my_struct));
+ data.val = 123;
+ data.other_val = 0;
+ alist_add(&lst, data);
+
+ data.val = 321;
+ alist_add(&lst, data);
+
+ data.val = 789;
+ alist_add(&lst, data);
+
+ ptr = alist_get(&lst, 0, struct my_struct);
+ ut_assertnonnull(ptr);
+ ut_asserteq(123, ptr->val);
+
+ ptr = alist_next(&lst, ptr);
+ ut_assertnonnull(ptr);
+ ut_asserteq(321, ptr->val);
+
+ ptr2 = (struct my_struct *)ptr;
+ ptr2 = alist_nextw(&lst, ptr2);
+ ut_assertnonnull(ptr2);
+
+ ptr = alist_next(&lst, ptr);
+ ut_assertnonnull(ptr);
+ ut_asserteq(789, ptr->val);
+ ut_asserteq_ptr(ptr, ptr2);
+ ptr2->val = 89;
+ ut_asserteq(89, ptr->val);
+
+ ptr = alist_next(&lst, ptr);
+ ut_assertnull(ptr);
+
+ alist_uninit(&lst);
+
+ /* Check for memory leaks */
+ ut_assertok(ut_check_delta(start));
+
+ return 0;
+}
+LIB_TEST(lib_test_alist_next, 0);
+
+/* Test alist_for_each() */
+static int lib_test_alist_for_each(struct unit_test_state *uts)
+{
+ const struct my_struct *ptr;
+ struct my_struct data, *ptr2;
+ struct alist lst;
+ ulong start;
+ int sum;
+
+ start = ut_check_free();
+
+ ut_assert(alist_init_struct(&lst, struct my_struct));
+ ut_asserteq_ptr(NULL, alist_end(&lst, struct my_struct));
+
+ sum = 0;
+ alist_for_each(ptr, &lst)
+ sum++;
+ ut_asserteq(0, sum);
+
+ alist_for_each(ptr, &lst)
+ sum++;
+ ut_asserteq(0, sum);
+
+ /* add three items */
+ data.val = 1;
+ data.other_val = 0;
+ alist_add(&lst, data);
+
+ ptr = lst.data;
+ ut_asserteq_ptr(ptr + 1, alist_end(&lst, struct my_struct));
+
+ data.val = 2;
+ alist_add(&lst, data);
+ ut_asserteq_ptr(ptr + 2, alist_end(&lst, struct my_struct));
+
+ data.val = 3;
+ alist_add(&lst, data);
+ ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct));
+
+ /* check alist_chk_ptr() */
+ ut_asserteq(true, alist_chk_ptr(&lst, ptr + 2));
+ ut_asserteq(false, alist_chk_ptr(&lst, ptr + 3));
+ ut_asserteq(false, alist_chk_ptr(&lst, ptr + 4));
+ ut_asserteq(true, alist_chk_ptr(&lst, ptr));
+ ut_asserteq(false, alist_chk_ptr(&lst, ptr - 1));
+
+ /* sum all items */
+ sum = 0;
+ alist_for_each(ptr, &lst)
+ sum += ptr->val;
+ ut_asserteq(6, sum);
+
+ /* increment all items */
+ alist_for_each(ptr2, &lst)
+ ptr2->val += 1;
+
+ /* sum all items again */
+ sum = 0;
+ alist_for_each(ptr, &lst)
+ sum += ptr->val;
+ ut_asserteq(9, sum);
+
+ ptr = lst.data;
+ ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct));
+
+ /* empty the list and try again */
+ alist_empty(&lst);
+ ut_asserteq_ptr(ptr, alist_end(&lst, struct my_struct));
+ ut_assertnull(alist_get(&lst, 0, struct my_struct));
+
+ sum = 0;
+ alist_for_each(ptr, &lst)
+ sum += ptr->val;
+ ut_asserteq(0, sum);
+
+ alist_uninit(&lst);
+
+ /* Check for memory leaks */
+ ut_assertok(ut_check_delta(start));
+
+ return 0;
+}
+LIB_TEST(lib_test_alist_for_each, 0);
+
+/* Test alist_empty() */
+static int lib_test_alist_empty(struct unit_test_state *uts)
+{
+ struct my_struct data;
+ struct alist lst;
+ ulong start;
+
+ start = ut_check_free();
+
+ ut_assert(alist_init_struct(&lst, struct my_struct));
+ ut_asserteq(0, lst.count);
+ data.val = 1;
+ data.other_val = 0;
+ alist_add(&lst, data);
+ ut_asserteq(1, lst.count);
+ ut_asserteq(4, lst.alloc);
+
+ alist_empty(&lst);
+ ut_asserteq(0, lst.count);
+ ut_asserteq(4, lst.alloc);
+ ut_assertnonnull(lst.data);
+ ut_asserteq(sizeof(data), lst.obj_size);
+
+ alist_uninit(&lst);
+
+ /* Check for memory leaks */
+ ut_assertok(ut_check_delta(start));
+
+ return 0;
+}
+LIB_TEST(lib_test_alist_empty, 0);
+
+static int lib_test_alist_filter(struct unit_test_state *uts)
+{
+ struct my_struct *from, *to, *ptr;
+ struct my_struct data;
+ struct alist lst;
+ ulong start;
+ int count;
+
+ start = ut_check_free();
+
+ ut_assert(alist_init_struct(&lst, struct my_struct));
+ data.val = 1;
+ data.other_val = 0;
+ alist_add(&lst, data);
+
+ data.val = 2;
+ alist_add(&lst, data);
+
+ data.val = 3;
+ alist_add(&lst, data);
+ ptr = lst.data;
+
+ /* filter out all values except 2 */
+ alist_for_each_filter(from, to, &lst) {
+ if (from->val != 2)
+ *to++ = *from;
+ }
+ alist_update_end(&lst, to);
+
+ ut_asserteq(2, lst.count);
+ ut_assertnonnull(lst.data);
+
+ ut_asserteq(1, alist_get(&lst, 0, struct my_struct)->val);
+ ut_asserteq(3, alist_get(&lst, 1, struct my_struct)->val);
+ ut_asserteq_ptr(ptr + 3, from);
+ ut_asserteq_ptr(ptr + 2, to);
+
+ /* filter out nothing */
+ alist_for_each_filter(from, to, &lst) {
+ if (from->val != 2)
+ *to++ = *from;
+ }
+ alist_update_end(&lst, to);
+ ut_asserteq_ptr(ptr + 2, from);
+ ut_asserteq_ptr(ptr + 2, to);
+
+ ut_asserteq(2, lst.count);
+ ut_assertnonnull(lst.data);
+
+ ut_asserteq(1, alist_get(&lst, 0, struct my_struct)->val);
+ ut_asserteq(3, alist_get(&lst, 1, struct my_struct)->val);
+
+ /* filter out everything */
+ alist_for_each_filter(from, to, &lst) {
+ if (from->val == 2)
+ *to++ = *from;
+ }
+ alist_update_end(&lst, to);
+ ut_asserteq_ptr(ptr + 2, from);
+ ut_asserteq_ptr(ptr, to);
+
+ /* filter out everything (nop) */
+ count = 0;
+ alist_for_each_filter(from, to, &lst) {
+ if (from->val == 2)
+ *to++ = *from;
+ count++;
+ }
+ alist_update_end(&lst, to);
+ ut_asserteq_ptr(ptr, from);
+ ut_asserteq_ptr(ptr, to);
+ ut_asserteq(0, count);
+
+ ut_asserteq(0, lst.count);
+ ut_assertnonnull(lst.data);
+
+ alist_uninit(&lst);
+
+ /* Check for memory leaks */
+ ut_assertok(ut_check_delta(start));
+
+ return 0;
+}
+LIB_TEST(lib_test_alist_filter, 0);
diff --git a/test/compression.c b/test/lib/compression.c
index 618a1936955..31b6e5b1eb4 100644
--- a/test/compression.c
+++ b/test/lib/compression.c
@@ -23,8 +23,7 @@
#include <linux/lzo.h>
#include <linux/zstd.h>
-#include <test/compression.h>
-#include <test/suites.h>
+#include <test/lib.h>
#include <test/ut.h>
static const char plain[] =
@@ -471,40 +470,40 @@ static int compression_test_gzip(struct unit_test_state *uts)
return run_test(uts, "gzip", compress_using_gzip,
uncompress_using_gzip);
}
-COMPRESSION_TEST(compression_test_gzip, 0);
+LIB_TEST(compression_test_gzip, 0);
static int compression_test_bzip2(struct unit_test_state *uts)
{
return run_test(uts, "bzip2", compress_using_bzip2,
uncompress_using_bzip2);
}
-COMPRESSION_TEST(compression_test_bzip2, 0);
+LIB_TEST(compression_test_bzip2, 0);
static int compression_test_lzma(struct unit_test_state *uts)
{
return run_test(uts, "lzma", compress_using_lzma,
uncompress_using_lzma);
}
-COMPRESSION_TEST(compression_test_lzma, 0);
+LIB_TEST(compression_test_lzma, 0);
static int compression_test_lzo(struct unit_test_state *uts)
{
return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
}
-COMPRESSION_TEST(compression_test_lzo, 0);
+LIB_TEST(compression_test_lzo, 0);
static int compression_test_lz4(struct unit_test_state *uts)
{
return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
}
-COMPRESSION_TEST(compression_test_lz4, 0);
+LIB_TEST(compression_test_lz4, 0);
static int compression_test_zstd(struct unit_test_state *uts)
{
return run_test(uts, "zstd", compress_using_zstd,
uncompress_using_zstd);
}
-COMPRESSION_TEST(compression_test_zstd, 0);
+LIB_TEST(compression_test_zstd, 0);
static int compress_using_none(struct unit_test_state *uts,
void *in, unsigned long in_size,
@@ -570,50 +569,40 @@ static int compression_test_bootm_gzip(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
}
-COMPRESSION_TEST(compression_test_bootm_gzip, 0);
+LIB_TEST(compression_test_bootm_gzip, 0);
static int compression_test_bootm_bzip2(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
}
-COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
+LIB_TEST(compression_test_bootm_bzip2, 0);
static int compression_test_bootm_lzma(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
}
-COMPRESSION_TEST(compression_test_bootm_lzma, 0);
+LIB_TEST(compression_test_bootm_lzma, 0);
static int compression_test_bootm_lzo(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
}
-COMPRESSION_TEST(compression_test_bootm_lzo, 0);
+LIB_TEST(compression_test_bootm_lzo, 0);
static int compression_test_bootm_lz4(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
}
-COMPRESSION_TEST(compression_test_bootm_lz4, 0);
+LIB_TEST(compression_test_bootm_lz4, 0);
static int compression_test_bootm_zstd(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_ZSTD, compress_using_zstd);
}
-COMPRESSION_TEST(compression_test_bootm_zstd, 0);
+LIB_TEST(compression_test_bootm_zstd, 0);
static int compression_test_bootm_none(struct unit_test_state *uts)
{
return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
}
-COMPRESSION_TEST(compression_test_bootm_none, 0);
-
-int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
-{
- struct unit_test *tests = UNIT_TEST_SUITE_START(compression_test);
- const int n_ents = UNIT_TEST_SUITE_COUNT(compression_test);
-
- return cmd_ut_category("compression", "compression_test_",
- tests, n_ents, argc, argv);
-}
+LIB_TEST(compression_test_bootm_none, 0);
diff --git a/test/str_ut.c b/test/lib/str.c
index 96e048975d8..3cc9dfea6aa 100644
--- a/test/str_ut.c
+++ b/test/lib/str.c
@@ -4,7 +4,7 @@
*/
#include <vsprintf.h>
-#include <test/suites.h>
+#include <test/lib.h>
#include <test/test.h>
#include <test/ut.h>
@@ -19,9 +19,6 @@ static const char str5[] = "0x9876543210the last time I was deloused";
static const char str6[] = "0778octal is seldom used";
static const char str7[] = "707it is a piece of computing history";
-/* Declare a new str test */
-#define STR_TEST(_name, _flags) UNIT_TEST(_name, _flags, str_test)
-
static int str_upper(struct unit_test_state *uts)
{
char out[TEST_STR_SIZE];
@@ -58,7 +55,7 @@ static int str_upper(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_upper, 0);
+LIB_TEST(str_upper, 0);
static int run_strtoul(struct unit_test_state *uts, const char *str, int base,
ulong expect_val, int expect_endp_offset, bool upper)
@@ -112,7 +109,7 @@ static int str_simple_strtoul(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_simple_strtoul, 0);
+LIB_TEST(str_simple_strtoul, 0);
static int run_strtoull(struct unit_test_state *uts, const char *str, int base,
unsigned long long expect_val, int expect_endp_offset,
@@ -175,7 +172,7 @@ static int str_simple_strtoull(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_simple_strtoull, 0);
+LIB_TEST(str_simple_strtoull, 0);
static int str_hextoul(struct unit_test_state *uts)
{
@@ -187,7 +184,7 @@ static int str_hextoul(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_hextoul, 0);
+LIB_TEST(str_hextoul, 0);
static int str_dectoul(struct unit_test_state *uts)
{
@@ -199,7 +196,7 @@ static int str_dectoul(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_dectoul, 0);
+LIB_TEST(str_dectoul, 0);
static int str_itoa(struct unit_test_state *uts)
{
@@ -219,7 +216,7 @@ static int str_itoa(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_itoa, 0);
+LIB_TEST(str_itoa, 0);
static int str_xtoa(struct unit_test_state *uts)
{
@@ -239,7 +236,7 @@ static int str_xtoa(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_xtoa, 0);
+LIB_TEST(str_xtoa, 0);
static int str_trailing(struct unit_test_state *uts)
{
@@ -271,7 +268,7 @@ static int str_trailing(struct unit_test_state *uts)
return 0;
}
-STR_TEST(str_trailing, 0);
+LIB_TEST(str_trailing, 0);
static int test_str_to_list(struct unit_test_state *uts)
{
@@ -351,12 +348,4 @@ static int test_str_to_list(struct unit_test_state *uts)
return 0;
}
-STR_TEST(test_str_to_list, 0);
-
-int do_ut_str(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- struct unit_test *tests = UNIT_TEST_SUITE_START(str_test);
- const int n_ents = UNIT_TEST_SUITE_COUNT(str_test);
-
- return cmd_ut_category("str", "str_", tests, n_ents, argc, argv);
-}
+LIB_TEST(test_str_to_list, 0);
diff --git a/test/time_ut.c b/test/lib/time.c
index 149c4b58f4a..b99e738c500 100644
--- a/test/time_ut.c
+++ b/test/lib/time.c
@@ -4,12 +4,13 @@
* Written by Simon Glass <sjg@chromium.org>
*/
-#include <command.h>
#include <errno.h>
#include <time.h>
#include <linux/delay.h>
+#include <test/lib.h>
+#include <test/ut.h>
-static int test_get_timer(void)
+static int test_get_timer(struct unit_test_state *uts)
{
ulong base, start, next, diff;
int iter;
@@ -21,11 +22,7 @@ static int test_get_timer(void)
next = get_timer(0);
} while (start == next);
- if (start + 1 != next) {
- printf("%s: iter=%d, start=%lu, next=%lu, expected a difference of 1\n",
- __func__, iter, start, next);
- return -EINVAL;
- }
+ ut_asserteq(start + 1, next);
start++;
}
@@ -34,16 +31,13 @@ static int test_get_timer(void)
* an extra millisecond may have passed.
*/
diff = get_timer(base);
- if (diff != iter && diff != iter + 1) {
- printf("%s: expected get_timer(base) to match elapsed time: diff=%lu, expected=%d\n",
- __func__, diff, iter);
- return -EINVAL;
- }
+ ut_assert(diff == iter || diff == iter + 1);
return 0;
}
+LIB_TEST(test_get_timer, 0);
-static int test_timer_get_us(void)
+static int test_timer_get_us(struct unit_test_state *uts)
{
ulong prev, next, min = 1000000;
long delta;
@@ -55,11 +49,8 @@ static int test_timer_get_us(void)
next = timer_get_us();
if (next != prev) {
delta = next - prev;
- if (delta < 0) {
- printf("%s: timer_get_us() went backwards from %lu to %lu\n",
- __func__, prev, next);
- return -EINVAL;
- } else if (delta != 0) {
+ ut_assert(delta >= 0);
+ if (delta) {
if (delta < min)
min = delta;
prev = next;
@@ -68,16 +59,13 @@ static int test_timer_get_us(void)
}
}
- if (min != 1) {
- printf("%s: Minimum microsecond delta should be 1 but is %lu\n",
- __func__, min);
- return -EINVAL;
- }
+ ut_asserteq(1, min);
return 0;
}
+LIB_TEST(test_timer_get_us, 0);
-static int test_time_comparison(void)
+static int test_time_comparison(struct unit_test_state *uts)
{
ulong start_us, end_us, delta_us;
long error;
@@ -92,13 +80,13 @@ static int test_time_comparison(void)
error = delta_us - 1000000;
printf("%s: Microsecond time for 1 second: %lu, error = %ld\n",
__func__, delta_us, error);
- if (abs(error) > 1000)
- return -EINVAL;
+ ut_assert(abs(error) <= 1000);
return 0;
}
+LIB_TEST(test_time_comparison, 0);
-static int test_udelay(void)
+static int test_udelay(struct unit_test_state *uts)
{
long error;
ulong start, delta;
@@ -111,22 +99,8 @@ static int test_udelay(void)
error = delta - 1000;
printf("%s: Delay time for 1000 udelay(1000): %lu ms, error = %ld\n",
__func__, delta, error);
- if (abs(error) > 100)
- return -EINVAL;
+ ut_assert(abs(error) <= 100);
return 0;
}
-
-int do_ut_time(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- int ret = 0;
-
- ret |= test_get_timer();
- ret |= test_timer_get_us();
- ret |= test_time_comparison();
- ret |= test_udelay();
-
- printf("Test %s\n", ret ? "failed" : "passed");
-
- return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
-}
+LIB_TEST(test_udelay, 0);
diff --git a/test/unicode_ut.c b/test/lib/unicode.c
index 13e29c9b9e3..673470c8d2c 100644
--- a/test/unicode_ut.c
+++ b/test/lib/unicode.c
@@ -11,13 +11,10 @@
#include <errno.h>
#include <log.h>
#include <malloc.h>
+#include <test/lib.h>
#include <test/test.h>
-#include <test/suites.h>
#include <test/ut.h>
-/* Linker list entry for a Unicode test */
-#define UNICODE_TEST(_name) UNIT_TEST(_name, 0, unicode_test)
-
/* Constants c1-c4 and d1-d4 encode the same letters */
/* Six characters translating to one utf-8 byte each. */
@@ -64,7 +61,7 @@ static int unicode_test_u16_strlen(struct unit_test_state *uts)
ut_asserteq(6, u16_strlen(c4));
return 0;
}
-UNICODE_TEST(unicode_test_u16_strlen);
+LIB_TEST(unicode_test_u16_strlen, 0);
static int unicode_test_u16_strnlen(struct unit_test_state *uts)
{
@@ -75,7 +72,7 @@ static int unicode_test_u16_strnlen(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_u16_strnlen);
+LIB_TEST(unicode_test_u16_strnlen, 0);
static int unicode_test_u16_strdup(struct unit_test_state *uts)
{
@@ -87,7 +84,7 @@ static int unicode_test_u16_strdup(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_u16_strdup);
+LIB_TEST(unicode_test_u16_strdup, 0);
static int unicode_test_u16_strcpy(struct unit_test_state *uts)
{
@@ -100,7 +97,7 @@ static int unicode_test_u16_strcpy(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_u16_strcpy);
+LIB_TEST(unicode_test_u16_strcpy, 0);
/* U-Boot uses UTF-16 strings in the EFI context only. */
#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
@@ -173,7 +170,7 @@ static int unicode_test_string16(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_string16);
+LIB_TEST(unicode_test_string16, 0);
#endif
static int unicode_test_utf8_get(struct unit_test_state *uts)
@@ -218,7 +215,7 @@ static int unicode_test_utf8_get(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_get);
+LIB_TEST(unicode_test_utf8_get, 0);
static int unicode_test_utf8_put(struct unit_test_state *uts)
{
@@ -256,7 +253,7 @@ static int unicode_test_utf8_put(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_put);
+LIB_TEST(unicode_test_utf8_put, 0);
static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts)
{
@@ -272,7 +269,7 @@ static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_utf16_strlen);
+LIB_TEST(unicode_test_utf8_utf16_strlen, 0);
static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts)
{
@@ -290,7 +287,7 @@ static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_utf16_strnlen);
+LIB_TEST(unicode_test_utf8_utf16_strnlen, 0);
/**
* ut_u16_strcmp() - Compare to u16 strings.
@@ -354,7 +351,7 @@ static int unicode_test_utf8_utf16_strcpy(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_utf16_strcpy);
+LIB_TEST(unicode_test_utf8_utf16_strcpy, 0);
static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts)
{
@@ -398,7 +395,7 @@ static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_utf16_strncpy);
+LIB_TEST(unicode_test_utf8_utf16_strncpy, 0);
static int unicode_test_utf16_get(struct unit_test_state *uts)
{
@@ -424,7 +421,7 @@ static int unicode_test_utf16_get(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf16_get);
+LIB_TEST(unicode_test_utf16_get, 0);
static int unicode_test_utf16_put(struct unit_test_state *uts)
{
@@ -452,7 +449,7 @@ static int unicode_test_utf16_put(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf16_put);
+LIB_TEST(unicode_test_utf16_put, 0);
static int unicode_test_utf16_strnlen(struct unit_test_state *uts)
{
@@ -470,7 +467,7 @@ static int unicode_test_utf16_strnlen(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf16_strnlen);
+LIB_TEST(unicode_test_utf16_strnlen, 0);
static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts)
{
@@ -486,7 +483,7 @@ static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf16_utf8_strlen);
+LIB_TEST(unicode_test_utf16_utf8_strlen, 0);
static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts)
{
@@ -498,7 +495,7 @@ static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts)
ut_asserteq(12, utf16_utf8_strnlen(c4, 3));
return 0;
}
-UNICODE_TEST(unicode_test_utf16_utf8_strnlen);
+LIB_TEST(unicode_test_utf16_utf8_strnlen, 0);
static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts)
{
@@ -543,7 +540,7 @@ static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf16_utf8_strcpy);
+LIB_TEST(unicode_test_utf16_utf8_strcpy, 0);
static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts)
{
@@ -587,7 +584,7 @@ static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf16_utf8_strncpy);
+LIB_TEST(unicode_test_utf16_utf8_strncpy, 0);
static int unicode_test_utf_to_lower(struct unit_test_state *uts)
{
@@ -604,7 +601,7 @@ static int unicode_test_utf_to_lower(struct unit_test_state *uts)
#endif
return 0;
}
-UNICODE_TEST(unicode_test_utf_to_lower);
+LIB_TEST(unicode_test_utf_to_lower, 0);
static int unicode_test_utf_to_upper(struct unit_test_state *uts)
{
@@ -621,7 +618,7 @@ static int unicode_test_utf_to_upper(struct unit_test_state *uts)
#endif
return 0;
}
-UNICODE_TEST(unicode_test_utf_to_upper);
+LIB_TEST(unicode_test_utf_to_upper, 0);
static int unicode_test_u16_strcasecmp(struct unit_test_state *uts)
{
@@ -646,7 +643,7 @@ static int unicode_test_u16_strcasecmp(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_u16_strcasecmp);
+LIB_TEST(unicode_test_u16_strcasecmp, 0);
static int unicode_test_u16_strncmp(struct unit_test_state *uts)
{
@@ -659,7 +656,7 @@ static int unicode_test_u16_strncmp(struct unit_test_state *uts)
ut_assert(u16_strcmp(u"deghi", u"abcdef") > 0);
return 0;
}
-UNICODE_TEST(unicode_test_u16_strncmp);
+LIB_TEST(unicode_test_u16_strncmp, 0);
static int unicode_test_u16_strsize(struct unit_test_state *uts)
{
@@ -669,7 +666,7 @@ static int unicode_test_u16_strsize(struct unit_test_state *uts)
ut_asserteq_64(u16_strsize(c4), 14);
return 0;
}
-UNICODE_TEST(unicode_test_u16_strsize);
+LIB_TEST(unicode_test_u16_strsize, 0);
static int unicode_test_utf_to_cp(struct unit_test_state *uts)
{
@@ -698,7 +695,7 @@ static int unicode_test_utf_to_cp(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf_to_cp);
+LIB_TEST(unicode_test_utf_to_cp, 0);
static void utf8_to_cp437_stream_helper(const char *in, char *out)
{
@@ -729,7 +726,7 @@ static int unicode_test_utf8_to_cp437_stream(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_to_cp437_stream);
+LIB_TEST(unicode_test_utf8_to_cp437_stream, 0);
static void utf8_to_utf32_stream_helper(const char *in, s32 *out)
{
@@ -778,7 +775,7 @@ static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_utf8_to_utf32_stream);
+LIB_TEST(unicode_test_utf8_to_utf32_stream, 0);
#ifdef CONFIG_EFI_LOADER
static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts)
@@ -795,7 +792,7 @@ static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_efi_create_indexed_name);
+LIB_TEST(unicode_test_efi_create_indexed_name, 0);
#endif
static int unicode_test_u16_strlcat(struct unit_test_state *uts)
@@ -846,13 +843,4 @@ static int unicode_test_u16_strlcat(struct unit_test_state *uts)
return 0;
}
-UNICODE_TEST(unicode_test_u16_strlcat);
-
-int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test);
- const int n_ents = UNIT_TEST_SUITE_COUNT(unicode_test);
-
- return cmd_ut_category("Unicode", "unicode_test_",
- tests, n_ents, argc, argv);
-}
+LIB_TEST(unicode_test_u16_strlcat, 0);
diff --git a/test/py/conftest.py b/test/py/conftest.py
index 46a410cf268..d9f074f3817 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -23,6 +23,7 @@ from pathlib import Path
import pytest
import re
from _pytest.runner import runtestprotocol
+import subprocess
import sys
from u_boot_spawn import BootFail, Timeout, Unexpected, handle_exception
@@ -65,12 +66,16 @@ def pytest_addoption(parser):
parser.addoption('--build-dir', default=None,
help='U-Boot build directory (O=)')
+ parser.addoption('--build-dir-extra', default=None,
+ help='U-Boot build directory for extra build (O=)')
parser.addoption('--result-dir', default=None,
help='U-Boot test result/tmp directory')
parser.addoption('--persistent-data-dir', default=None,
help='U-Boot test persistent generated data directory')
parser.addoption('--board-type', '--bd', '-B', default='sandbox',
help='U-Boot board type')
+ parser.addoption('--board-type-extra', '--bde', default='sandbox',
+ help='U-Boot extra board type')
parser.addoption('--board-identity', '--id', default='na',
help='U-Boot board identity/instance')
parser.addoption('--build', default=False, action='store_true',
@@ -80,6 +85,9 @@ def pytest_addoption(parser):
parser.addoption('--gdbserver', default=None,
help='Run sandbox under gdbserver. The argument is the channel '+
'over which gdbserver should communicate, e.g. localhost:1234')
+ 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")
def run_build(config, source_dir, build_dir, board_type, log):
"""run_build: Build U-Boot
@@ -125,26 +133,71 @@ def get_details(config):
Returns:
tuple:
str: Board type (U-Boot build name)
+ str: Extra board type (where two U-Boot builds are needed)
str: Identity for the lab board
str: Build directory
+ str: Extra build directory (where two U-Boot builds are needed)
str: Source directory
"""
- board_type = config.getoption('board_type')
- board_identity = config.getoption('board_identity')
+ role = config.getoption('role')
+
+ # Get a few provided parameters
build_dir = config.getoption('build_dir')
+ build_dir_extra = config.getoption('build_dir_extra')
+ if role:
+ # When using a role, build_dir and build_dir_extra are normally not set,
+ # since they are picked up from Labgrid-sjg via the u-boot-test-getrole
+ # script
+ board_identity = role
+ cmd = ['u-boot-test-getrole', role, '--configure']
+ env = os.environ.copy()
+ if build_dir:
+ 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',
+ env=env)
+ if proc.returncode:
+ raise ValueError(proc.stderr)
+ # For debugging
+ # print('conftest: lab:', proc.stdout)
+ vals = {}
+ for line in proc.stdout.splitlines():
+ item, value = line.split(' ', maxsplit=1)
+ k = item.split(':')[-1]
+ vals[k] = value
+ # For debugging
+ # print('conftest: lab info:', vals)
+
+ # Read the build directories here, in case none were provided in the
+ # command-line arguments
+ (board_type, board_type_extra, default_build_dir,
+ default_build_dir_extra, source_dir) = (vals['board'],
+ vals['board_extra'], vals['build_dir'], vals['build_dir_extra'],
+ vals['source_dir'])
+ else:
+ board_type = config.getoption('board_type')
+ board_type_extra = config.getoption('board_type_extra')
+ board_identity = config.getoption('board_identity')
+
+ source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR))
+ default_build_dir = source_dir + '/build-' + board_type
+ default_build_dir_extra = source_dir + '/build-' + board_type_extra
- source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR))
- default_build_dir = source_dir + '/build-' + board_type
+ # Use the provided command-line arguments if present, else fall back to
if not build_dir:
build_dir = default_build_dir
+ if not build_dir_extra:
+ build_dir_extra = default_build_dir_extra
- return board_type, board_identity, build_dir, source_dir
+ return (board_type, board_type_extra, board_identity, build_dir,
+ build_dir_extra, source_dir)
def pytest_xdist_setupnodes(config, specs):
"""Clear out any 'done' file from a previous build"""
global build_done_file
- build_dir = get_details(config)[2]
+ build_dir = get_details(config)[3]
build_done_file = Path(build_dir) / 'build.done'
if build_done_file.exists():
@@ -184,7 +237,8 @@ def pytest_configure(config):
global console
global ubconfig
- board_type, board_identity, build_dir, source_dir = get_details(config)
+ (board_type, board_type_extra, board_identity, build_dir, build_dir_extra,
+ source_dir) = get_details(config)
board_type_filename = board_type.replace('-', '_')
board_identity_filename = board_identity.replace('-', '_')
@@ -249,20 +303,25 @@ def pytest_configure(config):
ubconfig.test_py_dir = TEST_PY_DIR
ubconfig.source_dir = source_dir
ubconfig.build_dir = build_dir
+ ubconfig.build_dir_extra = build_dir_extra
ubconfig.result_dir = result_dir
ubconfig.persistent_data_dir = persistent_data_dir
ubconfig.board_type = board_type
+ ubconfig.board_type_extra = board_type_extra
ubconfig.board_identity = board_identity
ubconfig.gdbserver = gdbserver
+ ubconfig.use_running_system = config.getoption('use_running_system')
ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb'
ubconfig.connection_ok = True
env_vars = (
'board_type',
+ 'board_type_extra',
'board_identity',
'source_dir',
'test_py_dir',
'build_dir',
+ 'build_dir_extra',
'result_dir',
'persistent_data_dir',
)
diff --git a/test/py/tests/bootstd/flash1.img.xz b/test/py/tests/bootstd/flash1.img.xz
new file mode 100644
index 00000000000..29b78c62a9b
--- /dev/null
+++ b/test/py/tests/bootstd/flash1.img.xz
Binary files differ
diff --git a/test/py/tests/test_spi.py b/test/py/tests/test_spi.py
index caca9303271..44e54738dd0 100644
--- a/test/py/tests/test_spi.py
+++ b/test/py/tests/test_spi.py
@@ -695,7 +695,7 @@ def test_spi_negative(u_boot_console):
# Read to relocation address
output = u_boot_console.run_command('bdinfo')
- m = re.search('relocaddr\s*= (.+)', output)
+ m = re.search(r'relocaddr\s*= (.+)', output)
res_area = int(m.group(1), 16)
start = 0
diff --git a/test/py/tests/test_usb.py b/test/py/tests/test_usb.py
index fb3d20f0826..2397fd3c2e7 100644
--- a/test/py/tests/test_usb.py
+++ b/test/py/tests/test_usb.py
@@ -288,6 +288,47 @@ def test_usb_fatls_fatinfo(u_boot_console):
if not part_detect:
pytest.skip('No %s partition detected' % fs.upper())
+def usb_fatload_fatwrite(u_boot_console, fs, x, part):
+ addr = u_boot_utils.find_ram_base(u_boot_console)
+ size = random.randint(4, 1 * 1024 * 1024)
+ output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+ m = re.search('==> (.+?)', output)
+ if not m:
+ pytest.fail('CRC32 failed')
+ expected_crc32 = m.group(1)
+
+ file = '%s_%d' % ('uboot_test', size)
+ output = u_boot_console.run_command(
+ '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size)
+ )
+ assert 'Unable to write' not in output
+ assert 'Error' not in output
+ assert 'overflow' not in output
+ expected_text = '%d bytes written' % size
+ assert expected_text in output
+
+ alignment = int(
+ u_boot_console.config.buildconfig.get(
+ 'config_sys_cacheline_size', 128
+ )
+ )
+ offset = random.randrange(alignment, 1024, alignment)
+ output = u_boot_console.run_command(
+ '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file)
+ )
+ assert 'Invalid FAT entry' not in output
+ assert 'Unable to read file' not in output
+ assert 'Misaligned buffer address' not in output
+ expected_text = '%d bytes read' % size
+ assert expected_text in output
+
+ output = u_boot_console.run_command(
+ 'crc32 %x $filesize' % (addr + offset)
+ )
+ assert expected_crc32 in output
+
+ return file, size, expected_crc32
+
@pytest.mark.buildconfigspec('cmd_usb')
@pytest.mark.buildconfigspec('cmd_fat')
@pytest.mark.buildconfigspec('cmd_memory')
@@ -309,49 +350,11 @@ def test_usb_fatload_fatwrite(u_boot_console):
for part in partitions:
part_detect = 1
- addr = u_boot_utils.find_ram_base(u_boot_console)
- size = random.randint(4, 1 * 1024 * 1024)
- output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
- m = re.search('==> (.+?)', output)
- if not m:
- pytest.fail('CRC32 failed')
- expected_crc32 = m.group(1)
-
- file = '%s_%d' % ('uboot_test', size)
- output = u_boot_console.run_command(
- '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size)
- )
- assert 'Unable to write' not in output
- assert 'Error' not in output
- assert 'overflow' not in output
- expected_text = '%d bytes written' % size
- assert expected_text in output
-
- alignment = int(
- u_boot_console.config.buildconfig.get(
- 'config_sys_cacheline_size', 128
- )
- )
- offset = random.randrange(alignment, 1024, alignment)
- output = u_boot_console.run_command(
- '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file)
- )
- assert 'Invalid FAT entry' not in output
- assert 'Unable to read file' not in output
- assert 'Misaligned buffer address' not in output
- expected_text = '%d bytes read' % size
- assert expected_text in output
-
- output = u_boot_console.run_command(
- 'crc32 %x $filesize' % (addr + offset)
- )
- assert expected_crc32 in output
+ usb_fatload_fatwrite(u_boot_console, fs, x, part)
if not part_detect:
pytest.skip('No %s partition detected' % fs.upper())
- return file, size
-
@pytest.mark.buildconfigspec('cmd_usb')
@pytest.mark.buildconfigspec('cmd_ext4')
def test_usb_ext4ls(u_boot_console):
@@ -380,9 +383,42 @@ def test_usb_ext4ls(u_boot_console):
if not part_detect:
pytest.skip('No %s partition detected' % fs.upper())
+def usb_ext4load_ext4write(u_boot_console, fs, x, part):
+ addr = u_boot_utils.find_ram_base(u_boot_console)
+ size = random.randint(4, 1 * 1024 * 1024)
+ output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+ m = re.search('==> (.+?)', output)
+ if not m:
+ pytest.fail('CRC32 failed')
+ expected_crc32 = m.group(1)
+ file = '%s_%d' % ('uboot_test', size)
+
+ output = u_boot_console.run_command(
+ '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
+ )
+ assert 'Unable to write' not in output
+ assert 'Error' not in output
+ assert 'overflow' not in output
+ expected_text = '%d bytes written' % size
+ assert expected_text in output
+
+ offset = random.randrange(128, 1024, 128)
+ output = u_boot_console.run_command(
+ '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
+ )
+ expected_text = '%d bytes read' % size
+ assert expected_text in output
+
+ output = u_boot_console.run_command(
+ 'crc32 %x $filesize' % (addr + offset)
+ )
+ assert expected_crc32 in output
+
+ return file, size, expected_crc32
+
@pytest.mark.buildconfigspec('cmd_usb')
@pytest.mark.buildconfigspec('cmd_ext4')
-@pytest.mark.buildconfigspec('ext4_write')
+@pytest.mark.buildconfigspec('cmd_ext4_write')
@pytest.mark.buildconfigspec('cmd_memory')
def test_usb_ext4load_ext4write(u_boot_console):
devices, controllers, storage_device = test_usb_part(u_boot_console)
@@ -402,41 +438,11 @@ def test_usb_ext4load_ext4write(u_boot_console):
for part in partitions:
part_detect = 1
- addr = u_boot_utils.find_ram_base(u_boot_console)
- size = random.randint(4, 1 * 1024 * 1024)
- output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
- m = re.search('==> (.+?)', output)
- if not m:
- pytest.fail('CRC32 failed')
- expected_crc32 = m.group(1)
- file = '%s_%d' % ('uboot_test', size)
-
- output = u_boot_console.run_command(
- '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
- )
- assert 'Unable to write' not in output
- assert 'Error' not in output
- assert 'overflow' not in output
- expected_text = '%d bytes written' % size
- assert expected_text in output
-
- offset = random.randrange(128, 1024, 128)
- output = u_boot_console.run_command(
- '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
- )
- expected_text = '%d bytes read' % size
- assert expected_text in output
-
- output = u_boot_console.run_command(
- 'crc32 %x $filesize' % (addr + offset)
- )
- assert expected_crc32 in output
+ usb_ext4load_ext4write(u_boot_console, fs, x, part)
if not part_detect:
pytest.skip('No %s partition detected' % fs.upper())
- return file, size
-
@pytest.mark.buildconfigspec('cmd_usb')
@pytest.mark.buildconfigspec('cmd_ext2')
def test_usb_ext2ls(u_boot_console):
@@ -469,11 +475,10 @@ def test_usb_ext2ls(u_boot_console):
@pytest.mark.buildconfigspec('cmd_usb')
@pytest.mark.buildconfigspec('cmd_ext2')
@pytest.mark.buildconfigspec('cmd_ext4')
-@pytest.mark.buildconfigspec('ext4_write')
+@pytest.mark.buildconfigspec('cmd_ext4_write')
@pytest.mark.buildconfigspec('cmd_memory')
def test_usb_ext2load(u_boot_console):
devices, controllers, storage_device = test_usb_part(u_boot_console)
- file, size = test_usb_ext4load_ext4write(u_boot_console)
if not devices:
pytest.skip('No devices detected')
@@ -491,12 +496,9 @@ def test_usb_ext2load(u_boot_console):
for part in partitions:
part_detect = 1
+ file, size, expected_crc32 = \
+ usb_ext4load_ext4write(u_boot_console, 'ext4', x, part)
addr = u_boot_utils.find_ram_base(u_boot_console)
- output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
- m = re.search('==> (.+?)', output)
- if not m:
- pytest.fail('CRC32 failed')
- expected_crc32 = m.group(1)
offset = random.randrange(128, 1024, 128)
output = u_boot_console.run_command(
@@ -543,6 +545,7 @@ def test_usb_ls(u_boot_console):
pytest.skip('No partition detected')
@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_ext4_write')
@pytest.mark.buildconfigspec('cmd_fs_generic')
def test_usb_load(u_boot_console):
devices, controllers, storage_device = test_usb_part(u_boot_console)
@@ -565,15 +568,11 @@ def test_usb_load(u_boot_console):
addr = u_boot_utils.find_ram_base(u_boot_console)
if fs == 'fat':
- file, size = test_usb_fatload_fatwrite(u_boot_console)
+ file, size, expected_crc32 = \
+ usb_fatload_fatwrite(u_boot_console, fs, x, part)
elif fs == 'ext4':
- file, size = test_usb_ext4load_ext4write(u_boot_console)
-
- output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
- m = re.search('==> (.+?)', output)
- if not m:
- pytest.fail('CRC32 failed')
- expected_crc32 = m.group(1)
+ file, size, expected_crc32 = \
+ usb_ext4load_ext4write(u_boot_console, fs, x, part)
offset = random.randrange(128, 1024, 128)
output = u_boot_console.run_command(
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index 39aa1035e34..6d44191976b 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -28,21 +28,22 @@ def mkdir_cond(dirname):
if not os.path.exists(dirname):
os.mkdir(dirname)
-def setup_image(cons, mmc_dev, part_type, second_part=False):
+def setup_image(cons, devnum, part_type, second_part=False, basename='mmc'):
"""Create a 20MB disk image with a single partition
Args:
cons (ConsoleBase): Console to use
- mmc_dev (int): MMC device number to use, e.g. 1
+ devnum (int): Device number to use, e.g. 1
part_type (int): Partition type, e.g. 0xc for FAT32
second_part (bool): True to contain a small second partition
+ basename (str): Base name to use in the filename, e.g. 'mmc'
Returns:
tuple:
str: Filename of MMC image
str: Directory name of 'mnt' directory
"""
- fname = os.path.join(cons.config.source_dir, f'mmc{mmc_dev}.img')
+ fname = os.path.join(cons.config.source_dir, f'{basename}{devnum}.img')
mnt = os.path.join(cons.config.persistent_data_dir, 'mnt')
mkdir_cond(mnt)
@@ -78,16 +79,17 @@ def mount_image(cons, fname, mnt, fstype):
u_boot_utils.run_and_log(cons, f'sudo chown {getpass.getuser()} {mnt}')
return loop
-def copy_prepared_image(cons, mmc_dev, fname):
+def copy_prepared_image(cons, devnum, fname, basename='mmc'):
"""Use a prepared image since we cannot create one
Args:
cons (ConsoleBase): Console touse
- mmc_dev (int): MMC device number
+ devnum (int): device number
fname (str): Filename of MMC image
+ basename (str): Base name to use in the filename, e.g. 'mmc'
"""
infname = os.path.join(cons.config.source_dir,
- f'test/py/tests/bootstd/mmc{mmc_dev}.img.xz')
+ f'test/py/tests/bootstd/{basename}{devnum}.img.xz')
u_boot_utils.run_and_log(cons, ['sh', '-c', f'xz -dc {infname} >{fname}'])
def setup_bootmenu_image(cons):
@@ -208,8 +210,6 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
cons, f'echo here {kernel} {symlink}')
os.symlink(kernel, symlink)
- u_boot_utils.run_and_log(
- cons, f'mkimage -C none -A arm -T script -d {cmd_fname} {scr_fname}')
complete = True
except ValueError as exc:
@@ -549,6 +549,44 @@ def test_ut_dm_init(u_boot_console):
with open(fn, 'wb') as fh:
fh.write(data)
+
+def setup_efi_image(cons):
+ """Create a 20MB disk image with an EFI app on it"""
+ devnum = 1
+ basename = 'flash'
+ fname, mnt = setup_image(cons, devnum, 0xc, second_part=True,
+ basename=basename)
+
+ loop = None
+ mounted = False
+ complete = False
+ try:
+ loop = mount_image(cons, fname, mnt, 'ext4')
+ mounted = True
+ efi_dir = os.path.join(mnt, 'EFI')
+ mkdir_cond(efi_dir)
+ bootdir = os.path.join(efi_dir, 'BOOT')
+ mkdir_cond(bootdir)
+ efi_src = os.path.join(cons.config.build_dir,
+ f'lib/efi_loader/testapp.efi')
+ efi_dst = os.path.join(bootdir, 'BOOTSBOX.EFI')
+ with open(efi_src, 'rb') as inf:
+ with open(efi_dst, 'wb') as outf:
+ outf.write(inf.read())
+ complete = True
+ except ValueError as exc:
+ print(f'Falled to create image, failing back to prepared copy: {exc}')
+
+ finally:
+ if mounted:
+ u_boot_utils.run_and_log(cons, 'sudo umount --lazy %s' % mnt)
+ if loop:
+ u_boot_utils.run_and_log(cons, 'sudo losetup -d %s' % loop)
+
+ if not complete:
+ copy_prepared_image(cons, devnum, fname, basename)
+
+
@pytest.mark.buildconfigspec('cmd_bootflow')
@pytest.mark.buildconfigspec('sandbox')
def test_ut_dm_init_bootstd(u_boot_console):
@@ -559,6 +597,7 @@ def test_ut_dm_init_bootstd(u_boot_console):
setup_cedit_file(u_boot_console)
setup_cros_image(u_boot_console)
setup_android_image(u_boot_console)
+ setup_efi_image(u_boot_console)
# Restart so that the new mmc1.img is picked up
u_boot_console.restart_uboot()
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index d8d0bdf9fd4..fa9cd57b04b 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -23,12 +23,22 @@ pattern_stop_autoboot_prompt = re.compile('Hit any key to stop autoboot: ')
pattern_unknown_command = re.compile('Unknown command \'.*\' - try \'help\'')
pattern_error_notification = re.compile('## Error: ')
pattern_error_please_reset = re.compile('### ERROR ### Please RESET the board ###')
+pattern_ready_prompt = re.compile('{lab ready in (.*)s: (.*)}')
+pattern_lab_mode = re.compile('{lab mode.*}')
PAT_ID = 0
PAT_RE = 1
# Timeout before expecting the console to be ready (in milliseconds)
-TIMEOUT_MS = 30000
+TIMEOUT_MS = 30000 # Standard timeout
+TIMEOUT_CMD_MS = 10000 # Command-echo timeout
+
+# Timeout for board preparation in lab mode. This needs to be enough to build
+# U-Boot, write it to the board and then boot the board. Since this process is
+# under the control of another program (e.g. Labgrid), it will failure sooner
+# if something goes way. So use a very long timeout here to cover all possible
+# situations.
+TIMEOUT_PREPARE_MS = 3 * 60 * 1000
bad_pattern_defs = (
('spl_signon', pattern_u_boot_spl_signon),
@@ -142,6 +152,7 @@ class ConsoleBase(object):
self.at_prompt = False
self.at_prompt_logevt = None
+ self.lab_mode = False
def get_spawn(self):
# This is not called, ssubclass must define this.
@@ -172,43 +183,75 @@ class ConsoleBase(object):
"""
if self.p:
- self.p.close()
+ self.log.start_section('Stopping U-Boot')
+ close_type = self.p.close()
+ self.log.info(f'Close type: {close_type}')
+ self.log.end_section('Stopping U-Boot')
self.logstream.close()
+ def set_lab_mode(self):
+ """Select lab mode
+
+ This tells us that we will get a 'lab ready' message when the board is
+ ready for use. We don't need to look for signon messages.
+ """
+ self.log.info(f'test.py: Lab mode is active')
+ self.p.timeout = TIMEOUT_PREPARE_MS
+ self.lab_mode = True
+
def wait_for_boot_prompt(self, loop_num = 1):
"""Wait for the boot up until command prompt. This is for internal use only.
"""
try:
+ self.log.info('Waiting for U-Boot to be ready')
bcfg = self.config.buildconfig
config_spl_serial = bcfg.get('config_spl_serial', 'n') == 'y'
env_spl_skipped = self.config.env.get('env__spl_skipped', False)
env_spl_banner_times = self.config.env.get('env__spl_banner_times', 1)
- while loop_num > 0:
+ while not self.lab_mode and loop_num > 0:
loop_num -= 1
while config_spl_serial and not env_spl_skipped and env_spl_banner_times > 0:
- m = self.p.expect([pattern_u_boot_spl_signon] +
- self.bad_patterns)
- if m != 0:
+ m = self.p.expect([pattern_u_boot_spl_signon,
+ pattern_lab_mode] + self.bad_patterns)
+ if m == 1:
+ self.set_lab_mode()
+ break
+ elif m != 0:
raise BootFail('Bad pattern found on SPL console: ' +
- self.bad_pattern_ids[m - 1])
+ self.bad_pattern_ids[m - 1])
env_spl_banner_times -= 1
- m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
- if m != 0:
- raise BootFail('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 1])
- self.u_boot_version_string = self.p.after
+ if not self.lab_mode:
+ m = self.p.expect([pattern_u_boot_main_signon,
+ pattern_lab_mode] + self.bad_patterns)
+ if m == 1:
+ self.set_lab_mode()
+ elif m != 0:
+ raise BootFail('Bad pattern found on console: ' +
+ self.bad_pattern_ids[m - 1])
+ if not self.lab_mode:
+ self.u_boot_version_string = self.p.after
while True:
- m = self.p.expect([self.prompt_compiled,
+ m = self.p.expect([self.prompt_compiled, pattern_ready_prompt,
pattern_stop_autoboot_prompt] + self.bad_patterns)
if m == 0:
+ self.log.info(f'Found ready prompt {m}')
break
- if m == 1:
+ elif m == 1:
+ m = pattern_ready_prompt.search(self.p.after)
+ self.u_boot_version_string = m.group(2)
+ self.log.info(f'Lab: Board is ready')
+ self.p.timeout = TIMEOUT_MS
+ break
+ if m == 2:
+ self.log.info(f'Found autoboot prompt {m}')
self.p.send(' ')
continue
- raise BootFail('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 2])
+ if not self.lab_mode:
+ raise BootFail('Missing prompt / ready message on console: ' +
+ self.bad_pattern_ids[m - 3])
+ self.log.info(f'U-Boot is ready')
finally:
self.log.timestamp()
@@ -261,22 +304,28 @@ class ConsoleBase(object):
try:
self.at_prompt = False
+ if not self.p:
+ raise BootFail(
+ f"Lab failure: Connection lost when sending command '{cmd}'")
+
if send_nl:
cmd += '\n'
- while cmd:
- # Limit max outstanding data, so UART FIFOs don't overflow
- chunk = cmd[:self.max_fifo_fill]
- cmd = cmd[self.max_fifo_fill:]
- self.p.send(chunk)
- if not wait_for_echo:
- continue
- chunk = re.escape(chunk)
- chunk = chunk.replace('\\\n', '[\r\n]')
- m = self.p.expect([chunk] + self.bad_patterns)
- if m != 0:
- self.at_prompt = False
- raise BootFail('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 1])
+ rem = cmd # Remaining to be sent
+ with self.temporary_timeout(TIMEOUT_CMD_MS):
+ while rem:
+ # Limit max outstanding data, so UART FIFOs don't overflow
+ chunk = rem[:self.max_fifo_fill]
+ rem = rem[self.max_fifo_fill:]
+ self.p.send(chunk)
+ if not wait_for_echo:
+ continue
+ chunk = re.escape(chunk)
+ chunk = chunk.replace('\\\n', '[\r\n]')
+ m = self.p.expect([chunk] + self.bad_patterns)
+ if m != 0:
+ self.at_prompt = False
+ raise BootFail(f"Failed to get echo on console (cmd '{cmd}':rem '{rem}'): " +
+ self.bad_pattern_ids[m - 1])
if not wait_for_prompt:
return
if wait_for_reboot:
@@ -440,11 +489,17 @@ class ConsoleBase(object):
if not self.config.gdbserver:
self.p.timeout = TIMEOUT_MS
self.p.logfile_read = self.logstream
- if expect_reset:
- loop_num = 2
+ if self.config.use_running_system:
+ # Send an empty command to set up the 'expect' logic. This has
+ # the side effect of ensuring that there was no partial command
+ # line entered
+ self.run_command(' ')
else:
- loop_num = 1
- self.wait_for_boot_prompt(loop_num = loop_num)
+ if expect_reset:
+ loop_num = 2
+ else:
+ loop_num = 1
+ self.wait_for_boot_prompt(loop_num = loop_num)
self.at_prompt = True
self.at_prompt_logevt = self.logstream.logfile.cur_evt
except Exception as ex:
diff --git a/test/py/u_boot_console_exec_attach.py b/test/py/u_boot_console_exec_attach.py
index 8dd8cc1230c..8b253b4451d 100644
--- a/test/py/u_boot_console_exec_attach.py
+++ b/test/py/u_boot_console_exec_attach.py
@@ -59,14 +59,27 @@ class ConsoleExecAttach(ConsoleBase):
args = [self.config.board_type, self.config.board_identity]
s = Spawn(['u-boot-test-console'] + args)
- try:
- self.log.action('Resetting board')
- cmd = ['u-boot-test-reset'] + args
- runner = self.log.get_runner(cmd[0], sys.stdout)
- runner.run(cmd)
- runner.close()
- except:
- s.close()
- raise
+ if self.config.use_running_system:
+ self.log.action('Connecting to board without reset')
+ else:
+ try:
+ self.log.action('Resetting board')
+ cmd = ['u-boot-test-reset'] + args
+ runner = self.log.get_runner(cmd[0], sys.stdout)
+ runner.run(cmd)
+ runner.close()
+ except:
+ s.close()
+ raise
return s
+
+ def close(self):
+ super().close()
+
+ self.log.action('Releasing board')
+ args = [self.config.board_type, self.config.board_identity]
+ cmd = ['u-boot-test-release'] + args
+ runner = self.log.get_runner(cmd[0], sys.stdout)
+ runner.run(cmd)
+ runner.close()
diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py
index 24d369035e5..c703454389d 100644
--- a/test/py/u_boot_spawn.py
+++ b/test/py/u_boot_spawn.py
@@ -5,15 +5,21 @@
Logic to spawn a sub-process and interact with its stdio.
"""
+import io
import os
import re
import pty
import pytest
import signal
import select
+import sys
+import termios
import time
import traceback
+# Character to send (twice) to exit the terminal
+EXIT_CHAR = 0x1d # FS (Ctrl + ])
+
class Timeout(Exception):
"""An exception sub-class that indicates that a timeout occurred."""
@@ -115,11 +121,30 @@ class Spawn:
finally:
os._exit(255)
+ old = None
try:
+ isatty = False
+ try:
+ isatty = os.isatty(sys.stdout.fileno())
+
+ # with --capture=tee-sys we cannot call fileno()
+ except io.UnsupportedOperation as exc:
+ pass
+ if isatty:
+ new = termios.tcgetattr(self.fd)
+ old = new
+ new[3] = new[3] & ~(termios.ICANON | termios.ISIG)
+ new[3] = new[3] & ~termios.ECHO
+ new[6][termios.VMIN] = 0
+ new[6][termios.VTIME] = 0
+ termios.tcsetattr(self.fd, termios.TCSANOW, new)
+
self.poll = select.poll()
self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR |
select.POLLHUP | select.POLLNVAL)
except:
+ if old:
+ termios.tcsetattr(self.fd, termios.TCSANOW, old)
self.close()
raise
@@ -289,15 +314,28 @@ class Spawn:
None.
Returns:
- Nothing.
+ str: Type of closure completed
"""
-
+ # For Labgrid-sjg, ask it is exit gracefully, so it can transition the
+ # board to the final state (like 'off') before exiting.
+ if os.environ.get('USE_LABGRID_SJG'):
+ self.send(chr(EXIT_CHAR) * 2)
+
+ # Wait about 10 seconds for Labgrid to close and power off the board
+ for _ in range(100):
+ if not self.isalive():
+ return 'normal'
+ time.sleep(0.1)
+
+ # That didn't work, so try closing the PTY
os.close(self.fd)
for _ in range(100):
if not self.isalive():
- break
+ return 'break'
time.sleep(0.1)
+ return 'timeout'
+
def get_expect_output(self):
"""Return the output read by expect()
diff --git a/test/test-main.c b/test/test-main.c
index da5b07ce00b..8d764892fa6 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -4,6 +4,8 @@
* Written by Simon Glass <sjg@chromium.org>
*/
+#define LOG_CATEGORY LOGC_TEST
+
#include <blk.h>
#include <console.h>
#include <cyclic.h>
@@ -240,15 +242,22 @@ static bool test_matches(const char *prefix, const char *test_name,
* ut_list_has_dm_tests() - Check if a list of tests has driver model ones
*
* @tests: List of tests to run
- * @count: Number of tests to ru
+ * @count: Number of tests to run
+ * @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
+ * of the test name. If NULL, no prefix processing is done
+ * @select_name: Name of a single test being run (from the list provided). If
+ * NULL all tests are being run
* Return: true if any of the tests have the UTF_DM flag
*/
-static bool ut_list_has_dm_tests(struct unit_test *tests, int count)
+static bool ut_list_has_dm_tests(struct unit_test *tests, int count,
+ const char *prefix, const char *select_name)
{
struct unit_test *test;
for (test = tests; test < tests + count; test++) {
- if (test->flags & UTF_DM)
+ if (test_matches(prefix, test->name, select_name) &&
+ (test->flags & UTF_DM))
return true;
}
@@ -379,6 +388,12 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
return -EAGAIN;
}
}
+ if (test->flags & UFT_BLOBLIST) {
+ log_debug("save bloblist %p\n", gd_bloblist());
+ uts->old_bloblist = gd_bloblist();
+ gd_set_bloblist(NULL);
+ }
+
ut_silence_console(uts);
return 0;
@@ -402,6 +417,11 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test)
free(uts->of_other);
uts->of_other = NULL;
+ if (test->flags & UFT_BLOBLIST) {
+ gd_set_bloblist(uts->old_bloblist);
+ log_debug("restore bloblist %p\n", gd_bloblist());
+ }
+
blkcache_free();
return 0;
@@ -550,6 +570,9 @@ static int ut_run_test_live_flat(struct unit_test_state *uts,
* @count: Number of tests to run
* @select_name: Name of a single test to run (from the list provided). If NULL
* then all tests are run
+ * @test_insert: String describing a test to run after n other tests run, in the
+ * format n:name where n is the number of tests to run before this one and
+ * name is the name of the test to run
* Return: 0 if all tests passed, -ENOENT if test @select_name was not found,
* -EBADF if any failed
*/
@@ -594,14 +617,14 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
*/
len = strlen(test_name);
if (len < 6 || strcmp(test_name + len - 6, "_norun")) {
- printf("Test %s is manual so must have a name ending in _norun\n",
+ printf("Test '%s' is manual so must have a name ending in _norun\n",
test_name);
uts->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",
+ printf("Test '%s' skipped as it is manual (use -f to run it)\n",
test_name);
}
continue;
@@ -612,7 +635,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
if (one && upto == pos) {
ret = ut_run_test_live_flat(uts, one);
if (uts->fail_count != old_fail_count) {
- printf("Test %s failed %d times (position %d)\n",
+ printf("Test '%s' failed %d times (position %d)\n",
one->name,
uts->fail_count - old_fail_count, pos);
}
@@ -622,7 +645,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
for (i = 0; i < uts->runs_per_test; i++)
ret = ut_run_test_live_flat(uts, test);
if (uts->fail_count != old_fail_count) {
- printf("Test %s failed %d times\n", select_name,
+ printf("Test '%s' failed %d times\n", test_name,
uts->fail_count - old_fail_count);
}
found++;
@@ -646,7 +669,7 @@ int ut_run_list(const char *category, const char *prefix,
int ret;
if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
- ut_list_has_dm_tests(tests, count)) {
+ ut_list_has_dm_tests(tests, count, prefix, select_name)) {
has_dm_tests = true;
/*
* If we have no device tree, or it only has a root node, then
diff --git a/test/trace/test-trace.sh b/test/trace/test-trace.sh
deleted file mode 100755
index 5130b2bf017..00000000000
--- a/test/trace/test-trace.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: GPL-2.0+
-# Copyright (c) 2013 The Chromium OS Authors.
-#
-
-# Simple test script for tracing with sandbox
-
-TRACE_OPT="FTRACE=1"
-
-BASE="$(dirname $0)/.."
-. $BASE/common.sh
-
-run_trace() {
- echo "Run trace"
- ./${OUTPUT_DIR}/u-boot <<END
-trace stats
-hash sha256 0 10000
-trace pause
-trace stats
-hash sha256 0 10000
-trace stats
-trace resume
-hash sha256 0 10000
-trace pause
-trace stats
-reset
-END
-}
-
-check_results() {
- echo "Check results"
-
- # Expect sha256 to run 3 times, so we see the string 6 times
- if [ $(grep -c sha256 ${tmp}) -ne 6 ]; then
- fail "sha256 error"
- fi
-
- # 4 sets of results (output of 'trace stats')
- if [ $(grep -c "traced function calls" ${tmp}) -ne 4 ]; then
- fail "trace output error"
- fi
-
- # Check trace counts. We expect to see an increase in the number of
- # traced function calls between each 'trace stats' command, except
- # between calls 2 and 3, where tracing is paused.
- # This code gets the sign of the difference between each number and
- # its predecessor.
- counts="$(tr -d ',\r' <${tmp} | awk \
- '/traced function calls/ { diff = $1 - upto; upto = $1; \
- printf "%d ", diff < 0 ? -1 : (diff > 0 ? 1 : 0)}')"
-
- if [ "${counts}" != "1 1 0 1 " ]; then
- fail "trace collection error: ${counts}"
- fi
-}
-
-echo "Simple trace test / sanity check using sandbox"
-echo
-tmp="$(tempfile)"
-build_uboot "${TRACE_OPT}"
-run_trace >${tmp}
-check_results ${tmp}
-rm ${tmp}
-echo "Test passed"