summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile6
-rw-r--r--test/boot/Makefile2
-rw-r--r--test/boot/bootdev.c12
-rw-r--r--test/boot/bootflow.c7
-rw-r--r--test/cmd/Makefile3
-rw-r--r--test/cmd/command.c31
-rw-r--r--test/cmd/spawn.c32
-rw-r--r--test/common/Makefile6
-rw-r--r--test/common/print.c8
-rw-r--r--test/dm/Makefile2
-rw-r--r--test/dm/acpi.c59
-rw-r--r--test/dm/acpigen.c115
-rw-r--r--test/dm/dsa.c8
-rw-r--r--test/dm/eth.c77
-rw-r--r--test/dm/power-domain.c11
-rw-r--r--test/dm/test-fdt.c20
-rw-r--r--test/fuzz/Makefile2
-rw-r--r--test/lib/Makefile7
-rw-r--r--test/lib/initjmp.c73
-rw-r--r--test/lib/membuf.c239
-rw-r--r--test/lib/uthread.c146
-rw-r--r--test/py/conftest.py22
-rw-r--r--test/py/console_base.py25
-rw-r--r--test/py/pytest.ini1
-rw-r--r--test/py/requirements.txt1
-rw-r--r--test/py/tests/fs_helper.py42
-rw-r--r--test/py/tests/test_cat.py37
-rw-r--r--test/py/tests/test_cat/conftest.py36
-rw-r--r--test/py/tests/test_cat/test_cat.py20
-rw-r--r--test/py/tests/test_distro.py61
-rw-r--r--test/py/tests/test_efi_bootmgr.py70
-rw-r--r--test/py/tests/test_efi_bootmgr/conftest.py38
-rw-r--r--test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py44
-rw-r--r--test/py/tests/test_efi_capsule/capsule_common.py2
-rw-r--r--test/py/tests/test_efi_capsule/conftest.py45
-rw-r--r--test/py/tests/test_efi_secboot/conftest.py52
-rw-r--r--test/py/tests/test_eficonfig.py (renamed from test/py/tests/test_eficonfig/test_eficonfig.py)53
-rw-r--r--test/py/tests/test_eficonfig/conftest.py40
-rw-r--r--test/py/tests/test_fs/conftest.py46
-rw-r--r--test/py/tests/test_fs/fstest_helpers.py2
-rw-r--r--test/py/tests/test_fs/test_basic.py84
-rw-r--r--test/py/tests/test_fs/test_ext.py176
-rw-r--r--test/py/tests/test_fs/test_mkdir.py42
-rw-r--r--test/py/tests/test_fs/test_unlink.py38
-rw-r--r--test/py/tests/test_memtest.py8
-rw-r--r--test/py/tests/test_spi.py29
-rw-r--r--test/py/tests/test_trace.py8
-rw-r--r--test/py/tests/test_ut.py47
-rw-r--r--test/py/tests/test_xxd.py40
-rw-r--r--test/py/tests/test_xxd/conftest.py36
-rw-r--r--test/py/tests/test_xxd/test_xxd.py23
51 files changed, 1440 insertions, 594 deletions
diff --git a/test/Makefile b/test/Makefile
index 99d4797d968..f7ab9a36b2a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -4,15 +4,15 @@
obj-y += test-main.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/
-obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_ut.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += cmd/
+obj-$(CONFIG_$(PHASE_)CMDLINE) += cmd_ut.o
obj-y += dm/
obj-$(CONFIG_FUZZ) += fuzz/
ifndef CONFIG_SANDBOX_VPL
obj-$(CONFIG_UNIT_TEST) += lib/
endif
ifneq ($(CONFIG_HUSH_PARSER),)
-obj-$(CONFIG_$(XPL_)CMDLINE) += hush/
+obj-$(CONFIG_$(PHASE_)CMDLINE) += hush/
endif
obj-$(CONFIG_UT_OPTEE) += optee/
obj-y += ut.o
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 63487e8d29e..00223b44fe0 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_CEDIT) += cedit.o
endif
ifdef CONFIG_SANDBOX
-obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += bootm.o
endif
obj-$(CONFIG_MEASURED_BOOT) += measurement.o
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 5f07430714e..9af94786870 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -392,8 +392,7 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
ut_assert_console_end();
ut_assertok(bootdev_hunt("usb1", false));
- ut_assert_nextline(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
/* USB is 7th in the list, so bit 8 */
@@ -448,8 +447,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline("scanning bus for devices...");
ut_assert_skip_to_line("Hunting with: spi_flash");
ut_assert_nextline("Hunting with: usb");
- ut_assert_nextline(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_nextline("Hunting with: virtio");
ut_assert_console_end();
@@ -509,6 +507,7 @@ static int bootdev_test_bootable(struct unit_test_state *uts)
iter.part = 0;
ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk));
iter.dev = blk;
+ iter.flags = BOOTFLOWIF_ONLY_BOOTABLE;
ut_assertok(device_find_next_child(&iter.dev));
uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
@@ -550,8 +549,7 @@ static int bootdev_test_hunt_prio(struct unit_test_state *uts)
ut_assertok(bootdev_hunt_prio(BOOTDEVP_5_SCAN_SLOW, true));
ut_assert_nextline("Hunting with: ide");
ut_assert_nextline("Hunting with: usb");
- ut_assert_nextline(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
return 0;
@@ -603,7 +601,7 @@ static int bootdev_test_hunt_label(struct unit_test_state *uts)
ut_assertnonnull(dev);
ut_asserteq_str("usb_mass_storage.lun0.bootdev", dev->name);
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
- ut_assert_nextlinen("Bus usb@1: scanning bus usb@1");
+ ut_assert_nextline("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
return 0;
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index eb7f00af39a..b261bd5f620 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -297,8 +297,9 @@ static int bootflow_iter(struct unit_test_state *uts)
/* The first device is mmc2.bootdev which has no media */
ut_asserteq(-EPROTONOSUPPORT,
- bootflow_scan_first(NULL, NULL, &iter,
- BOOTFLOWIF_ALL | BOOTFLOWIF_SKIP_GLOBAL, &bflow));
+ bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWIF_ALL |
+ BOOTFLOWIF_SKIP_GLOBAL |
+ BOOTFLOWIF_ONLY_BOOTABLE, &bflow));
ut_asserteq(2, iter.num_methods);
ut_asserteq(0, iter.cur_method);
ut_asserteq(0, iter.part);
@@ -1289,7 +1290,7 @@ static int bootflow_efi(struct unit_test_state *uts)
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");
+ "Bus usb@1: 5 USB Device(s) found");
ut_assertok(run_command("bootflow list", 0));
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index d8a5e77402d..595e4cfcada 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -3,7 +3,7 @@
# Copyright (c) 2013 Google, Inc
# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
-obj-$(CONFIG_$(XPL_)CMDLINE) += command.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += command.o
ifdef CONFIG_HUSH_PARSER
obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o
endif
@@ -39,3 +39,4 @@ obj-$(CONFIG_CMD_WGET) += wget.o
endif
obj-$(CONFIG_ARM_FFA_TRANSPORT) += armffa.o
endif
+obj-$(CONFIG_CMD_SPAWN) += spawn.o
diff --git a/test/cmd/command.c b/test/cmd/command.c
index 5ec93d490ba..5b1e5a77e5d 100644
--- a/test/cmd/command.c
+++ b/test/cmd/command.c
@@ -45,31 +45,32 @@ static int command_test(struct unit_test_state *uts)
"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));
+ if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
+ ut_asserteq(1, run_command("false", 0));
+ ut_asserteq(1, run_command_list("false", -1, 0));
+ 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")));
+ ut_assertok(run_command("", 0));
+ ut_assertok(run_command(" ", 0));
+ }
ut_asserteq(1, run_command("'", 0));
/* Variadic function test-cases */
+ if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-zero-length"
- ut_assertok(run_commandf(""));
+ ut_assertok(run_commandf(""));
#pragma GCC diagnostic pop
- ut_assertok(run_commandf(" "));
+ ut_assertok(run_commandf(" "));
+ }
ut_asserteq(1, run_commandf("'"));
ut_assertok(run_commandf("env %s %s", "delete -f", "list"));
diff --git a/test/cmd/spawn.c b/test/cmd/spawn.c
new file mode 100644
index 00000000000..8f48f5ee25c
--- /dev/null
+++ b/test/cmd/spawn.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Tests for spawn and wait commands
+ *
+ * Copyright 2025, Linaro Ltd.
+ */
+
+#include <command.h>
+#include <test/cmd.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int test_cmd_spawn(struct unit_test_state *uts)
+{
+ ut_assertok(run_command("wait; spawn sleep 2; setenv j ${job_id}; "
+ "spawn setenv spawned true; "
+ "setenv jj ${job_id}; wait; "
+ "echo ${j} ${jj} ${spawned}", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "1 2 true"));
+
+ ut_assertok(run_command("spawn true; wait; setenv t $?; spawn false; "
+ "wait; setenv f $?; wait; echo $t $f $?", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "0 1 0"));
+ ut_assert_console_end();
+
+ return 0;
+}
+CMD_TEST(test_cmd_spawn, UTF_CONSOLE);
diff --git a/test/common/Makefile b/test/common/Makefile
index 1ad6c24b7e2..baefc7b3622 100644
--- a/test/common/Makefile
+++ b/test/common/Makefile
@@ -1,13 +1,13 @@
# SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_AUTOBOOT) += test_autoboot.o
-ifneq ($(CONFIG_$(XPL_)BLOBLIST),)
+ifneq ($(CONFIG_$(PHASE_)BLOBLIST),)
ifdef CONFIG_BLOBLIST_FIXED
-obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += bloblist.o
endif
endif
obj-$(CONFIG_CYCLIC) += cyclic.o
obj-$(CONFIG_EVENT_DYNAMIC) += event.o
obj-y += cread.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += print.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += print.o
diff --git a/test/common/print.c b/test/common/print.c
index e3711b10809..c48efc2783f 100644
--- a/test/common/print.c
+++ b/test/common/print.c
@@ -45,11 +45,11 @@ static int print_guid(struct unit_test_state *uts)
sprintf(str, "%pUL", guid);
ut_asserteq_str("04030201-0605-0807-090A-0B0C0D0E0F10", str);
sprintf(str, "%pUs", guid_esp);
- if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) { /* brace needed */
- ut_asserteq_str("system", str);
- } else {
+ if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) ||
+ IS_ENABLED(CONFIG_CMD_EFIDEBUG) || IS_ENABLED(CONFIG_EFI))
+ ut_asserteq_str("EFI System Partition", str);
+ else
ut_asserteq_str("c12a7328-f81f-11d2-ba4b-00a0c93ec93b", str);
- }
ret = snprintf(str, 4, "%pUL", guid);
ut_asserteq(0, str[3]);
ut_asserteq(36, ret);
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 3afcc26ca57..917dafe7d22 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -46,9 +46,7 @@ obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
obj-$(CONFIG_DM_DSA) += dsa.o
obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o
-ifdef CONFIG_NET
obj-$(CONFIG_DM_ETH) += eth.o
-endif
obj-$(CONFIG_EXTCON) += extcon.o
ifneq ($(CONFIG_EFI_PARTITION),)
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index 39a26bbb492..db012b6d2f1 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -309,6 +309,8 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
}
ut_asserteq(0, ctx.rsdt->entry[3]);
ut_asserteq(0, ctx.xsdt->entry[3]);
+ unmap_sysmem(buf);
+ free(buf);
return 0;
}
@@ -386,6 +388,8 @@ static int dm_test_acpi_ctx_and_base_tables(struct unit_test_state *uts)
ut_asserteq(nomap_to_sysmem(rsdt), rsdp->rsdt_address);
ut_asserteq(nomap_to_sysmem(xsdt), rsdp->xsdt_address);
+ unmap_sysmem(buf);
+ free(buf);
return 0;
}
@@ -428,11 +432,59 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
ut_assert_nextline("DMAR %16lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0",
addr, sizeof(struct acpi_dmar), OEM_REVISION);
ut_assert_console_end();
+ unmap_sysmem(buf);
+ free(buf);
return 0;
}
DM_TEST(dm_test_acpi_cmd_list, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE);
+/* Test 'acpi list -c' command */
+static int dm_test_acpi_cmd_list_chksum(struct unit_test_state *uts)
+{
+ struct acpi_ctx ctx;
+ ulong addr;
+ void *buf;
+
+ buf = memalign(16, BUF_SIZE);
+ ut_assertnonnull(buf);
+ addr = map_to_sysmem(buf);
+ ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
+
+ ut_assertok(acpi_write_dev_tables(&ctx));
+
+ run_command("acpi list -c", 0);
+ ut_assert_nextline("Name Base Size Detail");
+ ut_assert_nextline("---- ---------------- ----- ----------------------------");
+ ut_assert_nextline("RSDP %16lx %5zx v02 U-BOOT OK OK", addr,
+ sizeof(struct acpi_rsdp));
+ addr = ALIGN(addr + sizeof(struct acpi_rsdp), 16);
+ ut_assert_nextline("RSDT %16lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0 OK",
+ addr, sizeof(struct acpi_table_header) +
+ 3 * sizeof(u32), OEM_REVISION);
+ addr = ALIGN(addr + sizeof(struct acpi_rsdt), 16);
+ ut_assert_nextline("XSDT %16lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0 OK",
+ addr, sizeof(struct acpi_table_header) +
+ 3 * sizeof(u64), OEM_REVISION);
+ addr = ALIGN(addr + sizeof(struct acpi_xsdt), 64);
+ ut_assert_nextline("DMAR %16lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0 OK",
+ addr, sizeof(struct acpi_dmar), OEM_REVISION);
+ addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
+ ut_assert_nextline("DMAR %16lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0 OK",
+ addr, sizeof(struct acpi_dmar), OEM_REVISION);
+ addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
+ ut_assert_nextline("DMAR %16lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0 OK",
+ addr, sizeof(struct acpi_dmar), OEM_REVISION);
+ ut_assert_console_end();
+ ut_assert_console_end();
+ unmap_sysmem(buf);
+ free(buf);
+
+ return 0;
+}
+DM_TEST(dm_test_acpi_cmd_list_chksum,
+ UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE);
+
/* Test 'acpi dump' command */
static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
{
@@ -458,6 +510,8 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
ut_assert_nextline("DMAR @ %16lx", addr);
ut_assert_nextlines_are_dump(0x30);
ut_assert_console_end();
+ unmap_sysmem(buf);
+ free(buf);
return 0;
}
@@ -642,6 +696,8 @@ static int dm_test_acpi_cmd_items(struct unit_test_state *uts)
ut_assert_nextlines_are_dump(2);
ut_assert_nextline("%s", "");
ut_assert_console_end();
+ unmap_sysmem(buf);
+ free(buf);
return 0;
}
@@ -679,6 +735,8 @@ static int dm_test_acpi_cmd_set(struct unit_test_state *uts)
ut_asserteq(addr, gd_acpi_start());
ut_assert_console_end();
+ unmap_sysmem(buf);
+ free(buf);
return 0;
}
@@ -774,6 +832,7 @@ static int dm_test_acpi_find_table(struct unit_test_state *uts)
/* Restore previous ACPI tables */
gd_set_acpi_start(acpi_start);
+ unmap_sysmem(buf);
free(buf);
return 0;
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index 23c16bd9866..ee9517f9c29 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -1742,3 +1742,118 @@ static int dm_test_acpi_write_tsd_package(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_acpi_write_tsd_package, 0);
+
+static int dm_test_acpi_iort_smmu_v3(struct unit_test_state *uts)
+{
+ struct acpi_ctx *ctx;
+ int smmu_offset;
+ u8 *ptr;
+
+ ut_assertok(alloc_context(&ctx));
+ ctx->tab_start = ctx->current;
+ acpi_inc(ctx, sizeof(struct acpi_table_iort));
+
+ ptr = acpigen_get_current(ctx);
+
+ smmu_offset = acpi_iort_add_smmu_v3(ctx,
+ 0xaabbccddeeffULL, // Base address
+ 1, // Flags
+ 0xffeeddccaabbULL, // VATOS address
+ 0, // SMMUv3 Model
+ 3, // Event
+ 4, // Pri
+ 5, // Gerror
+ 6, // Sync
+ 7, // Proximity domain
+ 8, // DevIDMappingIndex
+ 0,
+ NULL);
+ ut_assert(smmu_offset);
+
+ ut_asserteq(ACPI_IORT_NODE_SMMU_V3, ptr[0]);
+ ut_asserteq(68, get_unaligned((u16 *)(ptr + 1)));
+ ut_asserteq(0, get_unaligned((u16 *)(ptr + 4)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 8)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 12)));
+
+ ut_asserteq_64(0xaabbccddeeffULL, get_unaligned((u64 *)(ptr + 16)));
+ ut_asserteq(1, get_unaligned((u32 *)(ptr + 24)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 28)));
+ ut_asserteq_64(0xffeeddccaabbULL, get_unaligned((u64 *)(ptr + 32)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 40)));
+ ut_asserteq(3, get_unaligned((u32 *)(ptr + 44)));
+ ut_asserteq(4, get_unaligned((u32 *)(ptr + 48)));
+ ut_asserteq(5, get_unaligned((u32 *)(ptr + 52)));
+ ut_asserteq(6, get_unaligned((u32 *)(ptr + 56)));
+ ut_asserteq(7, get_unaligned((u32 *)(ptr + 60)));
+ ut_asserteq(8, get_unaligned((u32 *)(ptr + 64)));
+
+ free_context(&ctx);
+
+ return 0;
+}
+DM_TEST(dm_test_acpi_iort_smmu_v3, 0);
+
+static int dm_test_acpi_iort_rc(struct unit_test_state *uts)
+{
+ struct acpi_ctx *ctx;
+ int its_group_offset, offset;
+ u8 *ptr;
+
+ ut_assertok(alloc_context(&ctx));
+ ctx->tab_start = ctx->current;
+ acpi_inc(ctx, sizeof(struct acpi_table_iort));
+
+ u32 identifiers[] = { 0 };
+
+ its_group_offset = acpi_iort_add_its_group(ctx, ARRAY_SIZE(identifiers),
+ identifiers);
+
+ ptr = acpigen_get_current(ctx);
+
+ struct acpi_iort_id_mapping map_rc[] = {
+ {0, 0xfff, 0, its_group_offset, 0},
+ {0x1000, 0xffff, 0x1000, its_group_offset, 0}
+ };
+
+ offset = acpi_iort_add_rc(ctx,
+ 0xaabbccddeeffULL, // Mem Access Properties
+ 2, // ATS attributes
+ 3, // PCI segment
+ 4, // Memory address size limit
+ ARRAY_SIZE(map_rc),
+ map_rc);
+
+ ut_assert(offset);
+ ut_asserteq(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, ptr[0]);
+ ut_asserteq(36 + ARRAY_SIZE(map_rc) * sizeof(struct acpi_iort_id_mapping),
+ get_unaligned((u16 *)(ptr + 1)));
+ ut_asserteq(0, get_unaligned((u16 *)(ptr + 4)));
+ ut_asserteq(2, get_unaligned((u32 *)(ptr + 8)));
+ ut_asserteq(36, get_unaligned((u32 *)(ptr + 12)));
+
+ ut_asserteq_64(0xaabbccddeeffULL, get_unaligned((u64 *)(ptr + 16)));
+ ut_asserteq(2, get_unaligned((u32 *)(ptr + 24)));
+ ut_asserteq(3, get_unaligned((u32 *)(ptr + 28)));
+ ut_asserteq(4, ptr[32]);
+ ut_asserteq(0, ptr[33]);
+ ut_asserteq(0, ptr[34]);
+ ut_asserteq(0, ptr[35]);
+
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 36)));
+ ut_asserteq(0xfff, get_unaligned((u32 *)(ptr + 40)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 44)));
+ ut_asserteq(its_group_offset, get_unaligned((u32 *)(ptr + 48)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 52)));
+
+ ut_asserteq(0x1000, get_unaligned((u32 *)(ptr + 56)));
+ ut_asserteq(0xffff, get_unaligned((u32 *)(ptr + 60)));
+ ut_asserteq(0x1000, get_unaligned((u32 *)(ptr + 64)));
+ ut_asserteq(its_group_offset, get_unaligned((u32 *)(ptr + 68)));
+ ut_asserteq(0, get_unaligned((u32 *)(ptr + 72)));
+
+ free_context(&ctx);
+
+ return 0;
+}
+DM_TEST(dm_test_acpi_iort_rc, 0); \ No newline at end of file
diff --git a/test/dm/dsa.c b/test/dm/dsa.c
index c6b4e12a758..9a31ae39d95 100644
--- a/test/dm/dsa.c
+++ b/test/dm/dsa.c
@@ -63,15 +63,15 @@ DM_TEST(dm_test_dsa_probe, UTF_SCAN_FDT);
*/
static int dm_test_dsa(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.2.3.5");
+ char *argv[] = { "ping", "1.1.2.2" };
env_set("ethact", "eth2");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
env_set("ethact", "lan0");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
env_set("ethact", "lan1");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
env_set("ethact", "");
diff --git a/test/dm/eth.c b/test/dm/eth.c
index 467495863e1..1087ae9572d 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -171,18 +171,18 @@ DM_TEST(dm_test_ip6_make_lladdr, UTF_SCAN_FDT);
static int dm_test_eth(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.1.2.2");
+ char *argv[] = { "ping", "1.1.2.2" };
env_set("ethact", "eth@10002000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
env_set("ethact", "eth@10003000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10003000", env_get("ethact"));
env_set("ethact", "eth@10004000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
return 0;
@@ -191,22 +191,23 @@ DM_TEST(dm_test_eth, UTF_SCAN_FDT);
static int dm_test_eth_alias(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.1.2.2");
+ char *argv[] = { "ping", "1.1.2.2" };
+
env_set("ethact", "eth0");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
env_set("ethact", "eth6");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
/* Expected to fail since eth1 is not defined in the device tree */
env_set("ethact", "eth1");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
env_set("ethact", "eth5");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10003000", env_get("ethact"));
return 0;
@@ -215,18 +216,18 @@ DM_TEST(dm_test_eth_alias, UTF_SCAN_FDT);
static int dm_test_eth_prime(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.1.2.2");
+ char *argv[] = { "ping", "1.1.2.2" };
/* Expected to be "eth@10003000" because of ethprime variable */
env_set("ethact", NULL);
env_set("ethprime", "eth5");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10003000", env_get("ethact"));
/* Expected to be "eth@10002000" because it is first */
env_set("ethact", NULL);
env_set("ethprime", NULL);
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
return 0;
@@ -249,6 +250,7 @@ DM_TEST(dm_test_eth_prime, UTF_SCAN_FDT);
*/
static int dm_test_eth_act(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
struct udevice *dev[DM_TEST_ETH_NUM];
const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
"sbe5", "eth@10004000"};
@@ -258,7 +260,6 @@ static int dm_test_eth_act(struct unit_test_state *uts)
int i;
memset(ethaddr, '\0', sizeof(ethaddr));
- net_ping_ip = string_to_ip("1.1.2.2");
/* Prepare the test scenario */
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
@@ -281,7 +282,7 @@ static int dm_test_eth_act(struct unit_test_state *uts)
env_set("ethact", ethname[0]);
/* Segment fault might happen if something is wrong */
- ut_asserteq(-ENODEV, net_loop(PING));
+ ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
/* Restore the env */
@@ -334,15 +335,17 @@ DM_TEST(dm_test_ethaddr, UTF_SCAN_FDT);
/* The asserts include a return on fail; cleanup in the caller */
static int _dm_test_eth_rotate1(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
+
/* Make sure that the default is to rotate to the next interface */
env_set("ethact", "eth@10004000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
/* If ethrotate is no, then we should fail on a bad MAC */
env_set("ethact", "eth@10004000");
env_set("ethrotate", "no");
- ut_asserteq(-EINVAL, net_loop(PING));
+ ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
return 0;
@@ -350,14 +353,16 @@ static int _dm_test_eth_rotate1(struct unit_test_state *uts)
static int _dm_test_eth_rotate2(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
+
/* Make sure we can skip invalid devices */
env_set("ethact", "eth@10004000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
/* Make sure we can handle device name which is not eth# */
env_set("ethact", "sbe5");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("sbe5", env_get("ethact"));
return 0;
@@ -368,9 +373,6 @@ static int dm_test_eth_rotate(struct unit_test_state *uts)
char ethaddr[18];
int retval;
- /* Set target IP to mock ping */
- net_ping_ip = string_to_ip("1.1.2.2");
-
/* Invalidate eth1's MAC address */
memset(ethaddr, '\0', sizeof(ethaddr));
strncpy(ethaddr, env_get("eth6addr"), 17);
@@ -396,6 +398,7 @@ static int dm_test_eth_rotate(struct unit_test_state *uts)
/* Restore the env */
env_set("ethaddr", ethaddr);
}
+
/* Restore the env */
env_set(".flags", NULL);
@@ -406,26 +409,28 @@ DM_TEST(dm_test_eth_rotate, UTF_SCAN_FDT);
/* The asserts include a return on fail; cleanup in the caller */
static int _dm_test_net_retry(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
+
/*
- * eth1 is disabled and netretry is yes, so the ping should succeed and
- * the active device should be eth0
+ * eth0 is disabled and netretry is yes, so the ping should succeed and
+ * the active device should be eth1
*/
- sandbox_eth_disable_response(1, true);
- env_set("ethact", "lan1");
+ sandbox_eth_disable_response(0, true);
+ env_set("ethact", "eth@10002000");
env_set("netretry", "yes");
sandbox_eth_skip_timeout();
- ut_assertok(net_loop(PING));
- ut_asserteq_str("eth@10002000", env_get("ethact"));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
+ ut_asserteq_str("eth@10003000", env_get("ethact"));
/*
- * eth1 is disabled and netretry is no, so the ping should fail and the
- * active device should be eth1
+ * eth0 is disabled and netretry is no, so the ping should fail and the
+ * active device should be eth0
*/
- env_set("ethact", "lan1");
+ env_set("ethact", "eth@10002000");
env_set("netretry", "no");
sandbox_eth_skip_timeout();
- ut_asserteq(-ENONET, net_loop(PING));
- ut_asserteq_str("lan1", env_get("ethact"));
+ ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
+ ut_asserteq_str("eth@10002000", env_get("ethact"));
return 0;
}
@@ -434,8 +439,6 @@ static int dm_test_net_retry(struct unit_test_state *uts)
{
int retval;
- net_ping_ip = string_to_ip("1.1.2.2");
-
retval = _dm_test_net_retry(uts);
/* Restore the env */
@@ -446,6 +449,7 @@ static int dm_test_net_retry(struct unit_test_state *uts)
}
DM_TEST(dm_test_net_retry, UTF_SCAN_FDT);
+#if CONFIG_IS_ENABLED(NET)
static int sb_check_arp_reply(struct udevice *dev, void *packet,
unsigned int len)
{
@@ -511,7 +515,9 @@ static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
return sb_check_arp_reply(dev, packet, len);
}
+#endif
+#if CONFIG_IS_ENABLED(NET)
static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
{
net_ping_ip = string_to_ip("1.1.2.2");
@@ -529,7 +535,9 @@ static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_eth_async_arp_reply, UTF_SCAN_FDT);
+#endif
+#if CONFIG_IS_ENABLED(NET)
static int sb_check_ping_reply(struct udevice *dev, void *packet,
unsigned int len)
{
@@ -613,6 +621,7 @@ static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_eth_async_ping_reply, UTF_SCAN_FDT);
+#endif
#if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY)
diff --git a/test/dm/power-domain.c b/test/dm/power-domain.c
index 896cf5b2ae9..1002d831764 100644
--- a/test/dm/power-domain.c
+++ b/test/dm/power-domain.c
@@ -27,7 +27,7 @@ static int dm_test_power_domain(struct unit_test_state *uts)
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test",
&dev_test));
- ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_get(dev_test));
@@ -35,11 +35,20 @@ static int dm_test_power_domain(struct unit_test_state *uts)
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
TEST_POWER_DOMAIN));
+ ut_asserteq(-EALREADY, sandbox_power_domain_test_on_ll(dev_test));
+ ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
+ ut_asserteq(-EBUSY, sandbox_power_domain_test_off_ll(dev_test));
+ ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_off(dev_test));
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
TEST_POWER_DOMAIN));
+ ut_asserteq(-EALREADY, sandbox_power_domain_test_off_ll(dev_test));
+ ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_free(dev_test));
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index af8cd617108..295fdcaa0d8 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -792,7 +792,7 @@ DM_TEST(dm_test_fdt_disable_enable_by_path, UTF_SCAN_PDATA | UTF_SCAN_FDT);
/* Test a few uclass phandle functions */
static int dm_test_fdt_phandle(struct unit_test_state *uts)
{
- struct udevice *back, *dev, *dev2;
+ struct udevice *back, *dispc, *panel, *dev, *dev2;
ut_assertok(uclass_find_first_device(UCLASS_PANEL_BACKLIGHT, &back));
ut_assertnonnull(back);
@@ -807,6 +807,24 @@ static int dm_test_fdt_phandle(struct unit_test_state *uts)
"power-supply", &dev2));
ut_asserteq_ptr(dev, dev2);
+ /* Test uclass_get_device_by_endpoint() */
+ ut_assertok(uclass_find_device_by_name(UCLASS_VIDEO_BRIDGE, "lvds-encoder", &dispc));
+ ut_assertnonnull(dispc);
+ ut_asserteq(0, device_active(dispc));
+ ut_assertok(uclass_find_device_by_name(UCLASS_PANEL, "panel", &panel));
+ ut_assertnonnull(panel);
+ ut_asserteq(0, device_active(panel));
+
+ ut_asserteq(-ENODEV, uclass_get_device_by_endpoint(UCLASS_PANEL_BACKLIGHT, dispc, 1, -1, &dev));
+ ut_asserteq(-EINVAL, uclass_get_device_by_endpoint(UCLASS_PANEL, dispc, 0, -1, &dev));
+ ut_assertok(uclass_get_device_by_endpoint(UCLASS_PANEL, dispc, 1, -1, &dev));
+ ut_asserteq_ptr(panel, dev);
+
+ ut_asserteq(-ENODEV, uclass_get_device_by_endpoint(UCLASS_PANEL_BACKLIGHT, panel, -1, -1, &dev2));
+ ut_asserteq(-EINVAL, uclass_get_device_by_endpoint(UCLASS_VIDEO_BRIDGE, panel, 1, -1, &dev2));
+ ut_assertok(uclass_get_device_by_endpoint(UCLASS_VIDEO_BRIDGE, panel, -1, -1, &dev2));
+ ut_asserteq_ptr(dispc, dev2);
+
return 0;
}
DM_TEST(dm_test_fdt_phandle, UTF_SCAN_PDATA | UTF_SCAN_FDT);
diff --git a/test/fuzz/Makefile b/test/fuzz/Makefile
index 8a135b65e4b..0a8f3d12239 100644
--- a/test/fuzz/Makefile
+++ b/test/fuzz/Makefile
@@ -4,5 +4,5 @@
# Written by Andrew Scull <ascull@google.com>
#
-obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_fuzz.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += cmd_fuzz.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
diff --git a/test/lib/Makefile b/test/lib/Makefile
index 0e4cb8e3dfd..d620510f998 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -3,7 +3,7 @@
# (C) Copyright 2018
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
-obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o
+obj-$(CONFIG_$(PHASE_)UT_COMPRESSION) += compression.o
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += abuf.o
@@ -14,6 +14,8 @@ obj-y += hexdump.o
obj-$(CONFIG_SANDBOX) += kconfig.o
obj-y += lmb.o
obj-$(CONFIG_HAVE_SETJMP) += longjmp.o
+obj-$(CONFIG_SANDBOX) += membuf.o
+obj-$(CONFIG_HAVE_INITJMP) += initjmp.o
obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
obj-$(CONFIG_SSCANF) += sscanf.o
obj-$(CONFIG_$(PHASE_)STRTO) += str.o
@@ -29,7 +31,8 @@ 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_$(PHASE_)UT_UNICODE) += unicode.o
+obj-$(CONFIG_UTHREAD) += uthread.o
obj-$(CONFIG_LIB_UUID) += uuid.o
else
obj-$(CONFIG_SANDBOX) += kconfig_spl.o
diff --git a/test/lib/initjmp.c b/test/lib/initjmp.c
new file mode 100644
index 00000000000..5b4b50b3f0f
--- /dev/null
+++ b/test/lib/initjmp.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2025 Linaro Limited
+ *
+ * Unit test for initjmp()
+ */
+
+#include <compiler.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <test/lib.h>
+#include <test/ut.h>
+#include <vsprintf.h>
+
+static bool ep_entered;
+static jmp_buf return_buf;
+
+static void __noreturn entrypoint(void)
+{
+ ep_entered = true;
+
+ /* Jump back to the main routine */
+ longjmp(return_buf, 1);
+
+ /* Not reached */
+ panic("longjmp failed\n");
+}
+
+static int lib_initjmp(struct unit_test_state *uts)
+{
+ int ret;
+ void *stack;
+ jmp_buf buf;
+ /* Arbitrary but smaller values (< page size?) fail on SANDBOX */
+ size_t stack_sz = 8192;
+
+ (void)entrypoint;
+
+ ep_entered = false;
+
+ stack = malloc(stack_sz);
+ ut_assertnonnull(stack);
+
+ /*
+ * Prepare return_buf so that entrypoint may jump back just after the
+ * if()
+ */
+ if (!setjmp(return_buf)) {
+ /* return_buf initialized, entrypoint not yet called */
+
+ /*
+ * Prepare another jump buffer to jump into entrypoint with the
+ * given stack
+ */
+ ret = initjmp(buf, entrypoint, stack, stack_sz);
+ ut_assertok(ret);
+
+ /* Jump into entrypoint */
+ longjmp(buf, 1);
+ /*
+ * Not reached since entrypoint is expected to branch after
+ * the if()
+ */
+ ut_assert(false);
+ }
+
+ ut_assert(ep_entered);
+
+ free(stack);
+
+ return 0;
+}
+LIB_TEST(lib_initjmp, 0);
diff --git a/test/lib/membuf.c b/test/lib/membuf.c
new file mode 100644
index 00000000000..3f268a422d5
--- /dev/null
+++ b/test/lib/membuf.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <membuf.h>
+#include <os.h>
+#include <rand.h>
+#include <string.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#define TEST_SIZE 16
+#define TEST_COUNT 10000
+
+static void membuf_zero(struct membuf *mb)
+{
+ memset(mb->start, '\0', mb->end - mb->start);
+}
+
+static int membuf_check(struct unit_test_state *uts, struct membuf *mb,
+ int value)
+{
+ /* head is out of range */
+ ut_assert(!(mb->head < mb->start || mb->head >= mb->end));
+
+ /* tail is out of range */
+ ut_assert(!(mb->tail < mb->start || mb->tail >= mb->end));
+
+ return 0;
+}
+
+/* write from 1 to test_size bytes, and check they come back OK */
+static int lib_test_membuf_one(struct unit_test_state *uts)
+{
+ char in[TEST_SIZE * 2], out[TEST_SIZE * 2];
+ struct membuf mb;
+ int size, ret, test_size, i;
+
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ /* setup in test */
+ for (i = 0; i < TEST_SIZE; i++) {
+ in[i] = (i & 63) + '0';
+ in[i + TEST_SIZE] = in[i];
+ }
+
+ test_size = TEST_SIZE;
+
+ for (i = 1; i < TEST_COUNT; i++) {
+ membuf_zero(&mb);
+ size = rand() % test_size;
+
+ // now write patterns and check they come back OK
+ ret = membuf_put(&mb, in, 0);
+ ret = membuf_put(&mb, in, size);
+ ut_asserteq(size, ret);
+
+ ret = membuf_put(&mb, in, 0);
+ ut_assertok(membuf_check(uts, &mb, i));
+
+ ret = membuf_get(&mb, out, 0);
+ ret = membuf_get(&mb, out, size);
+ ut_asserteq(size, ret);
+
+ ret = membuf_get(&mb, out, 0);
+ ut_assertok(membuf_check(uts, &mb, i));
+
+ ut_asserteq_mem(in, out, size);
+ }
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_one, 0);
+
+/* write random number of bytes, and check they come back OK */
+static int lib_test_membuf_random(struct unit_test_state *uts)
+{
+ char in[TEST_SIZE * 2];
+ char buf[TEST_SIZE * 2];
+ struct membuf mb;
+ int size, ret, test_size, i;
+ char *inptr, *outptr;
+ int max_avail, min_free;
+
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ for (i = 0; i < TEST_SIZE; i++) {
+ in[i] = (i & 63) + '0';
+ in[i + TEST_SIZE] = in[i];
+ }
+
+ test_size = TEST_SIZE;
+
+ inptr = in;
+ outptr = in;
+ min_free = TEST_COUNT;
+ max_avail = 0;
+ membuf_zero(&mb);
+ for (i = 0; i < TEST_COUNT; i++) {
+ size = rand() % test_size;
+
+ if (membuf_free(&mb) < min_free)
+ min_free = membuf_free(&mb);
+
+ ret = membuf_put(&mb, inptr, size);
+ ut_assertok(membuf_check(uts, &mb, i));
+ inptr += ret;
+ if (inptr >= in + TEST_SIZE)
+ inptr -= TEST_SIZE;
+
+ size = rand() % (test_size - 1);
+
+ if (membuf_avail(&mb) > max_avail)
+ max_avail = membuf_avail(&mb);
+
+ ret = membuf_get(&mb, buf, size);
+ ut_assertok(membuf_check(uts, &mb, i));
+ ut_asserteq_mem(buf, outptr, ret);
+
+ outptr += ret;
+ if (outptr >= in + TEST_SIZE)
+ outptr -= TEST_SIZE;
+ }
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_random, 0);
+
+/* test membuf_extend() with split segments */
+static int lib_test_membuf_extend(struct unit_test_state *uts)
+{
+ char in[TEST_SIZE * 2];
+ char buf[TEST_SIZE * 2];
+ struct membuf mb;
+ int ret, test_size, i, cur;
+ char *data;
+
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ for (i = 0; i < TEST_SIZE; i++) {
+ in[i] = (i & 63) + '0';
+ in[i + TEST_SIZE] = in[i];
+ }
+
+ test_size = TEST_SIZE - 1;
+
+ for (cur = 0; cur <= test_size; cur++) {
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ membuf_zero(&mb);
+
+ /*
+ * add some bytes, then remove them - this will force the membuf
+ * to have data split into two segments when we fill it
+ */
+ ret = membuf_putraw(&mb, TEST_SIZE / 2, true, &data);
+ membuf_getraw(&mb, ret, true, &data);
+ ut_asserteq(TEST_SIZE / 2, ret);
+
+ /* fill it */
+ ret = membuf_put(&mb, in, cur);
+ ut_assertok(membuf_check(uts, &mb, cur));
+ ut_asserteq(cur, ret);
+
+ /* extend the buffer */
+ ut_assertok(membuf_extend_by(&mb, TEST_SIZE, -1));
+ ut_assertok(membuf_check(uts, &mb, cur));
+
+ /* check our data is still there */
+ ret = membuf_get(&mb, buf, TEST_SIZE * 2);
+ ut_assertok(membuf_check(uts, &mb, cur));
+ ut_asserteq(cur, ret);
+ ut_asserteq_mem(in, buf, cur);
+ membuf_uninit(&mb);
+ }
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_extend, 0);
+
+/* test membuf_readline() with generated data */
+static int lib_test_membuf_readline(struct unit_test_state *uts)
+{
+ char *buf;
+ int size, cur, i, ret, readptr, cmpptr;
+ struct membuf mb;
+ char *data;
+ char str[256];
+ char *s;
+
+ ut_assertok(membuf_new(&mb, 1024));
+ membuf_zero(&mb);
+
+ /* Use the README as test data */
+ ut_assertok(os_read_file("README", (void **)&buf, &size));
+
+ cur = 0;
+ readptr = 0;
+ cmpptr = 0;
+ for (i = 0; i < 100000; i++, cur += 1) {
+ /* fill the buffer with up to 'cur' bytes */
+ ret = membuf_putraw(&mb, cur, false, &data);
+
+ if (ret > 0) {
+ int can_read = min(ret, size - readptr);
+
+ memcpy(data, &buf[readptr], can_read);
+ readptr += can_read;
+
+ membuf_putraw(&mb, can_read, true, &data);
+ ut_assertok(membuf_check(uts, &mb, i));
+ }
+
+ /* read a line and compare */
+ ret = membuf_readline(&mb, str, 256, 0, true);
+ ut_assertok(membuf_check(uts, &mb, i));
+ if (ret) {
+ char *ptr;
+
+ s = &buf[cmpptr];
+ ptr = strchr(s, '\n');
+ *ptr = '\0';
+
+ ut_asserteq_str(s, str);
+ cmpptr += strlen(s) + 1;
+ *ptr = '\n';
+ } else {
+ ut_assert(membuf_free(&mb));
+ }
+ }
+ membuf_dispose(&mb);
+ os_free(buf);
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_readline, 0);
diff --git a/test/lib/uthread.c b/test/lib/uthread.c
new file mode 100644
index 00000000000..10a94d1c560
--- /dev/null
+++ b/test/lib/uthread.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Linaro Limited
+ *
+ * Unit test for uthread
+ */
+
+#include <stdbool.h>
+#include <test/lib.h>
+#include <test/ut.h>
+#include <uthread.h>
+
+static int count;
+
+/* A thread entry point */
+static void worker(void *arg)
+{
+ int loops = (int)(unsigned long)arg;
+ int i;
+
+ for (i = 0; i < loops; i++) {
+ count++;
+ uthread_schedule();
+ }
+}
+
+/*
+ * uthread() - testing the uthread API
+ *
+ * This function creates two threads with the same entry point. The first one
+ * receives 5 as an argument, the second one receives 10. The number indicates
+ * the number of time the worker thread should loop on uthread_schedule()
+ * before returning. The workers increment a global counter each time they loop.
+ * As a result the main thread knows how many times it should call
+ * uthread_schedule() to let the two threads proceed, and it also knows which
+ * value the counter should have at any moment.
+ */
+static int uthread(struct unit_test_state *uts)
+{
+ int i;
+ int id1, id2;
+
+ count = 0;
+ id1 = uthread_grp_new_id();
+ ut_assert(id1 != 0);
+ id2 = uthread_grp_new_id();
+ ut_assert(id2 != 0);
+ ut_assert(id1 != id2);
+ ut_assertok(uthread_create(NULL, worker, (void *)5, 0, id1));
+ ut_assertok(uthread_create(NULL, worker, (void *)10, 0, 0));
+ /*
+ * The first call is expected to schedule the first worker, which will
+ * schedule the second one, which will schedule back to the main thread
+ * (here). Therefore count should be 2.
+ */
+ ut_assert(uthread_schedule());
+ ut_asserteq(2, count);
+ ut_assert(!uthread_grp_done(id1));
+ /* Four more calls should bring the count to 10 */
+ for (i = 0; i < 4; i++) {
+ ut_assert(!uthread_grp_done(id1));
+ ut_assert(uthread_schedule());
+ }
+ ut_asserteq(10, count);
+ /* This one allows the first worker to exit */
+ ut_assert(uthread_schedule());
+ /* At this point there should be no runnable thread in group 'id1' */
+ ut_assert(uthread_grp_done(id1));
+ /* Five more calls for the second worker to finish incrementing */
+ for (i = 0; i < 5; i++)
+ ut_assert(uthread_schedule());
+ ut_asserteq(15, count);
+ /* Plus one call to let the second worker return from its entry point */
+ ut_assert(uthread_schedule());
+ /* Now both tasks should be done, schedule should return false */
+ ut_assert(!uthread_schedule());
+
+ return 0;
+}
+LIB_TEST(uthread, 0);
+
+struct mw_args {
+ struct unit_test_state *uts;
+ struct uthread_mutex *m;
+ int flag;
+};
+
+static int mutex_worker_ret;
+
+static int _mutex_worker(struct mw_args *args)
+{
+ struct unit_test_state *uts = args->uts;
+
+ ut_asserteq(-EBUSY, uthread_mutex_trylock(args->m));
+ ut_assertok(uthread_mutex_lock(args->m));
+ args->flag = 1;
+ ut_assertok(uthread_mutex_unlock(args->m));
+
+ return 0;
+}
+
+static void mutex_worker(void *arg)
+{
+ mutex_worker_ret = _mutex_worker((struct mw_args *)arg);
+}
+
+/*
+ * thread_mutex() - testing uthread mutex operations
+ *
+ */
+static int uthread_mutex(struct unit_test_state *uts)
+{
+ struct uthread_mutex m = UTHREAD_MUTEX_INITIALIZER;
+ struct mw_args args = { .uts = uts, .m = &m, .flag = 0 };
+ int id;
+ int i;
+
+ id = uthread_grp_new_id();
+ ut_assert(id != 0);
+ /* Take the mutex */
+ ut_assertok(uthread_mutex_lock(&m));
+ /* Start a thread */
+ ut_assertok(uthread_create(NULL, mutex_worker, (void *)&args, 0,
+ id));
+ /* Let the thread run for a bit */
+ for (i = 0; i < 100; i++)
+ ut_assert(uthread_schedule());
+ /* Thread should not have set the flag due to the mutex */
+ ut_asserteq(0, args.flag);
+ /* Release the mutex */
+ ut_assertok(uthread_mutex_unlock(&m));
+ /* Schedule the thread until it is done */
+ while (uthread_schedule())
+ ;
+ /* Now the flag should be set */
+ ut_asserteq(1, args.flag);
+ /* And the mutex should be available */
+ ut_assertok(uthread_mutex_trylock(&m));
+ ut_assertok(uthread_mutex_unlock(&m));
+
+ /* Of course no error are expected from the thread routine */
+ ut_assertok(mutex_worker_ret);
+
+ return 0;
+}
+LIB_TEST(uthread_mutex, 0);
diff --git a/test/py/conftest.py b/test/py/conftest.py
index e59897c1f78..5aea85647af 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -334,6 +334,7 @@ def pytest_configure(config):
ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb'
ubconfig.connection_ok = True
ubconfig.timing = config.getoption('timing')
+ ubconfig.role = config.getoption('role')
env_vars = (
'board_type',
@@ -760,6 +761,26 @@ def setup_singlethread(item):
if worker_id and worker_id != 'master':
pytest.skip('must run single-threaded')
+def setup_role(item):
+ """Process any 'role' marker for a test.
+
+ Skip this test if the role does not match.
+
+ Args:
+ item (pytest.Item): The pytest test item
+ """
+ required_roles = []
+ for roles in item.iter_markers('role'):
+ role = roles.args[0]
+ if role.startswith('!'):
+ if ubconfig.role == role[1:]:
+ pytest.skip(f'role "{ubconfig.role}" not supported')
+ return
+ else:
+ required_roles.append(role)
+ if required_roles and ubconfig.role not in required_roles:
+ pytest.skip(f'board "{ubconfig.role}" not supported')
+
def start_test_section(item):
anchors[item.name] = log.start_section(item.name)
@@ -781,6 +802,7 @@ def pytest_runtest_setup(item):
setup_buildconfigspec(item)
setup_requiredtool(item)
setup_singlethread(item)
+ setup_role(item)
def pytest_runtest_protocol(item, nextitem):
"""pytest hook: Called to execute a test.
diff --git a/test/py/console_base.py b/test/py/console_base.py
index 260df773bac..88d444b44b8 100644
--- a/test/py/console_base.py
+++ b/test/py/console_base.py
@@ -370,21 +370,30 @@ class ConsoleBase(object):
output.append(self.run_command(cmd))
return output
- def ctrlc(self):
- """Send a CTRL-C character to U-Boot.
+ def send(self, msg):
+ """Send characters without waiting for echo, etc."""
+ self.run_command(msg, wait_for_prompt=False, wait_for_echo=False,
+ send_nl=False)
+
+ def ctrl(self, char):
+ """Send a CTRL- character to U-Boot.
This is useful in order to stop execution of long-running synchronous
commands such as "ums".
Args:
- None.
-
- Returns:
- Nothing.
+ char (str): Character to send, e.g. 'C' to send Ctrl-C
"""
+ self.log.action(f'Sending Ctrl-{char}')
+ self.send(chr(ord(char) - ord('@')))
- self.log.action('Sending Ctrl-C')
- self.run_command(chr(3), wait_for_echo=False, send_nl=False)
+ def ctrlc(self):
+ """Send a CTRL-C character to U-Boot.
+
+ This is useful in order to stop execution of long-running synchronous
+ commands such as "ums".
+ """
+ self.ctrl('C')
def wait_for(self, text):
"""Wait for a pattern to be emitted by U-Boot.
diff --git a/test/py/pytest.ini b/test/py/pytest.ini
index 26d83f83e00..361be0178ee 100644
--- a/test/py/pytest.ini
+++ b/test/py/pytest.ini
@@ -12,3 +12,4 @@ markers =
requiredtool: U-Boot: Required host tools for a test.
slow: U-Boot: Specific test will run slowly.
singlethread: Cannot run in parallel
+ role: U-Boot: Indicates the lab 'role' which can execute this test
diff --git a/test/py/requirements.txt b/test/py/requirements.txt
index acfe17dce9f..804a427b351 100644
--- a/test/py/requirements.txt
+++ b/test/py/requirements.txt
@@ -2,3 +2,4 @@ filelock==3.0.12
pycryptodomex==3.21.0
pytest==6.2.5
pytest-xdist==2.5.0
+FATtools==1.0.42
diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py
index d85e2b98a24..b8a22b22806 100644
--- a/test/py/tests/fs_helper.py
+++ b/test/py/tests/fs_helper.py
@@ -35,7 +35,9 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
else:
mkfs_opt = ''
- if re.match('fat', fs_type):
+ if fs_type == 'exfat':
+ fs_lnxtype = 'exfat'
+ elif re.match('fat', fs_type) or fs_type == 'fs_generic':
fs_lnxtype = 'vfat'
else:
fs_lnxtype = fs_type
@@ -43,7 +45,7 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
if src_dir:
if fs_lnxtype == 'ext4':
mkfs_opt = mkfs_opt + ' -d ' + src_dir
- elif fs_lnxtype != 'vfat':
+ elif fs_lnxtype != 'vfat' and fs_lnxtype != 'exfat':
raise ValueError(f'src_dir not implemented for fs {fs_lnxtype}')
count = (size + size_gran - 1) // size_gran
@@ -64,11 +66,47 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
check_call(f'tune2fs -O ^metadata_csum {fs_img}', shell=True)
elif fs_lnxtype == 'vfat' and src_dir:
check_call(f'mcopy -i {fs_img} -vsmpQ {src_dir}/* ::/', shell=True)
+ elif fs_lnxtype == 'exfat' and src_dir:
+ check_call(f'fattools cp {src_dir}/* {fs_img}', shell=True)
return fs_img
except CalledProcessError:
call(f'rm -f {fs_img}', shell=True)
raise
+def setup_image(ubman, devnum, part_type, img_size=20, second_part=False,
+ basename='mmc'):
+ """Create a disk image with a single partition
+
+ Args:
+ ubman (ConsoleBase): Console to use
+ devnum (int): Device number to use, e.g. 1
+ part_type (int): Partition type, e.g. 0xc for FAT32
+ img_size (int): Image size in MiB
+ 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 scratch directory
+ """
+ fname = os.path.join(ubman.config.source_dir, f'{basename}{devnum}.img')
+ mnt = os.path.join(ubman.config.persistent_data_dir, 'scratch')
+
+ spec = f'type={part_type:x}, size={img_size - 2}M, start=1M, bootable'
+ if second_part:
+ spec += '\ntype=c'
+
+ try:
+ check_call(f'mkdir -p {mnt}', shell=True)
+ check_call(f'qemu-img create {fname} {img_size}M', shell=True)
+ check_call(f'printf "{spec}" | sfdisk {fname}', shell=True)
+ except CalledProcessError:
+ call(f'rm -f {fname}', shell=True)
+ raise
+
+ return fname, mnt
+
# Just for trying out
if __name__ == "__main__":
import collections
diff --git a/test/py/tests/test_cat.py b/test/py/tests/test_cat.py
new file mode 100644
index 00000000000..252c3d50a02
--- /dev/null
+++ b/test/py/tests/test_cat.py
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+""" Unit test for cat command
+"""
+
+import pytest
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_cat')
+def test_cat(ubman):
+ """ Unit test for cat
+
+ Args:
+ ubman -- U-Boot console
+ """
+ try:
+ scratch_dir = ubman.config.persistent_data_dir + '/scratch'
+
+ check_call('mkdir -p %s' % scratch_dir, shell=True)
+
+ with open(scratch_dir + '/hello', 'w', encoding = 'ascii') as file:
+ file.write('hello world\n')
+
+ cat_data = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_cat', scratch_dir)
+ response = ubman.run_command_list([ f'host bind 0 {cat_data}',
+ 'cat host 0 hello'])
+ assert 'hello world' in response
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_cat image failed')
+ call('rm -f %s' % cat_data, shell=True)
+ return
+ finally:
+ call('rm -rf %s' % scratch_dir, shell=True)
+ call('rm -f %s' % cat_data, shell=True)
diff --git a/test/py/tests/test_cat/conftest.py b/test/py/tests/test_cat/conftest.py
deleted file mode 100644
index 320e7ebd295..00000000000
--- a/test/py/tests/test_cat/conftest.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for cat command test
-"""
-
-import os
-import shutil
-from subprocess import check_call, CalledProcessError
-import pytest
-
-@pytest.fixture(scope='session')
-def cat_data(u_boot_config):
- """Set up a file system to be used in cat tests
-
- Args:
- u_boot_config -- U-Boot configuration.
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_cat'
- image_path = u_boot_config.persistent_data_dir + '/cat.img'
-
- try:
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/hello', 'w', encoding = 'ascii') as file:
- file.write('hello world\n')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- yield image_path
- except CalledProcessError:
- pytest.skip('Setup failed')
- finally:
- shutil.rmtree(mnt_point)
- if os.path.exists(image_path):
- os.remove(image_path)
diff --git a/test/py/tests/test_cat/test_cat.py b/test/py/tests/test_cat/test_cat.py
deleted file mode 100644
index 883803fece7..00000000000
--- a/test/py/tests/test_cat/test_cat.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-""" Unit test for cat command
-"""
-
-import pytest
-
-@pytest.mark.boardspec('sandbox')
-@pytest.mark.buildconfigspec('cmd_cat')
-def test_cat(ubman, cat_data):
- """ Unit test for cat
-
- Args:
- ubman -- U-Boot console
- cat_data -- Path to the disk image used for testing.
- """
- response = ubman.run_command_list([
- f'host bind 0 {cat_data}',
- 'cat host 0 hello'])
- assert 'hello world' in response
diff --git a/test/py/tests/test_distro.py b/test/py/tests/test_distro.py
new file mode 100644
index 00000000000..bdf4ab657d1
--- /dev/null
+++ b/test/py/tests/test_distro.py
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2025 Canonical Ltd.
+# Written by Simon Glass <simon.glass@canonical.com>
+
+import pytest
+
+# Enable early console so that the test can see if something goes wrong
+CONSOLE = 'earlycon=uart8250,io,0x3f8 console=uart8250,io,0x3f8'
+
+@pytest.mark.boardspec('qemu-x86_64')
+@pytest.mark.role('qemu-x86_64')
+def test_distro(ubman):
+ """Test that of-platdata can be generated and used in sandbox"""
+ with ubman.log.section('boot'):
+ ubman.run_command('boot', wait_for_prompt=False)
+
+ with ubman.log.section('Grub'):
+ # Wait for grub to come up and offset a menu
+ ubman.p.expect(['Try or Install Ubuntu'])
+
+ # Press 'e' to edit the command line
+ ubman.log.info("Pressing 'e'")
+ ubman.run_command('e', wait_for_prompt=False, send_nl=False)
+
+ # Wait until we see the editor appear
+ ubman.p.expect(['/casper/initrd'])
+
+ # Go down to the 'linux' line. Avoid using down-arrow as that includes
+ # an Escape character, which may be parsed by Grub as such, causing it
+ # to return to the top menu
+ ubman.log.info("Going DOWN")
+ ubman.ctrl('N')
+ ubman.ctrl('N')
+ ubman.ctrl('N')
+
+ # Go to end of line
+ ubman.log.info("Going to EOL")
+ ubman.ctrl('E')
+
+ # Backspace to remove 'quiet splash'
+ ubman.log.info("Erasing quiet and splash")
+ ubman.send('\b' * len('quiet splash'))
+
+ # Send our noisy console
+ ubman.log.info("Noisy console")
+ ubman.send(CONSOLE)
+
+ # Tell grub to boot
+ ubman.log.info("boot")
+ ubman.ctrl('X')
+ ubman.p.expect(['Booting a command list'])
+
+ with ubman.log.section('Linux'):
+ # Linux should start immediately
+ ubman.p.expect(['Linux version'])
+
+ with ubman.log.section('Ubuntu'):
+ # Shortly later, we should see this banner
+ ubman.p.expect(['Welcome to .*Ubuntu 24.04.1 LTS.*!'])
+
+ ubman.restart_uboot()
diff --git a/test/py/tests/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr.py
new file mode 100644
index 00000000000..4c10cbdf17d
--- /dev/null
+++ b/test/py/tests/test_efi_bootmgr.py
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0+
+""" Unit test for UEFI bootmanager
+"""
+
+import shutil
+import pytest
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_efidebug')
+@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
+@pytest.mark.singlethread
+def test_efi_bootmgr(ubman):
+ """ Unit test for UEFI bootmanager
+ The efidebug command is used to set up UEFI load options.
+ The bootefi bootmgr loads initrddump.efi as a payload.
+ The crc32 of the loaded initrd.img is checked
+
+ Args:
+ ubman -- U-Boot console
+ """
+ try:
+ efi_bootmgr_data, mnt = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_bootmgr')
+
+ with open(mnt + '/initrd-1.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 1")
+
+ with open(mnt + '/initrd-2.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 2")
+
+ shutil.copyfile(ubman.config.build_dir + '/lib/efi_loader/initrddump.efi',
+ mnt + '/initrddump.efi')
+
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_efi_bootmgr', mnt)
+ check_call(f'dd if={fsfile} of={efi_bootmgr_data} bs=1M seek=1', shell=True)
+
+ ubman.run_command(cmd = f'host bind 0 {efi_bootmgr_data}')
+
+ ubman.run_command(cmd = 'efidebug boot add ' \
+ '-b 0001 label-1 host 0:1 initrddump.efi ' \
+ '-i host 0:1 initrd-1.img -s nocolor')
+ ubman.run_command(cmd = 'efidebug boot dump')
+ ubman.run_command(cmd = 'efidebug boot order 0001')
+ ubman.run_command(cmd = 'bootefi bootmgr')
+ response = ubman.run_command(cmd = 'load', wait_for_echo=False)
+ assert 'crc32: 0x181464af' in response
+ ubman.run_command(cmd = 'exit', wait_for_echo=False)
+
+ ubman.run_command(cmd = 'efidebug boot add ' \
+ '-B 0002 label-2 host 0:1 initrddump.efi ' \
+ '-I host 0:1 initrd-2.img -s nocolor')
+ ubman.run_command(cmd = 'efidebug boot dump')
+ ubman.run_command(cmd = 'efidebug boot order 0002')
+ ubman.run_command(cmd = 'bootefi bootmgr')
+ response = ubman.run_command(cmd = 'load', wait_for_echo=False)
+ assert 'crc32: 0x811d3515' in response
+ ubman.run_command(cmd = 'exit', wait_for_echo=False)
+
+ ubman.run_command(cmd = 'efidebug boot rm 0001')
+ ubman.run_command(cmd = 'efidebug boot rm 0002')
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_efi_bootmgr image failed')
+ call('rm -f %s' % efi_bootmgr_data, shell=True)
+ return
+ finally:
+ call('rm -rf %s' % mnt, shell=True)
+ call('rm -f %s' % efi_bootmgr_data, shell=True)
diff --git a/test/py/tests/test_efi_bootmgr/conftest.py b/test/py/tests/test_efi_bootmgr/conftest.py
deleted file mode 100644
index 0eca025058e..00000000000
--- a/test/py/tests/test_efi_bootmgr/conftest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for UEFI bootmanager test."""
-
-import os
-import shutil
-from subprocess import check_call
-import pytest
-
-@pytest.fixture(scope='session')
-def efi_bootmgr_data(u_boot_config):
- """Set up a file system to be used in UEFI bootmanager tests.
-
- Args:
- u_boot_config -- U-Boot configuration.
-
- Return:
- A path to disk image to be used for testing
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_bootmgr'
- image_path = u_boot_config.persistent_data_dir + '/efi_bootmgr.img'
-
- shutil.rmtree(mnt_point, ignore_errors=True)
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 1")
-
- with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 2")
-
- shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
- mnt_point + '/initrddump.efi')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- return image_path
diff --git a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py
deleted file mode 100644
index 8800e9de5b4..00000000000
--- a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-""" Unit test for UEFI bootmanager
-"""
-
-import pytest
-
-@pytest.mark.boardspec('sandbox')
-@pytest.mark.buildconfigspec('cmd_efidebug')
-@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
-@pytest.mark.singlethread
-def test_efi_bootmgr(ubman, efi_bootmgr_data):
- """ Unit test for UEFI bootmanager
- The efidebug command is used to set up UEFI load options.
- The bootefi bootmgr loads initrddump.efi as a payload.
- The crc32 of the loaded initrd.img is checked
-
- Args:
- ubman -- U-Boot console
- efi_bootmgr_data -- Path to the disk image used for testing.
- """
- ubman.run_command(cmd = f'host bind 0 {efi_bootmgr_data}')
-
- ubman.run_command(cmd = 'efidebug boot add ' \
- '-b 0001 label-1 host 0:1 initrddump.efi ' \
- '-i host 0:1 initrd-1.img -s nocolor')
- ubman.run_command(cmd = 'efidebug boot dump')
- ubman.run_command(cmd = 'efidebug boot order 0001')
- ubman.run_command(cmd = 'bootefi bootmgr')
- response = ubman.run_command(cmd = 'load', wait_for_echo=False)
- assert 'crc32: 0x181464af' in response
- ubman.run_command(cmd = 'exit', wait_for_echo=False)
-
- ubman.run_command(cmd = 'efidebug boot add ' \
- '-B 0002 label-2 host 0:1 initrddump.efi ' \
- '-I host 0:1 initrd-2.img -s nocolor')
- ubman.run_command(cmd = 'efidebug boot dump')
- ubman.run_command(cmd = 'efidebug boot order 0002')
- ubman.run_command(cmd = 'bootefi bootmgr')
- response = ubman.run_command(cmd = 'load', wait_for_echo=False)
- assert 'crc32: 0x811d3515' in response
- ubman.run_command(cmd = 'exit', wait_for_echo=False)
-
- ubman.run_command(cmd = 'efidebug boot rm 0001')
- ubman.run_command(cmd = 'efidebug boot rm 0002')
diff --git a/test/py/tests/test_efi_capsule/capsule_common.py b/test/py/tests/test_efi_capsule/capsule_common.py
index 40b3fca809e..04dabc176c4 100644
--- a/test/py/tests/test_efi_capsule/capsule_common.py
+++ b/test/py/tests/test_efi_capsule/capsule_common.py
@@ -136,7 +136,7 @@ def do_reboot_dtb_specified(u_boot_config, ubman, dtb_filename):
ubman -- A console connection to U-Boot.
dtb_filename -- DTB file name.
"""
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
+ mnt_point = u_boot_config.persistent_data_dir + '/scratch'
ubman.config.dtb = mnt_point + CAPSULE_DATA_DIR \
+ f'/{dtb_filename}'
ubman.restart_uboot()
diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py
index 61eab5112a1..961d2e0b3c1 100644
--- a/test/py/tests/test_efi_capsule/conftest.py
+++ b/test/py/tests/test_efi_capsule/conftest.py
@@ -7,11 +7,12 @@
import os
from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
import pytest
from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR, EFITOOLS_PATH
-@pytest.fixture(scope='session')
-def efi_capsule_data(request, u_boot_config):
+@pytest.fixture(scope='function')
+def efi_capsule_data(request, ubman):
"""Set up a file system and return path to image.
The function sets up a file system to be used in UEFI capsule and
@@ -19,14 +20,14 @@ def efi_capsule_data(request, u_boot_config):
for testing.
request -- Pytest request object.
- u_boot_config -- U-Boot configuration.
+ ubman -- U-Boot configuration.
"""
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
- data_dir = mnt_point + CAPSULE_DATA_DIR
- install_dir = mnt_point + CAPSULE_INSTALL_DIR
- image_path = u_boot_config.persistent_data_dir + '/test_efi_capsule.img'
-
try:
+ image_path, mnt_point = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_capsule')
+ data_dir = mnt_point + CAPSULE_DATA_DIR
+ install_dir = mnt_point + CAPSULE_INSTALL_DIR
+
# Create a target device
check_call('dd if=/dev/zero of=./spi.bin bs=1MiB count=16', shell=True)
@@ -34,9 +35,9 @@ def efi_capsule_data(request, u_boot_config):
check_call('mkdir -p %s' % data_dir, shell=True)
check_call('mkdir -p %s' % install_dir, shell=True)
- capsule_auth_enabled = u_boot_config.buildconfig.get(
+ capsule_auth_enabled = ubman.config.buildconfig.get(
'config_efi_capsule_authenticate')
- key_dir = u_boot_config.source_dir + '/board/sandbox'
+ key_dir = ubman.config.source_dir + '/board/sandbox'
if capsule_auth_enabled:
# Get the keys from the board directory
check_call('cp %s/capsule_priv_key_good.key %s/SIGNER.key'
@@ -54,12 +55,12 @@ def efi_capsule_data(request, u_boot_config):
# Update dtb to add the version information
check_call('cd %s; '
'cp %s/test/py/tests/test_efi_capsule/version.dtso .'
- % (data_dir, u_boot_config.source_dir), shell=True)
+ % (data_dir, ubman.config.source_dir), shell=True)
if capsule_auth_enabled:
check_call('cd %s; '
'cp %s/arch/sandbox/dts/test.dtb test_sig.dtb'
- % (data_dir, u_boot_config.build_dir), shell=True)
+ % (data_dir, ubman.config.build_dir), shell=True)
check_call('cd %s; '
'dtc -@ -I dts -O dtb -o version.dtbo version.dtso; '
'fdtoverlay -i test_sig.dtb '
@@ -70,29 +71,33 @@ def efi_capsule_data(request, u_boot_config):
'dtc -@ -I dts -O dtb -o version.dtbo version.dtso; '
'fdtoverlay -i %s/arch/sandbox/dts/test.dtb '
'-o test_ver.dtb version.dtbo'
- % (data_dir, u_boot_config.build_dir), shell=True)
+ % (data_dir, ubman.config.build_dir), shell=True)
# two regions: one for u-boot.bin and the other for u-boot.env
check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir,
shell=True)
pythonpath = os.environ.get('PYTHONPATH', '')
- os.environ['PYTHONPATH'] = pythonpath + ':' + '%s/scripts/dtc/pylibfdt' % u_boot_config.build_dir
+ os.environ['PYTHONPATH'] = pythonpath + ':' + '%s/scripts/dtc/pylibfdt' % ubman.config.build_dir
check_call('cd %s; '
'cc -E -I %s/include -x assembler-with-cpp -o capsule_gen_tmp.dts %s/test/py/tests/test_efi_capsule/capsule_gen_binman.dts; '
'dtc -I dts -O dtb capsule_gen_tmp.dts -o capsule_binman.dtb;'
- % (data_dir, u_boot_config.source_dir, u_boot_config.source_dir), shell=True)
+ % (data_dir, ubman.config.source_dir, ubman.config.source_dir), shell=True)
check_call('cd %s; '
'./tools/binman/binman --toolpath %s/tools build -u -d %s/capsule_binman.dtb -O %s -m --allow-missing -I %s -I ./board/sandbox -I ./arch/sandbox/dts'
- % (u_boot_config.source_dir, u_boot_config.build_dir, data_dir, data_dir, data_dir), shell=True)
- check_call('cp %s/Test* %s' % (u_boot_config.build_dir, data_dir), shell=True)
+ % (ubman.config.source_dir, ubman.config.build_dir, data_dir, data_dir, data_dir), shell=True)
+ check_call('cp %s/Test* %s' % (ubman.config.build_dir, data_dir), shell=True)
os.environ['PYTHONPATH'] = pythonpath
- # Create a disk image with EFI system partition
- check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' %
- (mnt_point, image_path), shell=True)
+ # Create a 16MiB partition as the EFI system partition in the disk
+ # image
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x1000000,
+ 'test_efi_capsule', mnt_point)
+ check_call(f'dd conv=notrunc if={fsfile} of={image_path} bs=1M seek=1', shell=True)
+ check_call('sgdisk --mbrtogpt %s' % image_path, shell=True)
check_call('sgdisk %s -A 1:set:0 -t 1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B' %
image_path, shell=True)
+ call('rm -f %s' % fsfile, shell=True)
except CalledProcessError as exception:
pytest.skip('Setup failed: %s' % exception.cmd)
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
index 0fa0747fc76..aa9a3536296 100644
--- a/test/py/tests/test_efi_secboot/conftest.py
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -5,27 +5,25 @@
"""Fixture for UEFI secure boot test."""
from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
import pytest
from defs import *
-@pytest.fixture(scope='session')
-def efi_boot_env(request, u_boot_config):
+@pytest.fixture(scope='function')
+def efi_boot_env(request, ubman):
"""Set up a file system to be used in UEFI secure boot test.
Args:
request: Pytest request object.
- u_boot_config: U-Boot configuration.
+ ubman: U-Boot configuration.
Return:
A path to disk image to be used for testing
"""
- image_path = u_boot_config.persistent_data_dir
- image_path = image_path + '/test_efi_secboot.img'
try:
- mnt_point = u_boot_config.build_dir + '/mnt_efisecure'
- check_call('rm -rf {}'.format(mnt_point), shell=True)
- check_call('mkdir -p {}'.format(mnt_point), shell=True)
+ image_path, mnt_point = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_secboot')
# suffix
# *.key: RSA private key in PEM
@@ -101,7 +99,7 @@ def efi_boot_env(request, u_boot_config):
# Copy image
check_call('cp %s/lib/efi_loader/helloworld.efi %s' %
- (u_boot_config.build_dir, mnt_point), shell=True)
+ (ubman.config.build_dir, mnt_point), shell=True)
# Sign image
check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi'
@@ -111,7 +109,7 @@ def efi_boot_env(request, u_boot_config):
% mnt_point, shell=True)
# Create a corrupted signed image
check_call('cd %s; sh %s/test/py/tests/test_efi_secboot/forge_image.sh helloworld.efi.signed helloworld_forged.efi.signed'
- % (mnt_point, u_boot_config.source_dir), shell=True)
+ % (mnt_point, ubman.config.source_dir), shell=True)
# Digest image
check_call('cd %s; %shash-to-efi-sig-list helloworld.efi db_hello.hash; %ssign-efi-sig-list -t "2020-04-07" -c KEK.crt -k KEK.key db db_hello.hash db_hello.auth'
% (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH),
@@ -123,9 +121,9 @@ def efi_boot_env(request, u_boot_config):
% (mnt_point, EFITOOLS_PATH),
shell=True)
- check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat {} {}'.format(
- mnt_point, image_path), shell=True)
- check_call('rm -rf {}'.format(mnt_point), shell=True)
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x1000000,
+ 'test_efi_secboot', mnt_point)
+ check_call(f'dd if={fsfile} of={image_path} bs=1M seek=1', shell=True)
except CalledProcessError as exception:
pytest.skip('Setup failed: %s' % exception.cmd)
@@ -133,15 +131,16 @@ def efi_boot_env(request, u_boot_config):
else:
yield image_path
finally:
- call('rm -f %s' % image_path, shell=True)
+ call('rm -rf %s' % mnt_point, shell=True)
+ call('rm -f %s %s' % (image_path, fsfile), shell=True)
#
# Fixture for UEFI secure boot test of intermediate certificates
#
-@pytest.fixture(scope='session')
-def efi_boot_env_intca(request, u_boot_config):
+@pytest.fixture(scope='function')
+def efi_boot_env_intca(request, ubman):
"""Set up file system for secure boot test.
Set up a file system to be used in UEFI secure boot test
@@ -149,18 +148,15 @@ def efi_boot_env_intca(request, u_boot_config):
Args:
request: Pytest request object.
- u_boot_config: U-Boot configuration.
+ ubman: U-Boot configuration.
Return:
A path to disk image to be used for testing
"""
- image_path = u_boot_config.persistent_data_dir
- image_path = image_path + '/test_efi_secboot_intca.img'
try:
- mnt_point = u_boot_config.persistent_data_dir + '/mnt_efi_secboot_intca'
- check_call('rm -rf {}'.format(mnt_point), shell=True)
- check_call('mkdir -p {}'.format(mnt_point), shell=True)
+ image_path, mnt_point = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_secboot_intca')
# Create signature database
# PK
@@ -190,7 +186,7 @@ def efi_boot_env_intca(request, u_boot_config):
# TestRoot
check_call('cp %s/test/py/tests/test_efi_secboot/openssl.cnf %s'
- % (u_boot_config.source_dir, mnt_point), shell=True)
+ % (ubman.config.source_dir, mnt_point), shell=True)
check_call('cd %s; export OPENSSL_CONF=./openssl.cnf; openssl genrsa -out TestRoot.key 2048; openssl req -extensions v3_ca -new -x509 -days 365 -key TestRoot.key -out TestRoot.crt -subj "/CN=TEST_root/"; touch index.txt; touch index.txt.attr'
% mnt_point, shell=True)
# TestSub
@@ -231,7 +227,7 @@ def efi_boot_env_intca(request, u_boot_config):
# in SignedData
check_call('cp %s/lib/efi_loader/helloworld.efi %s' %
- (u_boot_config.build_dir, mnt_point), shell=True)
+ (ubman.config.build_dir, mnt_point), shell=True)
# signed by TestCert
check_call('cd %s; %ssbsign --key TestCert.key --cert TestCert.crt --out helloworld.efi.signed_a helloworld.efi'
% (mnt_point, SBSIGN_PATH), shell=True)
@@ -242,8 +238,9 @@ def efi_boot_env_intca(request, u_boot_config):
check_call('cd %s; cat TestSub.crt TestRoot.crt > TestSubRoot.crt; %ssbsign --key TestCert.key --cert TestCert.crt --addcert TestSubRoot.crt --out helloworld.efi.signed_abc helloworld.efi'
% (mnt_point, SBSIGN_PATH), shell=True)
- check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat {} {}'.format(mnt_point, image_path), shell=True)
- check_call('rm -rf {}'.format(mnt_point), shell=True)
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x1000000,
+ 'test_efi_secboot_intca', mnt_point)
+ check_call(f'dd if={fsfile} of={image_path} bs=1M seek=1', shell=True)
except CalledProcessError as e:
pytest.skip('Setup failed: %s' % e.cmd)
@@ -251,4 +248,5 @@ def efi_boot_env_intca(request, u_boot_config):
else:
yield image_path
finally:
- call('rm -f %s' % image_path, shell=True)
+ call('rm -rf %s' % mnt_point, shell=True)
+ call('rm -f %s %s' % (image_path, fsfile), shell=True)
diff --git a/test/py/tests/test_eficonfig/test_eficonfig.py b/test/py/tests/test_eficonfig.py
index 3ca8e27c76b..ac1600ec252 100644
--- a/test/py/tests/test_eficonfig/test_eficonfig.py
+++ b/test/py/tests/test_eficonfig.py
@@ -3,12 +3,56 @@
"""
import pytest
+import shutil
+import pytest
import time
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_eficonfig')
@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
-def test_efi_eficonfig(ubman, efi_eficonfig_data):
+def test_efi_eficonfig(ubman):
+
+ def prepare_image(u_boot_config):
+ """Set up a file system to be used in UEFI "eficonfig" command
+ tests. This creates a disk image with the following files:
+ initrd-1.img
+ initrd-2.img
+ initrddump.efi
+
+ Args:
+ u_boot_config -- U-Boot configuration.
+
+ Return:
+ A path to disk image to be used for testing
+
+ """
+ try:
+ image_path, mnt_point = fs_helper.setup_image(u_boot_config, 0,
+ 0xc,
+ basename='test_eficonfig')
+
+ with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 1")
+
+ with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 2")
+
+ shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
+ mnt_point + '/initrddump.efi')
+
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_eficonfig', mnt_point)
+ check_call(f'dd if={fsfile} of={image_path} bs=1M seek=1', shell=True)
+
+ yield image_path
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_eficonfig image failed')
+ call('rm -f %s' % image_path, shell=True)
+ finally:
+ call('rm -rf %s' % mnt_point, shell=True)
+ call('rm -f %s' % image_path, shell=True)
def send_user_input_and_wait(user_str, expect_str):
time.sleep(0.1) # TODO: does not work correctly without sleep
@@ -57,12 +101,6 @@ def test_efi_eficonfig(ubman, efi_eficonfig_data):
Args:
ubman -- U-Boot console
- efi__data -- Path to the disk image used for testing.
- Test disk image has following files.
- initrd-1.img
- initrd-2.img
- initrddump.efi
-
"""
# This test passes for unknown reasons in the bowels of U-Boot. It needs to
# be replaced with a unit test.
@@ -71,6 +109,7 @@ def test_efi_eficonfig(ubman, efi_eficonfig_data):
# Restart the system to clean the previous state
ubman.restart_uboot()
+ efi_eficonfig_data = prepare_image(ubman.config)
with ubman.temporary_timeout(500):
#
# Test Case 1: Check the menu is displayed
diff --git a/test/py/tests/test_eficonfig/conftest.py b/test/py/tests/test_eficonfig/conftest.py
deleted file mode 100644
index 0a82fbefd75..00000000000
--- a/test/py/tests/test_eficonfig/conftest.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for UEFI eficonfig test
-"""
-
-import os
-import shutil
-from subprocess import check_call
-import pytest
-
-@pytest.fixture(scope='session')
-def efi_eficonfig_data(u_boot_config):
- """Set up a file system to be used in UEFI "eficonfig" command
- tests
-
- Args:
- u_boot_config -- U-Boot configuration.
-
- Return:
- A path to disk image to be used for testing
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_eficonfig'
- image_path = u_boot_config.persistent_data_dir + '/efi_eficonfig.img'
-
- shutil.rmtree(mnt_point, ignore_errors=True)
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 1")
-
- with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 2")
-
- shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
- mnt_point + '/initrddump.efi')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- return image_path
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
index 47a584ffe7c..0205048e73a 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -11,13 +11,13 @@ from fstest_defs import *
# pylint: disable=E0611
from tests import fs_helper
-supported_fs_basic = ['fat16', 'fat32', 'ext4']
-supported_fs_ext = ['fat12', 'fat16', 'fat32']
+supported_fs_basic = ['fat16', 'fat32', 'exfat', 'ext4', 'fs_generic']
+supported_fs_ext = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_fat = ['fat12', 'fat16']
-supported_fs_mkdir = ['fat12', 'fat16', 'fat32']
-supported_fs_unlink = ['fat12', 'fat16', 'fat32']
+supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
+supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_symlink = ['ext4']
-supported_fs_rename = ['fat12', 'fat16', 'fat32']
+supported_fs_rename = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
#
# Filesystem test specific setup
@@ -108,6 +108,22 @@ def pytest_generate_tests(metafunc):
#
# Helper functions
#
+def fstype_to_prefix(fs_type):
+ """Convert a file system type to an U-Boot command prefix
+
+ Args:
+ fs_type: File system type.
+
+ Return:
+ A corresponding command prefix for file system type.
+ """
+ if fs_type == 'fs_generic' or fs_type == 'exfat':
+ return ''
+ elif re.match('fat', fs_type):
+ return 'fat'
+ else:
+ return fs_type
+
def fstype_to_ubname(fs_type):
"""Convert a file system type to an U-Boot specific string
@@ -139,8 +155,12 @@ def check_ubconfig(config, fs_type):
Return:
Nothing.
"""
- if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
+ if fs_type == 'exfat' and not config.buildconfig.get('config_fs_%s' % fs_type, None):
+ pytest.skip('.config feature "FS_%s" not enabled' % fs_type.upper())
+ if fs_type != 'exfat' and not config.buildconfig.get('config_cmd_%s' % fs_type, None):
pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
+ if fs_type == 'fs_generic' or fs_type == 'exfat':
+ return
if not config.buildconfig.get('config_%s_write' % fs_type, None):
pytest.skip('.config feature "%s_WRITE" not enabled'
% fs_type.upper())
@@ -178,6 +198,8 @@ def fs_obj_basic(request, u_boot_config):
volume file name and a list of MD5 hashes.
"""
fs_type = request.param
+ fs_cmd_prefix = fstype_to_prefix(fs_type)
+ fs_cmd_write = 'save' if fs_type == 'fs_generic' or fs_type == 'exfat' else 'write'
fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
@@ -267,7 +289,7 @@ def fs_obj_basic(request, u_boot_config):
pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
return
else:
- yield [fs_ubtype, fs_img, md5val]
+ yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fs_img, md5val]
finally:
call('rm -rf %s' % scratch_dir, shell=True)
call('rm -f %s' % fs_img, shell=True)
@@ -288,6 +310,8 @@ def fs_obj_ext(request, u_boot_config):
volume file name and a list of MD5 hashes.
"""
fs_type = request.param
+ fs_cmd_prefix = fstype_to_prefix(fs_type)
+ fs_cmd_write = 'save' if fs_type == 'fs_generic' or fs_type == 'exfat' else 'write'
fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
@@ -357,7 +381,7 @@ def fs_obj_ext(request, u_boot_config):
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_img, md5val]
+ yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fs_img, md5val]
finally:
call('rm -rf %s' % scratch_dir, shell=True)
call('rm -f %s' % fs_img, shell=True)
@@ -378,6 +402,7 @@ def fs_obj_mkdir(request, u_boot_config):
volume file name.
"""
fs_type = request.param
+ fs_cmd_prefix = fstype_to_prefix(fs_type)
fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
@@ -390,7 +415,7 @@ def fs_obj_mkdir(request, u_boot_config):
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_img]
+ yield [fs_ubtype, fs_cmd_prefix, fs_img]
call('rm -f %s' % fs_img, shell=True)
#
@@ -409,6 +434,7 @@ def fs_obj_unlink(request, u_boot_config):
volume file name.
"""
fs_type = request.param
+ fs_cmd_prefix = fstype_to_prefix(fs_type)
fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
@@ -456,7 +482,7 @@ def fs_obj_unlink(request, u_boot_config):
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_img]
+ yield [fs_ubtype, fs_cmd_prefix, fs_img]
finally:
call('rm -rf %s' % scratch_dir, shell=True)
call('rm -f %s' % fs_img, shell=True)
diff --git a/test/py/tests/test_fs/fstest_helpers.py b/test/py/tests/test_fs/fstest_helpers.py
index c1447b4d43e..d25326ee993 100644
--- a/test/py/tests/test_fs/fstest_helpers.py
+++ b/test/py/tests/test_fs/fstest_helpers.py
@@ -9,6 +9,8 @@ def assert_fs_integrity(fs_type, fs_img):
try:
if fs_type == 'ext4':
check_call('fsck.ext4 -n -f %s' % fs_img, shell=True)
+ elif fs_type == 'exfat':
+ check_call('fsck.exfat -n %s' % fs_img, shell=True)
elif fs_type in ['fat12', 'fat16', 'fat32']:
check_call('fsck.fat -n %s' % fs_img, shell=True)
except CalledProcessError:
diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py
index 5a02348bb94..88b163ce305 100644
--- a/test/py/tests/test_fs/test_basic.py
+++ b/test/py/tests/test_fs/test_basic.py
@@ -20,32 +20,45 @@ class TestFsBasic(object):
"""
Test Case 1 - ls command, listing a root directory and invalid directory
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 1a - ls'):
# Test Case 1 - ls
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sls host 0:0' % fs_type])
+ '%sls host 0:0' % fs_cmd_prefix])
assert(re.search('2621440000 *%s' % BIG_FILE, ''.join(output)))
assert(re.search('1048576 *%s' % SMALL_FILE, ''.join(output)))
with ubman.log.section('Test Case 1b - ls (invalid dir)'):
# In addition, test with a nonexistent directory to see if we crash.
output = ubman.run_command(
- '%sls host 0:0 invalid_d' % fs_type)
+ '%sls host 0:0 invalid_d' % fs_cmd_prefix)
assert('' == output)
+ with ubman.log.section('Test Case 1c - test -e'):
+ # Test Case 1 - test -e
+ output = ubman.run_command_list([
+ 'host bind 0 %s' % fs_img,
+ 'test -e host 0:0 1MB.file && echo PASS'])
+ assert('PASS' in ''.join(output))
+
+ with ubman.log.section('Test Case 1d - test -e (invalid file)'):
+ # In addition, test with a nonexistent file to see if we crash.
+ output = ubman.run_command(
+ 'test -e host 0:0 2MB.file || echo PASS')
+ assert('PASS' in ''.join(output))
+
def test_fs2(self, ubman, fs_obj_basic):
"""
Test Case 2 - size command for a small file
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 2a - size (small)'):
# 1MB is 0x0010 0000
# Test Case 2a - size of small file
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%ssize host 0:0 /%s' % (fs_type, SMALL_FILE),
+ '%ssize host 0:0 /%s' % (fs_cmd_prefix, SMALL_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -53,7 +66,7 @@ class TestFsBasic(object):
with ubman.log.section('Test Case 2b - size (/../<file>)'):
# Test Case 2b - size of small file via a path using '..'
output = ubman.run_command_list([
- '%ssize host 0:0 /SUBDIR/../%s' % (fs_type, SMALL_FILE),
+ '%ssize host 0:0 /SUBDIR/../%s' % (fs_cmd_prefix, SMALL_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -62,13 +75,13 @@ class TestFsBasic(object):
"""
Test Case 3 - size command for a large file
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 3 - size (large)'):
# 2.5GB (1024*1024*2500) is 0x9C40 0000
# Test Case 3 - size of big file
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%ssize host 0:0 /%s' % (fs_type, BIG_FILE),
+ '%ssize host 0:0 /%s' % (fs_cmd_prefix, BIG_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=9c400000' in ''.join(output))
@@ -77,12 +90,12 @@ class TestFsBasic(object):
"""
Test Case 4 - load a small file, 1MB
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 4 - load (small)'):
# Test Case 4a - Read full 1MB of small file
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, SMALL_FILE),
'printenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -96,12 +109,12 @@ class TestFsBasic(object):
"""
Test Case 5 - load, reading first 1MB of 3GB file
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 5 - load (first 1MB)'):
# Test Case 5a - First 1MB of big file
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s %x 0x0' % (fs_type, ADDR, BIG_FILE, LENGTH),
+ '%sload host 0:0 %x /%s %x 0x0' % (fs_cmd_prefix, ADDR, BIG_FILE, LENGTH),
'printenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -115,14 +128,14 @@ class TestFsBasic(object):
"""
Test Case 6 - load, reading last 1MB of 3GB file
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 6 - load (last 1MB)'):
# fails for ext as no offset support
# Test Case 6a - Last 1MB of big file
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
'%sload host 0:0 %x /%s %x 0x9c300000'
- % (fs_type, ADDR, BIG_FILE, LENGTH),
+ % (fs_cmd_prefix, ADDR, BIG_FILE, LENGTH),
'printenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -136,14 +149,14 @@ class TestFsBasic(object):
"""
Test Case 7 - load, 1MB from the last 1MB in 2GB
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 7 - load (last 1MB in 2GB)'):
# fails for ext as no offset support
# Test Case 7a - One from the last 1MB chunk of 2GB
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
'%sload host 0:0 %x /%s %x 0x7ff00000'
- % (fs_type, ADDR, BIG_FILE, LENGTH),
+ % (fs_cmd_prefix, ADDR, BIG_FILE, LENGTH),
'printenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -157,14 +170,14 @@ class TestFsBasic(object):
"""
Test Case 8 - load, reading first 1MB in 2GB
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 8 - load (first 1MB in 2GB)'):
# fails for ext as no offset support
# Test Case 8a - One from the start 1MB chunk from 2GB
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
'%sload host 0:0 %x /%s %x 0x80000000'
- % (fs_type, ADDR, BIG_FILE, LENGTH),
+ % (fs_cmd_prefix, ADDR, BIG_FILE, LENGTH),
'printenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -178,14 +191,14 @@ class TestFsBasic(object):
"""
Test Case 9 - load, 1MB crossing 2GB boundary
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 9 - load (crossing 2GB boundary)'):
# fails for ext as no offset support
# Test Case 9a - One 1MB chunk crossing the 2GB boundary
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
'%sload host 0:0 %x /%s %x 0x7ff80000'
- % (fs_type, ADDR, BIG_FILE, LENGTH),
+ % (fs_cmd_prefix, ADDR, BIG_FILE, LENGTH),
'printenv filesize'])
assert('filesize=100000' in ''.join(output))
@@ -199,14 +212,14 @@ class TestFsBasic(object):
"""
Test Case 10 - load, reading beyond file end'):
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 10 - load (beyond file end)'):
# Generic failure case
# Test Case 10 - 2MB chunk from the last 1MB of big file
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
'%sload host 0:0 %x /%s 0x00200000 0x9c300000'
- % (fs_type, ADDR, BIG_FILE),
+ % (fs_cmd_prefix, ADDR, BIG_FILE),
'printenv filesize',
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
@@ -216,22 +229,22 @@ class TestFsBasic(object):
"""
Test Case 11 - write'
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 11 - write'):
# Read 1MB from small file
# Write it back to test the writes
# Test Case 11a - Check that the write succeeded
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
- '%swrite host 0:0 %x /%s.w $filesize'
- % (fs_type, ADDR, SMALL_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, SMALL_FILE),
+ '%s%s host 0:0 %x /%s.w $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, SMALL_FILE)])
assert('1048576 bytes written' in ''.join(output))
# Test Case 11b - Check md5 of written to is same
# as the one read from
output = ubman.run_command_list([
- '%sload host 0:0 %x /%s.w' % (fs_type, ADDR, SMALL_FILE),
+ '%sload host 0:0 %x /%s.w' % (fs_cmd_prefix, ADDR, SMALL_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[0] in ''.join(output))
@@ -241,7 +254,7 @@ class TestFsBasic(object):
"""
Test Case 12 - write to "." directory
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 12 - write (".")'):
# Next test case checks writing a file whose dirent
# is the first in the block, which is always true for "."
@@ -249,7 +262,8 @@ class TestFsBasic(object):
# Test Case 12 - Check directory traversal
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%swrite host 0:0 %x /. 0x10' % (fs_type, ADDR)])
+ '%s%s host 0:0 %x /. 0x10'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR)])
assert('Unable to write' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -257,23 +271,23 @@ class TestFsBasic(object):
"""
Test Case 13 - write to a file with "/./<filename>"
"""
- fs_type,fs_img,md5val = fs_obj_basic
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_basic
with ubman.log.section('Test Case 13 - write ("./<file>")'):
# Read 1MB from small file
# Write it via "same directory", i.e. "." dirent
# Test Case 13a - Check directory traversal
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, SMALL_FILE),
- '%swrite host 0:0 %x /./%s2 $filesize'
- % (fs_type, ADDR, SMALL_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, SMALL_FILE),
+ '%s%s host 0:0 %x /./%s2 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, SMALL_FILE)])
assert('1048576 bytes written' in ''.join(output))
# Test Case 13b - Check md5 of written to is same
# as the one read from
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x /./%s2' % (fs_type, ADDR, SMALL_FILE),
+ '%sload host 0:0 %x /./%s2' % (fs_cmd_prefix, ADDR, SMALL_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[0] in ''.join(output))
@@ -282,7 +296,7 @@ class TestFsBasic(object):
# as the one read from
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x /%s2' % (fs_type, ADDR, SMALL_FILE),
+ '%sload host 0:0 %x /%s2' % (fs_cmd_prefix, ADDR, SMALL_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[0] in ''.join(output))
diff --git a/test/py/tests/test_fs/test_ext.py b/test/py/tests/test_fs/test_ext.py
index 9c213f2da55..41f126e7876 100644
--- a/test/py/tests/test_fs/test_ext.py
+++ b/test/py/tests/test_fs/test_ext.py
@@ -33,20 +33,20 @@ class TestFsExt(object):
"""
Test Case 1 - write a file with absolute path
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 1 - write with abs path'):
# Test Case 1a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w1 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w1 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
assert('20480 bytes written' in ''.join(output))
# Test Case 1b - Check md5 of file content
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x /dir1/%s.w1' % (fs_type, ADDR, MIN_FILE),
+ '%sload host 0:0 %x /dir1/%s.w1' % (fs_cmd_prefix, ADDR, MIN_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[0] in ''.join(output))
@@ -56,20 +56,20 @@ class TestFsExt(object):
"""
Test Case 2 - write to a file with relative path
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 2 - write with rel path'):
# Test Case 2a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x dir1/%s.w2 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x dir1/%s.w2 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
assert('20480 bytes written' in ''.join(output))
# Test Case 2b - Check md5 of file content
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x dir1/%s.w2' % (fs_type, ADDR, MIN_FILE),
+ '%sload host 0:0 %x dir1/%s.w2' % (fs_cmd_prefix, ADDR, MIN_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[0] in ''.join(output))
@@ -79,14 +79,14 @@ class TestFsExt(object):
"""
Test Case 3 - write to a file with invalid path
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 3 - write with invalid path'):
# Test Case 3 - Check if command expectedly failed
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/none/%s.w3 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/none/%s.w3 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
assert('Unable to write file /dir1/none/' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -94,22 +94,22 @@ class TestFsExt(object):
"""
Test Case 4 - write at non-zero offset, enlarging file size
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 4 - write at non-zero offset, enlarging file size'):
# Test Case 4a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w4 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w4 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/%s.w4 $filesize 0x1400'
- % (fs_type, ADDR, MIN_FILE))
+ '%s%s host 0:0 %x /dir1/%s.w4 $filesize 0x1400'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE))
assert('20480 bytes written' in output)
# Test Case 4b - Check size of written file
output = ubman.run_command_list([
- '%ssize host 0:0 /dir1/%s.w4' % (fs_type, MIN_FILE),
+ '%ssize host 0:0 /dir1/%s.w4' % (fs_cmd_prefix, MIN_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=6400' in ''.join(output))
@@ -117,7 +117,7 @@ class TestFsExt(object):
# Test Case 4c - Check md5 of file content
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x /dir1/%s.w4' % (fs_type, ADDR, MIN_FILE),
+ '%sload host 0:0 %x /dir1/%s.w4' % (fs_cmd_prefix, ADDR, MIN_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[1] in ''.join(output))
@@ -127,22 +127,22 @@ class TestFsExt(object):
"""
Test Case 5 - write at non-zero offset, shrinking file size
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 5 - write at non-zero offset, shrinking file size'):
# Test Case 5a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w5 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w5 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/%s.w5 0x1400 0x1400'
- % (fs_type, ADDR, MIN_FILE))
+ '%s%s host 0:0 %x /dir1/%s.w5 0x1400 0x1400'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE))
assert('5120 bytes written' in output)
# Test Case 5b - Check size of written file
output = ubman.run_command_list([
- '%ssize host 0:0 /dir1/%s.w5' % (fs_type, MIN_FILE),
+ '%ssize host 0:0 /dir1/%s.w5' % (fs_cmd_prefix, MIN_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=2800' in ''.join(output))
@@ -150,7 +150,7 @@ class TestFsExt(object):
# Test Case 5c - Check md5 of file content
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x /dir1/%s.w5' % (fs_type, ADDR, MIN_FILE),
+ '%sload host 0:0 %x /dir1/%s.w5' % (fs_cmd_prefix, ADDR, MIN_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[2] in ''.join(output))
@@ -160,22 +160,22 @@ class TestFsExt(object):
"""
Test Case 6 - write nothing at the start, truncating to zero
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 6 - write nothing at the start, truncating to zero'):
# Test Case 6a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w6 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w6 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/%s.w6 0 0'
- % (fs_type, ADDR, MIN_FILE))
+ '%s%s host 0:0 %x /dir1/%s.w6 0 0'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE))
assert('0 bytes written' in output)
# Test Case 6b - Check size of written file
output = ubman.run_command_list([
- '%ssize host 0:0 /dir1/%s.w6' % (fs_type, MIN_FILE),
+ '%ssize host 0:0 /dir1/%s.w6' % (fs_cmd_prefix, MIN_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=0' in ''.join(output))
@@ -185,22 +185,22 @@ class TestFsExt(object):
"""
Test Case 7 - write at the end (append)
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 7 - write at the end (append)'):
# Test Case 7a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w7 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w7 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/%s.w7 $filesize $filesize'
- % (fs_type, ADDR, MIN_FILE))
+ '%s%s host 0:0 %x /dir1/%s.w7 $filesize $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE))
assert('20480 bytes written' in output)
# Test Case 7b - Check size of written file
output = ubman.run_command_list([
- '%ssize host 0:0 /dir1/%s.w7' % (fs_type, MIN_FILE),
+ '%ssize host 0:0 /dir1/%s.w7' % (fs_cmd_prefix, MIN_FILE),
'printenv filesize',
'setenv filesize'])
assert('filesize=a000' in ''.join(output))
@@ -208,7 +208,7 @@ class TestFsExt(object):
# Test Case 7c - Check md5 of file content
output = ubman.run_command_list([
'mw.b %x 00 100' % ADDR,
- '%sload host 0:0 %x /dir1/%s.w7' % (fs_type, ADDR, MIN_FILE),
+ '%sload host 0:0 %x /dir1/%s.w7' % (fs_cmd_prefix, ADDR, MIN_FILE),
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(md5val[3] in ''.join(output))
@@ -218,17 +218,17 @@ class TestFsExt(object):
"""
Test Case 8 - write at offset beyond the end of file
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 8 - write beyond the end'):
# Test Case 8a - Check if command expectedly failed
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w8 $filesize'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w8 $filesize'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/%s.w8 0x1400 %x'
- % (fs_type, ADDR, MIN_FILE, 0x100000 + 0x1400))
+ '%s%s host 0:0 %x /dir1/%s.w8 0x1400 %x'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE, 0x100000 + 0x1400))
assert('Unable to write file /dir1' in output)
assert_fs_integrity(fs_type, fs_img)
@@ -236,14 +236,14 @@ class TestFsExt(object):
"""
Test Case 9 - write to a non-existing file at non-zero offset
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 9 - write to non-existing file with non-zero offset'):
# Test Case 9a - Check if command expectedly failed
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
- '%swrite host 0:0 %x /dir1/%s.w9 0x1400 0x1400'
- % (fs_type, ADDR, MIN_FILE)])
+ '%sload host 0:0 %x /%s' % (fs_cmd_prefix, ADDR, MIN_FILE),
+ '%s%s host 0:0 %x /dir1/%s.w9 0x1400 0x1400'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MIN_FILE)])
assert('Unable to write file /dir1' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -252,7 +252,7 @@ class TestFsExt(object):
'Test Case 10 - create/delete as many directories under root directory
as amount of directory entries goes beyond one cluster size)'
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 10 - create/delete (many)'):
# Test Case 10a - Create many files
# Please note that the size of directory entry is 32 bytes.
@@ -262,9 +262,9 @@ class TestFsExt(object):
for i in range(0, 66):
output = ubman.run_command(
- '%swrite host 0:0 %x /FILE0123456789_%02x 100'
- % (fs_type, ADDR, i))
- output = ubman.run_command('%sls host 0:0 /' % fs_type)
+ '%s%s host 0:0 %x /FILE0123456789_%02x 100'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, i))
+ output = ubman.run_command('%sls host 0:0 /' % fs_cmd_prefix)
assert('FILE0123456789_00' in output)
assert('FILE0123456789_41' in output)
@@ -272,8 +272,8 @@ class TestFsExt(object):
for i in range(0, 66):
output = ubman.run_command(
'%srm host 0:0 /FILE0123456789_%02x'
- % (fs_type, i))
- output = ubman.run_command('%sls host 0:0 /' % fs_type)
+ % (fs_cmd_prefix, i))
+ output = ubman.run_command('%sls host 0:0 /' % fs_cmd_prefix)
assert(not 'FILE0123456789_00' in output)
assert(not 'FILE0123456789_41' in output)
@@ -281,9 +281,9 @@ class TestFsExt(object):
# Please note no.64 and 65 are intentionally re-created
for i in range(64, 128):
output = ubman.run_command(
- '%swrite host 0:0 %x /FILE0123456789_%02x 100'
- % (fs_type, ADDR, i))
- output = ubman.run_command('%sls host 0:0 /' % fs_type)
+ '%s%s host 0:0 %x /FILE0123456789_%02x 100'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, i))
+ output = ubman.run_command('%sls host 0:0 /' % fs_cmd_prefix)
assert('FILE0123456789_40' in output)
assert('FILE0123456789_79' in output)
@@ -294,7 +294,7 @@ class TestFsExt(object):
'Test Case 11 - create/delete as many directories under non-root
directory as amount of directory entries goes beyond one cluster size)'
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 11 - create/delete (many)'):
# Test Case 11a - Create many files
# Please note that the size of directory entry is 32 bytes.
@@ -304,9 +304,9 @@ class TestFsExt(object):
for i in range(0, 66):
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/FILE0123456789_%02x 100'
- % (fs_type, ADDR, i))
- output = ubman.run_command('%sls host 0:0 /dir1' % fs_type)
+ '%s%s host 0:0 %x /dir1/FILE0123456789_%02x 100'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, i))
+ output = ubman.run_command('%sls host 0:0 /dir1' % fs_cmd_prefix)
assert('FILE0123456789_00' in output)
assert('FILE0123456789_41' in output)
@@ -314,8 +314,8 @@ class TestFsExt(object):
for i in range(0, 66):
output = ubman.run_command(
'%srm host 0:0 /dir1/FILE0123456789_%02x'
- % (fs_type, i))
- output = ubman.run_command('%sls host 0:0 /dir1' % fs_type)
+ % (fs_cmd_prefix, i))
+ output = ubman.run_command('%sls host 0:0 /dir1' % fs_cmd_prefix)
assert(not 'FILE0123456789_00' in output)
assert(not 'FILE0123456789_41' in output)
@@ -323,9 +323,9 @@ class TestFsExt(object):
# Please note no.64 and 65 are intentionally re-created
for i in range(64, 128):
output = ubman.run_command(
- '%swrite host 0:0 %x /dir1/FILE0123456789_%02x 100'
- % (fs_type, ADDR, i))
- output = ubman.run_command('%sls host 0:0 /dir1' % fs_type)
+ '%s%s host 0:0 %x /dir1/FILE0123456789_%02x 100'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, i))
+ output = ubman.run_command('%sls host 0:0 /dir1' % fs_cmd_prefix)
assert('FILE0123456789_40' in output)
assert('FILE0123456789_79' in output)
@@ -335,21 +335,29 @@ class TestFsExt(object):
"""
Test Case 12 - write plain and mangle file
"""
- fs_type,fs_img,md5val = fs_obj_ext
+ fs_type,fs_cmd_prefix,fs_cmd_write,fs_img,md5val = fs_obj_ext
with ubman.log.section('Test Case 12 - write plain and mangle file'):
# Test Case 12a - Check if command successfully returned
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%swrite host 0:0 %x /%s 0'
- % (fs_type, ADDR, PLAIN_FILE),
- '%swrite host 0:0 %x /%s 0'
- % (fs_type, ADDR, MANGLE_FILE)])
+ '%s%s host 0:0 %x /%s 0'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, PLAIN_FILE),
+ '%s%s host 0:0 %x /%s 0'
+ % (fs_cmd_prefix, fs_cmd_write, ADDR, MANGLE_FILE)])
assert('0 bytes written' in ''.join(output))
- # Test Case 12b - Read file system content
- output = check_output('mdir -i %s' % fs_img, shell=True).decode()
- # Test Case 12c - Check if short filename is not mangled
- assert(str2fat(PLAIN_FILE) in ''.join(output))
- # Test Case 12d - Check if long filename is mangled
- assert(str2fat(MANGLE_FILE) in ''.join(output))
+ if fs_type == 'exfat':
+ # Test Case 12b - Read file system content
+ output = check_output('fattools ls %s' % fs_img, shell=True).decode()
+ # Test Case 12c - Check if short filename is not mangled
+ assert(PLAIN_FILE in ''.join(output))
+ # Test Case 12d - Check if long filename is mangled
+ assert(MANGLE_FILE in ''.join(output))
+ else:
+ # Test Case 12b - Read file system content
+ output = check_output('mdir -i %s' % fs_img, shell=True).decode()
+ # Test Case 12c - Check if short filename is not mangled
+ assert(str2fat(PLAIN_FILE) in ''.join(output))
+ # Test Case 12d - Check if long filename is mangled
+ assert(str2fat(MANGLE_FILE) in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
diff --git a/test/py/tests/test_fs/test_mkdir.py b/test/py/tests/test_fs/test_mkdir.py
index df680a87d57..1578c3cba3a 100644
--- a/test/py/tests/test_fs/test_mkdir.py
+++ b/test/py/tests/test_fs/test_mkdir.py
@@ -18,16 +18,16 @@ class TestMkdir(object):
"""
Test Case 1 - create a directory under a root
"""
- fs_type,fs_img = fs_obj_mkdir
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_mkdir
with ubman.log.section('Test Case 1 - mkdir'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%smkdir host 0:0 dir1' % fs_type,
- '%sls host 0:0 /' % fs_type])
+ '%smkdir host 0:0 dir1' % fs_cmd_prefix,
+ '%sls host 0:0 /' % fs_cmd_prefix])
assert('dir1/' in ''.join(output))
output = ubman.run_command(
- '%sls host 0:0 dir1' % fs_type)
+ '%sls host 0:0 dir1' % fs_cmd_prefix)
assert('./' in output)
assert('../' in output)
assert_fs_integrity(fs_type, fs_img)
@@ -37,16 +37,16 @@ class TestMkdir(object):
"""
Test Case 2 - create a directory under a sub-directory
"""
- fs_type,fs_img = fs_obj_mkdir
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_mkdir
with ubman.log.section('Test Case 2 - mkdir (sub-sub directory)'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%smkdir host 0:0 dir1/dir2' % fs_type,
- '%sls host 0:0 dir1' % fs_type])
+ '%smkdir host 0:0 dir1/dir2' % fs_cmd_prefix,
+ '%sls host 0:0 dir1' % fs_cmd_prefix])
assert('dir2/' in ''.join(output))
output = ubman.run_command(
- '%sls host 0:0 dir1/dir2' % fs_type)
+ '%sls host 0:0 dir1/dir2' % fs_cmd_prefix)
assert('./' in output)
assert('../' in output)
assert_fs_integrity(fs_type, fs_img)
@@ -56,11 +56,11 @@ class TestMkdir(object):
Test Case 3 - trying to create a directory with a non-existing
path should fail
"""
- fs_type,fs_img = fs_obj_mkdir
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_mkdir
with ubman.log.section('Test Case 3 - mkdir (non-existing path)'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%smkdir host 0:0 none/dir3' % fs_type])
+ '%smkdir host 0:0 none/dir3' % fs_cmd_prefix])
assert('Unable to create a directory' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -68,11 +68,11 @@ class TestMkdir(object):
"""
Test Case 4 - trying to create "." should fail
"""
- fs_type,fs_img = fs_obj_mkdir
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_mkdir
with ubman.log.section('Test Case 4 - mkdir (".")'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%smkdir host 0:0 .' % fs_type])
+ '%smkdir host 0:0 .' % fs_cmd_prefix])
assert('Unable to create a directory' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -80,11 +80,11 @@ class TestMkdir(object):
"""
Test Case 5 - trying to create ".." should fail
"""
- fs_type,fs_img = fs_obj_mkdir
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_mkdir
with ubman.log.section('Test Case 5 - mkdir ("..")'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%smkdir host 0:0 ..' % fs_type])
+ '%smkdir host 0:0 ..' % fs_cmd_prefix])
assert('Unable to create a directory' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -93,29 +93,29 @@ class TestMkdir(object):
'Test Case 6 - create as many directories as amount of directory
entries goes beyond a cluster size)'
"""
- fs_type,fs_img = fs_obj_mkdir
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_mkdir
with ubman.log.section('Test Case 6 - mkdir (create many)'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%smkdir host 0:0 dir6' % fs_type,
- '%sls host 0:0 /' % fs_type])
+ '%smkdir host 0:0 dir6' % fs_cmd_prefix,
+ '%sls host 0:0 /' % fs_cmd_prefix])
assert('dir6/' in ''.join(output))
for i in range(0, 20):
output = ubman.run_command(
'%smkdir host 0:0 dir6/0123456789abcdef%02x'
- % (fs_type, i))
- output = ubman.run_command('%sls host 0:0 dir6' % fs_type)
+ % (fs_cmd_prefix, i))
+ output = ubman.run_command('%sls host 0:0 dir6' % fs_cmd_prefix)
assert('0123456789abcdef00/' in output)
assert('0123456789abcdef13/' in output)
output = ubman.run_command(
- '%sls host 0:0 dir6/0123456789abcdef13/.' % fs_type)
+ '%sls host 0:0 dir6/0123456789abcdef13/.' % fs_cmd_prefix)
assert('./' in output)
assert('../' in output)
output = ubman.run_command(
- '%sls host 0:0 dir6/0123456789abcdef13/..' % fs_type)
+ '%sls host 0:0 dir6/0123456789abcdef13/..' % fs_cmd_prefix)
assert('0123456789abcdef00/' in output)
assert('0123456789abcdef13/' in output)
assert_fs_integrity(fs_type, fs_img)
diff --git a/test/py/tests/test_fs/test_unlink.py b/test/py/tests/test_fs/test_unlink.py
index 7e911f02413..1e2df3dbfd8 100644
--- a/test/py/tests/test_fs/test_unlink.py
+++ b/test/py/tests/test_fs/test_unlink.py
@@ -19,16 +19,16 @@ class TestUnlink(object):
"""
Test Case 1 - delete a file
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 1 - unlink (file)'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%srm host 0:0 dir1/file1' % fs_type,
- '%sls host 0:0 dir1/file1' % fs_type])
+ '%srm host 0:0 dir1/file1' % fs_cmd_prefix,
+ '%sls host 0:0 dir1/file1' % fs_cmd_prefix])
assert('' == ''.join(output))
output = ubman.run_command(
- '%sls host 0:0 dir1/' % fs_type)
+ '%sls host 0:0 dir1/' % fs_cmd_prefix)
assert(not 'file1' in output)
assert('file2' in output)
assert_fs_integrity(fs_type, fs_img)
@@ -37,18 +37,18 @@ class TestUnlink(object):
"""
Test Case 2 - delete many files
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 2 - unlink (many)'):
output = ubman.run_command('host bind 0 %s' % fs_img)
for i in range(0, 20):
output = ubman.run_command_list([
- '%srm host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i),
- '%sls host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i)])
+ '%srm host 0:0 dir2/0123456789abcdef%02x' % (fs_cmd_prefix, i),
+ '%sls host 0:0 dir2/0123456789abcdef%02x' % (fs_cmd_prefix, i)])
assert('' == ''.join(output))
output = ubman.run_command(
- '%sls host 0:0 dir2' % fs_type)
+ '%sls host 0:0 dir2' % fs_cmd_prefix)
assert('0 file(s), 2 dir(s)' in output)
assert_fs_integrity(fs_type, fs_img)
@@ -56,11 +56,11 @@ class TestUnlink(object):
"""
Test Case 3 - trying to delete a non-existing file should fail
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 3 - unlink (non-existing)'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%srm host 0:0 dir1/nofile' % fs_type])
+ '%srm host 0:0 dir1/nofile' % fs_cmd_prefix])
assert('nofile: doesn\'t exist' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -68,15 +68,15 @@ class TestUnlink(object):
"""
Test Case 4 - delete an empty directory
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 4 - unlink (directory)'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%srm host 0:0 dir4' % fs_type])
+ '%srm host 0:0 dir4' % fs_cmd_prefix])
assert('' == ''.join(output))
output = ubman.run_command(
- '%sls host 0:0 /' % fs_type)
+ '%sls host 0:0 /' % fs_cmd_prefix)
assert(not 'dir4' in output)
assert_fs_integrity(fs_type, fs_img)
@@ -85,11 +85,11 @@ class TestUnlink(object):
Test Case 5 - trying to deleting a non-empty directory ".."
should fail
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 5 - unlink ("non-empty directory")'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%srm host 0:0 dir5' % fs_type])
+ '%srm host 0:0 dir5' % fs_cmd_prefix])
assert('directory is not empty' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -97,11 +97,11 @@ class TestUnlink(object):
"""
Test Case 6 - trying to deleting a "." should fail
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 6 - unlink (".")'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%srm host 0:0 dir5/.' % fs_type])
+ '%srm host 0:0 dir5/.' % fs_cmd_prefix])
assert('directory is not empty' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
@@ -109,10 +109,10 @@ class TestUnlink(object):
"""
Test Case 7 - trying to deleting a ".." should fail
"""
- fs_type,fs_img = fs_obj_unlink
+ fs_type,fs_cmd_prefix,fs_img = fs_obj_unlink
with ubman.log.section('Test Case 7 - unlink ("..")'):
output = ubman.run_command_list([
'host bind 0 %s' % fs_img,
- '%srm host 0:0 dir5/..' % fs_type])
+ '%srm host 0:0 dir5/..' % fs_cmd_prefix])
assert('directory is not empty' in ''.join(output))
assert_fs_integrity(fs_type, fs_img)
diff --git a/test/py/tests/test_memtest.py b/test/py/tests/test_memtest.py
index 0340edbea5a..f24f9f0d67d 100644
--- a/test/py/tests/test_memtest.py
+++ b/test/py/tests/test_memtest.py
@@ -29,12 +29,12 @@ def get_memtest_env(ubman):
if not f:
pytest.skip("memtest is not enabled!")
else:
- start = f.get("start_addr", 0x0)
- size = f.get("size", 0x1000)
- pattern = f.get("pattern", 0x0)
+ start = hex(f.get("start_addr", 0x0))
+ size = hex(f.get("size", 0x1000))
+ pattern = hex(f.get("pattern", 0x0))
iteration = f.get("iteration", 2)
timeout = f.get("timeout", 50000)
- end = hex(int(start) + int(size))
+ end = hex(int(start, 16) + int(size, 16))
return start, end, pattern, iteration, timeout
@pytest.mark.buildconfigspec("cmd_memtest")
diff --git a/test/py/tests/test_spi.py b/test/py/tests/test_spi.py
index dd767528dbf..09174f91e98 100644
--- a/test/py/tests/test_spi.py
+++ b/test/py/tests/test_spi.py
@@ -703,4 +703,33 @@ def test_spi_negative(ubman):
ubman, 'read', start, size, res_area, 1, error_msg, EXPECTED_READ
)
+ # Start reading from the reserved area
+ m = re.search(r'reserved\[0\]\s*\[(0x.+)-(0x.+)\]', output)
+ if not m or int(m.group(1), 16) == 0:
+ ubman.log.info('No reserved area is defined or start addr is 0x0!')
+ else:
+ rstart_area = int(m.group(1), 16)
+ rend_area = int(m.group(2), 16)
+
+ # Case 1: Start reading from the middle of the reserved area
+ r_size = rend_area - rstart_area
+ r_area = rstart_area + r_size
+ flash_ops(
+ ubman, 'read', start, size, r_area, 1, error_msg, EXPECTED_READ
+ )
+
+ # Case 2: Start reading from before the reserved area to cross-over
+ # the reserved area
+ rstart_area = rstart_area - int(size/2)
+ flash_ops(
+ ubman, 'read', start, size, rstart_area, 1, error_msg, EXPECTED_READ
+ )
+
+ # Case 3: Start reading till after the reserved area to cross-over
+ # the reserved area
+ rend_area = rend_area - int(size/2)
+ flash_ops(
+ ubman, 'read', start, size, rend_area, 1, error_msg, EXPECTED_READ
+ )
+
i = i + 1
diff --git a/test/py/tests/test_trace.py b/test/py/tests/test_trace.py
index 6ac1b225465..fcdcbe2c6db 100644
--- a/test/py/tests/test_trace.py
+++ b/test/py/tests/test_trace.py
@@ -201,7 +201,7 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
# Then look for this:
# u-boot-1 0..... 282.101375: funcgraph_exit: 0.006 us | }
# Then check for this:
- # u-boot-1 0..... 282.101375: funcgraph_entry: 0.000 us | calc_reloc_ofs();
+ # u-boot-1 0..... 282.101375: funcgraph_entry: 0.000 us | event_init();
expected_indent = None
found_start = False
@@ -224,8 +224,8 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
found_end = True
# The next function after initf_bootstage() exits should be
- # initcall_is_event()
- assert upto == 'calc_reloc_ofs()'
+ # event_init()
+ assert upto == 'event_init()'
# Now look for initf_dm() and dm_timer_init() so we can check the bootstage
# time
@@ -274,7 +274,7 @@ def check_flamegraph(ubman, fname, proftool, map_fname, trace_fg):
# We expect dm_timer_init() to be called twice: once before relocation and
# once after
look1 = 'initf_dm;dm_timer_init 1'
- look2 = 'board_init_r;initcall_run_list;initr_dm_devices;dm_timer_init 1'
+ look2 = 'board_init_r;initcall_run_r;initr_dm_devices;dm_timer_init 1'
found = 0
with open(trace_fg, 'r') as fd:
for line in fd:
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index ea0c43cd4fc..cdf54adc600 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -27,35 +27,16 @@ def mkdir_cond(dirname):
if not os.path.exists(dirname):
os.mkdir(dirname)
-def setup_image(ubman, devnum, part_type, img_size=20, second_part=False,
- basename='mmc'):
- """Create a disk image with a single partition
+def copy_partition(ubman, fsfile, outname):
+ """Copy a partition into a disk iamge
Args:
- ubman (ConsoleBase): Console to use
- devnum (int): Device number to use, e.g. 1
- part_type (int): Partition type, e.g. 0xc for FAT32
- img_size (int): Image size in MiB
- 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 scratch directory
+ ubman (ConsoleBase): U-Boot fixture
+ fsfile (str): Name of partition file
+ outname (str): Name of full-disk file to update
"""
- fname = os.path.join(ubman.config.source_dir, f'{basename}{devnum}.img')
- mnt = os.path.join(ubman.config.persistent_data_dir, 'scratch')
- mkdir_cond(mnt)
-
- spec = f'type={part_type:x}, size={img_size - 2}M, start=1M, bootable'
- if second_part:
- spec += '\ntype=c'
-
- utils.run_and_log(ubman, f'qemu-img create {fname} 20M')
- utils.run_and_log(ubman, f'sfdisk {fname}',
- stdin=spec.encode('utf-8'))
- return fname, mnt
+ utils.run_and_log(ubman,
+ f'dd if={fsfile} of={outname} bs=1M seek=1 conv=notrunc')
def setup_bootmenu_image(ubman):
"""Create a 20MB disk image with a single ext4 partition
@@ -63,7 +44,7 @@ def setup_bootmenu_image(ubman):
This is modelled on Armbian 22.08 Jammy
"""
mmc_dev = 4
- fname, mnt = setup_image(ubman, mmc_dev, 0x83)
+ fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0x83)
script = '''# DO NOT EDIT THIS FILE
#
@@ -172,14 +153,14 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
fsfile = 'ext18M.img'
utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}')
utils.run_and_log(ubman, f'mkfs.ext4 {fsfile} -d {mnt}')
- utils.run_and_log(ubman, f'dd if={fsfile} of={fname} bs=1M seek=1')
+ copy_partition(ubman, fsfile, fname)
utils.run_and_log(ubman, f'rm -rf {mnt}')
utils.run_and_log(ubman, f'rm -f {fsfile}')
def setup_bootflow_image(ubman):
"""Create a 20MB disk image with a single FAT partition"""
mmc_dev = 1
- fname, mnt = setup_image(ubman, mmc_dev, 0xc, second_part=True)
+ fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0xc, second_part=True)
vmlinux = 'vmlinuz-5.3.7-301.fc31.armv7hl'
initrd = 'initramfs-5.3.7-301.fc31.armv7hl.img'
@@ -224,7 +205,7 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}')
utils.run_and_log(ubman, f'mkfs.vfat {fsfile}')
utils.run_and_log(ubman, ['sh', '-c', f'mcopy -i {fsfile} {mnt}/* ::/'])
- utils.run_and_log(ubman, f'dd if={fsfile} of={fname} bs=1M seek=1')
+ copy_partition(ubman, fsfile, fname)
utils.run_and_log(ubman, f'rm -rf {mnt}')
utils.run_and_log(ubman, f'rm -f {fsfile}')
@@ -545,8 +526,8 @@ def setup_efi_image(ubman):
"""Create a 20MB disk image with an EFI app on it"""
devnum = 1
basename = 'flash'
- fname, mnt = setup_image(ubman, devnum, 0xc, second_part=True,
- basename=basename)
+ fname, mnt = fs_helper.setup_image(ubman, devnum, 0xc, second_part=True,
+ basename=basename)
efi_dir = os.path.join(mnt, 'EFI')
mkdir_cond(efi_dir)
@@ -562,7 +543,7 @@ def setup_efi_image(ubman):
utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}')
utils.run_and_log(ubman, f'mkfs.vfat {fsfile}')
utils.run_and_log(ubman, ['sh', '-c', f'mcopy -vs -i {fsfile} {mnt}/* ::/'])
- utils.run_and_log(ubman, f'dd if={fsfile} of={fname} bs=1M seek=1')
+ copy_partition(ubman, fsfile, fname)
utils.run_and_log(ubman, f'rm -rf {mnt}')
utils.run_and_log(ubman, f'rm -f {fsfile}')
diff --git a/test/py/tests/test_xxd.py b/test/py/tests/test_xxd.py
new file mode 100644
index 00000000000..c457c54146c
--- /dev/null
+++ b/test/py/tests/test_xxd.py
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+""" Unit test for xxd command
+"""
+
+import pytest
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_xxd')
+def test_xxd(ubman):
+ """ Unit test for xxd
+
+ Args:
+ ubman -- U-Boot console
+ """
+ try:
+ scratch_dir = ubman.config.persistent_data_dir + '/scratch'
+
+ check_call('mkdir -p %s' % scratch_dir, shell=True)
+
+ with open(scratch_dir + '/hello', 'w', encoding = 'ascii') as file:
+ file.write('hello world\n\x00\x01\x02\x03\x04\x05')
+
+ xxd_data = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_xxd', scratch_dir)
+ response = ubman.run_command_list([ f'host bind 0 {xxd_data}',
+ 'xxd host 0 hello'])
+
+ assert '00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....\r\r\n' + \
+ '00000010: 04 05 ..' \
+ in response
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_xxd image failed')
+ call('rm -f %s' % xxd_data, shell=True)
+ return
+ finally:
+ call('rm -rf %s' % scratch_dir, shell=True)
+ call('rm -f %s' % xxd_data, shell=True)
diff --git a/test/py/tests/test_xxd/conftest.py b/test/py/tests/test_xxd/conftest.py
deleted file mode 100644
index 47c7cce1aa9..00000000000
--- a/test/py/tests/test_xxd/conftest.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for xxd command test
-"""
-
-import os
-import shutil
-from subprocess import check_call, CalledProcessError
-import pytest
-
-@pytest.fixture(scope='session')
-def xxd_data(u_boot_config):
- """Set up a file system to be used in xxd tests
-
- Args:
- u_boot_config -- U-Boot configuration.
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_xxd'
- image_path = u_boot_config.persistent_data_dir + '/xxd.img'
-
- try:
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/hello', 'w', encoding = 'ascii') as file:
- file.write('hello world\n\x00\x01\x02\x03\x04\x05')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- yield image_path
- except CalledProcessError:
- pytest.skip('Setup failed')
- finally:
- shutil.rmtree(mnt_point)
- if os.path.exists(image_path):
- os.remove(image_path)
diff --git a/test/py/tests/test_xxd/test_xxd.py b/test/py/tests/test_xxd/test_xxd.py
deleted file mode 100644
index c04bf8b7a25..00000000000
--- a/test/py/tests/test_xxd/test_xxd.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-""" Unit test for xxd command
-"""
-
-import pytest
-
-@pytest.mark.boardspec('sandbox')
-@pytest.mark.buildconfigspec('cmd_xxd')
-def test_xxd(ubman, xxd_data):
- """ Unit test for xxd
-
- Args:
- ubman -- U-Boot console
- xxd_data -- Path to the disk image used for testing.
- """
- response = ubman.run_command_list([
- f'host bind 0 {xxd_data}',
- 'xxd host 0 hello'])
-
- assert '00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....\r\r\n' + \
- '00000010: 04 05 ..' \
- in response