Add a bootstd test for the error path of the efi_mgr bootmeth: remove the BootOrder variable so that the boot manager has nothing to load and check that booting the bootflow returns -ENOENT rather than the generic -EFAULT that bootflow_boot() reports when a boot() method returns zero.
Running the real boot manager initialises the EFI subsystem in the sandbox process, which would leak into later tests, so restart U-Boot after this test in test_ut.py as is already done for other session-changing tests. Signed-off-by: Aristo Chen <[email protected]> --- Changes in v2: - Remove BootOrder instead of pointing it at a non-existent load option, which relied on efidebug accepting invalid input (Heinrich) - Check for -ENOENT accordingly and drop the CMD_EFIDEBUG dependency test/boot/bootflow.c | 40 ++++++++++++++++++++++++++++++++++++++++ test/py/tests/test_ut.py | 3 ++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 1cc137c9700..9d71fffba8e 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -14,6 +14,7 @@ #include <dm.h> #include <efi.h> #include <efi_loader.h> +#include <efi_variable.h> #include <env.h> #include <expo.h> #include <mapmem.h> @@ -470,6 +471,45 @@ static int bootflow_system(struct unit_test_state *uts) } BOOTSTD_TEST(bootflow_system, UTF_DM | UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE); + +/* Check that a failed 'efi_mgr' boot reports the boot manager's error */ +static int bootflow_efi_mgr_err(struct unit_test_state *uts) +{ + struct udevice *bootstd, *dev; + struct bootflow *bflow; + efi_status_t status; + int ret; + + if (!IS_ENABLED(CONFIG_EFI_BOOTMGR)) + return -EAGAIN; + ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); + ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_3efi_mgr), + "efi_mgr", 0, ofnode_null(), &dev)); + ut_assertok(device_probe(dev)); + sandbox_set_fake_efi_mgr_dev(dev, true); + + bootstd_clear_glob(); + ut_assertok(run_command("bootflow scan -H", 0)); + + /* Remove any BootOrder so that the boot manager has nothing to load */ + ut_asserteq(EFI_SUCCESS, efi_init_obj_list()); + status = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + 0, 0, NULL, false); + ut_assert(status == EFI_SUCCESS || status == EFI_NOT_FOUND); + + for (ret = bootflow_first_glob(&bflow); !ret; + ret = bootflow_next_glob(&bflow)) { + if (!strcmp("efi_mgr", bflow->method->name)) + break; + } + ut_assertok(ret); + + /* The boot manager finds no boot option; its error must not be lost */ + ut_asserteq(-ENOENT, bootflow_boot(bflow)); + + return 0; +} +BOOTSTD_TEST(bootflow_efi_mgr_err, UTF_DM | UTF_SCAN_PDATA | UTF_SCAN_FDT); #endif /* Check disabling a bootmethod if it requests it */ diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index fa50c8008a5..787020e3e0c 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -643,7 +643,8 @@ def ut_ubman_fixture(ubman, ut_subtest): yield ubman - if ut_subtest in ("bootstd bootflow_cmd_boot", "bootstd bootflow_scan_boot"): + if ut_subtest in ("bootstd bootflow_cmd_boot", "bootstd bootflow_scan_boot", + "bootstd bootflow_efi_mgr_err"): ubman.restart_uboot() -- 2.43.0
