diff options
Diffstat (limited to 'test')
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 |