[PATCH 23/28] bootmethod: Add tests for bootmethod and bootflow
Simon Glass
sjg at chromium.org
Thu Aug 19 05:45:56 CEST 2021
Add a set of combined tests for these two commands.
Expand the sandbox console-recording limit so that these can work.
These tests rely on a filesystem script which is not yet added to the
Python tests. It is included here as a shell script.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
MAINTAINERS | 1 +
configs/sandbox_defconfig | 2 +-
include/test/suites.h | 2 +
test/Makefile | 1 +
test/boot/Makefile | 5 +
test/boot/bootmethod.c | 271 ++++++++++++++++++++++++++++++++++++++
test/cmd_ut.c | 4 +
try.sh | 131 ++++++++++++++++++
8 files changed, 416 insertions(+), 1 deletion(-)
create mode 100644 test/boot/Makefile
create mode 100644 test/boot/bootmethod.c
create mode 100755 try.sh
diff --git a/MAINTAINERS b/MAINTAINERS
index 367193358b7..2f74f7dbb19 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -639,6 +639,7 @@ F: cmd/bootflow.c
F: cmd/bootmethod.c
F: include/bootmethod.h
F: include/distro.h
+F: test/boot/bootmethod.c
BTRFS
M: Marek Behun <marek.behun at nic.cz>
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 952d430304c..31a8d6a1d90 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -26,7 +26,7 @@ CONFIG_AUTOBOOT_NEVER_TIMEOUT=y
CONFIG_AUTOBOOT_STOP_STR_ENABLE=y
CONFIG_AUTOBOOT_STOP_STR_CRYPT="$5$rounds=640000$HrpE65IkB8CM5nCL$BKT3QdF98Bo8fJpTr9tjZLZQyzqPASBY20xuK5Rent9"
CONFIG_CONSOLE_RECORD=y
-CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x2000
CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_LOG=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
diff --git a/include/test/suites.h b/include/test/suites.h
index d35cd83a4eb..c36aa568e78 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -29,6 +29,8 @@ int cmd_ut_category(const char *name, const char *prefix,
int do_ut_addrmap(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]);
int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
+int do_ut_bootmethod(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[]);
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]);
int do_ut_common(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
diff --git a/test/Makefile b/test/Makefile
index b3b2902e2e7..abd605a4351 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_UT_TIME) += time_ut.o
obj-y += ut.o
ifeq ($(CONFIG_SPL_BUILD),)
+obj-$(CONFIG_UNIT_TEST) += boot/
obj-$(CONFIG_UNIT_TEST) += common/
obj-$(CONFIG_UNIT_TEST) += lib/
obj-y += log/
diff --git a/test/boot/Makefile b/test/boot/Makefile
new file mode 100644
index 00000000000..bb1599b9c0d
--- /dev/null
+++ b/test/boot/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2021 Google LLC
+
+obj-$(CONFIG_BOOTMETHOD) += bootmethod.o
diff --git a/test/boot/bootmethod.c b/test/boot/bootmethod.c
new file mode 100644
index 00000000000..4467625c0fd
--- /dev/null
+++ b/test/boot/bootmethod.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg at chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <bootmethod.h>
+#include <test/suites.h>
+#include <test/ut.h>
+
+/* Declare a new bootmethod test */
+#define BOOTMETHOD_TEST(_name, _flags) \
+ UNIT_TEST(_name, _flags, bootmethod_test)
+
+/* Check 'bootmethod list' command */
+static int bootmethod_test_cmd_list(struct unit_test_state *uts)
+{
+ int probed;
+
+ console_record_reset_enable();
+ for (probed = 0; probed < 2; probed++) {
+ int probe_ch = probed ? '+' : ' ';
+
+ ut_assertok(run_command(probed ? "bootmethod list -p" :
+ "bootmethod list", 0));
+ ut_assert_nextline("Seq Probed Status Uclass Name");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("%3x [ %c ] %6s %-8s %s", 0, probe_ch, "OK",
+ "mmc", "mmc2.bootmethod");
+ ut_assert_nextline("%3x [ %c ] %6s %-8s %s", 1, probe_ch, "OK",
+ "mmc", "mmc1.bootmethod");
+ ut_assert_nextline("%3x [ %c ] %6s %-8s %s", 2, probe_ch, "OK",
+ "mmc", "mmc0.bootmethod");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(3 devices)");
+ ut_assert_console_end();
+ }
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_list, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootmethod select' and 'info' commands */
+static int bootmethod_test_cmd_select(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_asserteq(1, run_command("bootmethod info", 0));
+ ut_assert_nextlinen("Please use");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootmethod select 0", 0));
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootmethod info", 0));
+ ut_assert_nextline("Name: mmc2.bootmethod");
+ ut_assert_nextline("Uclass: mmc");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_select, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootflow scan/list' commands */
+static int bootmethod_test_cmd_bootflow(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_assertok(run_command("bootmethod select 2", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow scan -l", 0));
+ ut_assert_nextline("Scanning for bootflows in bootmethod 'mmc0.bootmethod'");
+ ut_assert_nextline("Seq Type State Uclass Part Name Filename");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline(" 0 distro-boot loaded mmc 1 mmc0.bootmethod.part_1 extlinux/extlinux.conf");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(21 bootflows, 1 valid)");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootflow list", 0));
+ ut_assert_nextline("Showing bootflows for bootmethod 'mmc0.bootmethod'");
+ ut_assert_nextline("Seq Type State Uclass Part Name Filename");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline(" 0 distro-boot loaded mmc 1 mmc0.bootmethod.part_1 extlinux/extlinux.conf");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(1 bootflow, 1 valid)");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_bootflow, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootflow scan/list' commands using all bootmethods */
+static int bootmethod_test_cmd_bootflow_glob(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_assertok(run_command("bootflow scan -l", 0));
+ ut_assert_nextline("Scanning for bootflows in all bootmethods");
+ ut_assert_nextline("Seq Type State Uclass Part Name Filename");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("Scanning bootmethod 'mmc2.bootmethod':");
+ ut_assert_nextline("Scanning bootmethod 'mmc1.bootmethod':");
+ ut_assert_nextline("Scanning bootmethod 'mmc0.bootmethod':");
+ ut_assert_nextline(" 0 distro-boot loaded mmc 1 mmc0.bootmethod.part_1 extlinux/extlinux.conf");
+ ut_assert_nextline("No more bootmethods");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(1 bootflow, 1 valid)");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootflow list", 0));
+ ut_assert_nextline("Showing all bootflows");
+ ut_assert_nextline("Seq Type State Uclass Part Name Filename");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline(" 0 distro-boot loaded mmc 1 mmc0.bootmethod.part_1 extlinux/extlinux.conf");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(1 bootflow, 1 valid)");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_bootflow_glob,
+ UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootflow scan -e' */
+static int bootmethod_test_cmd_bootflow_scan_e(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_assertok(run_command("bootflow scan -ale", 0));
+ ut_assert_nextline("Scanning for bootflows in all bootmethods");
+ ut_assert_nextline("Seq Type State Uclass Part Name Filename");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("Scanning bootmethod 'mmc2.bootmethod':");
+ ut_assert_nextline(" 0 distro-boot media mmc 0 mmc2.bootmethod.part_1 <NULL>");
+ ut_assert_nextline(" ** No partition found, err=-93");
+ ut_assert_nextline(" 1 distro-boot media mmc 0 mmc2.bootmethod.part_2 <NULL>");
+
+ ut_assert_skip_to_line("Scanning bootmethod 'mmc1.bootmethod':");
+ ut_assert_skip_to_line("Scanning bootmethod 'mmc0.bootmethod':");
+ ut_assert_nextline(" 28 distro-boot loaded mmc 1 mmc0.bootmethod.part_1 extlinux/extlinux.conf");
+ ut_assert_nextline(" 29 distro-boot media mmc 0 mmc0.bootmethod.part_2 <NULL>");
+ ut_assert_skip_to_line(" 3b distro-boot media mmc 0 mmc0.bootmethod.part_14 <NULL>");
+ ut_assert_nextline(" ** No partition found, err=-2");
+ ut_assert_nextline("No more bootmethods");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(60 bootflows, 1 valid)");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootflow list", 0));
+ ut_assert_nextline("Showing all bootflows");
+ ut_assert_nextline("Seq Type State Uclass Part Name Filename");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline(" 0 distro-boot media mmc 0 mmc2.bootmethod.part_1 <NULL>");
+ ut_assert_skip_to_line(" 28 distro-boot loaded mmc 1 mmc0.bootmethod.part_1 extlinux/extlinux.conf");
+ ut_assert_skip_to_line(" 3b distro-boot media mmc 0 mmc0.bootmethod.part_14 <NULL>");
+ ut_assert_nextlinen("---");
+ ut_assert_nextline("(60 bootflows, 1 valid)");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_bootflow_scan_e,
+ UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootflow info' */
+static int bootmethod_test_cmd_bootflow_info(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_assertok(run_command("bootmethod select 2", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow scan", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow select 0", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow info", 0));
+ ut_assert_nextline("Name: mmc0.bootmethod.part_1");
+ ut_assert_nextline("Device: mmc0.bootmethod");
+ ut_assert_nextline("Block dev: mmc0.blk");
+ ut_assert_nextline("Sequence: 0");
+ ut_assert_nextline("Type: distro-boot");
+ ut_assert_nextline("State: loaded");
+ ut_assert_nextline("Partition: 1");
+ ut_assert_nextline("Subdir: (none)");
+ ut_assert_nextline("Filename: extlinux/extlinux.conf");
+ ut_assert_nextlinen("Buffer: ");
+ ut_assert_nextline("Size: 237 (567 bytes)");
+ ut_assert_nextline("Error: 0");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("bootflow info -d", 0));
+ ut_assert_nextline("Name: mmc0.bootmethod.part_1");
+ ut_assert_skip_to_line("Error: 0");
+ ut_assert_nextline("Contents:");
+ ut_assert_nextline("%s", "");
+ ut_assert_nextline("# extlinux.conf generated by appliance-creator");
+ ut_assert_skip_to_line("initrd /initramfs-5.3.7-301.fc31.armv7hl.img");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_bootflow_info,
+ UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootflow scan -b' to boot the first available bootmethod */
+static int bootmethod_test_cmd_bootflow_scan_boot(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_assertok(run_command("bootflow scan -b", 0));
+ ut_assert_nextline("** Booting bootflow 'mmc0.bootmethod.part_1'");
+ ut_assert_nextline("Ignoring unknown command: ui");
+
+ /*
+ * We expect it to get through to boot although sandbox always returns
+ * -EFAULT as it cannot actually boot the kernel
+ */
+ ut_assert_skip_to_line("sandbox: continuing, as we cannot run Linux");
+ ut_assert_nextline("Boot failed (err=-14)");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_bootflow_scan_boot,
+ UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootflow boot' to boot a selected bootflow */
+static int bootmethod_test_cmd_bootflow_boot(struct unit_test_state *uts)
+{
+ console_record_reset_enable();
+ ut_assertok(run_command("bootmethod select 2", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow scan", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow select 0", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow boot", 0));
+ ut_assert_nextline("** Booting bootflow 'mmc0.bootmethod.part_1'");
+ ut_assert_nextline("Ignoring unknown command: ui");
+
+ /*
+ * We expect it to get through to boot although sandbox always returns
+ * -EFAULT as it cannot actually boot the kernel
+ */
+ ut_assert_skip_to_line("sandbox: continuing, as we cannot run Linux");
+ ut_assert_nextline("Boot failed (err=-14)");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_cmd_bootflow_boot,
+ UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check we can get a bootmethod */
+static int bootmethod_test_get(struct unit_test_state *uts)
+{
+ struct bootmethod_iter iter;
+ struct bootflow bflow;
+
+ ut_assertok(bootmethod_scan_first_bootflow(&iter, 0, &bflow));
+
+ return 0;
+}
+BOOTMETHOD_TEST(bootmethod_test_get, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+int do_ut_bootmethod(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct unit_test *tests = UNIT_TEST_SUITE_START(bootmethod_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(bootmethod_test);
+
+ return cmd_ut_category("bootmethod", "bootmethod_test_",
+ tests, n_ents, argc, argv);
+}
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 90b260f72d6..c71f5575a04 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -28,6 +28,10 @@ int cmd_ut_category(const char *name, const char *prefix,
static struct cmd_tbl cmd_ut_sub[] = {
U_BOOT_CMD_MKENT(all, CONFIG_SYS_MAXARGS, 1, do_ut_all, "", ""),
+#ifdef CONFIG_BOOTMETHOD
+ U_BOOT_CMD_MKENT(bootmethod, CONFIG_SYS_MAXARGS, 1, do_ut_bootmethod,
+ "", ""),
+#endif
U_BOOT_CMD_MKENT(common, CONFIG_SYS_MAXARGS, 1, do_ut_common, "", ""),
#if defined(CONFIG_UT_DM)
U_BOOT_CMD_MKENT(dm, CONFIG_SYS_MAXARGS, 1, do_ut_dm, "", ""),
diff --git a/try.sh b/try.sh
new file mode 100755
index 00000000000..14519c3144c
--- /dev/null
+++ b/try.sh
@@ -0,0 +1,131 @@
+#!/bin/bash
+
+set -e
+
+file=mmc.img
+mnt=/mnt/x
+fat=/mnt/y
+dstdir=$fat/extlinux
+
+vmlinux=vmlinuz-5.3.7-301.fc31.armv7hl
+initrd=initramfs-5.3.7-301.fc31.armv7hl.img
+dtb=dtb-5.3.7-301.fc31.armv7hl/sandbox.dtb
+
+old() {
+ mkfs.vfat $file
+ sudo mount -o loop $file $mnt
+ #sudo cp /tmp/b/efi-x86_payload64/u-boot-payload.efi /mnt/x
+ #sudo cp /tmp/efi64/startup.nsh $mnt
+ #sudo cp /tmp/efi64/vmlinuz $mnt
+ echo >>/tmp/extlinux.conf <<EOF
+ui menu.c32
+
+menu autoboot Arch Boot. Automatic boot in # second{,s}. Press a key for options.
+menu title Arch Boot Options.
+menu hidden
+
+timeout 50
+
+default Arch
+
+label Arch
+ kernel /zImage
+ append root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait consoleblank=0 no_console_suspend=1 console=ttymxc0,115200n8
+ fdtdir /dtbs
+ initrd /initramfs-linux.img
+EOF
+ sudo cp /tmp/extlinux.conf $mnt
+ ls $mnt
+ sudo umount $mnt
+}
+
+
+fat_setup() {
+ echo 'type=c' | sudo sfdisk $file
+ #sudo kpartx -a $file
+ loop=$(sudo losetup --show -f -P $file)
+ echo "Mounted to $loop"
+ fatpart="${loop}p1"
+ sudo mkfs.vfat $fatpart
+ sudo mount -o loop ${fatpart} $fat
+}
+
+
+fat_finish() {
+ sudo mkdir -p $dstdir
+ sudo cp /tmp/extlinux.conf $dstdir
+
+ echo "vmlinux" | gzip >/tmp/inf
+ mkimage -f auto -d /tmp/inf /tmp/$vmlinux
+
+ sudo cp /tmp/$vmlinux $fat
+
+ echo "initd" >/tmp/$initrd
+ sudo cp /tmp/$initrd $fat
+
+ dtb_dir="$(dirname /tmp/$dtb)"
+ mkdir -p $dtb_dir
+ echo "/dts-v1/; / {};" | dtc >/tmp/$dtb
+ sudo cp -r $dtb_dir $fat
+
+ ls $dstdir
+
+ sudo umount $fat
+
+ losetup -d $loop
+}
+
+
+new() {
+ fat_setup
+ cat >/tmp/extlinux.conf << EOF
+ui menu.c32
+
+menu autoboot Arch Boot. Automatic boot in # second{,s}. Press a key for options.
+menu title Arch Boot Options.
+menu hidden
+
+timeout 50
+
+default Arch
+
+label Arch
+ kernel /zImage
+ append root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait consoleblank=0 no_console_suspend=1 console=ttymxc0,115200n8
+ fdtdir /dtbs
+ initrd /initramfs-linux.img
+EOF
+ fat_finish
+}
+
+
+fedora31() {
+ fat_setup
+ cat >/tmp/extlinux.conf << EOF
+# extlinux.conf generated by appliance-creator
+ui menu.c32
+menu autoboot Welcome to Fedora-Workstation-armhfp-31-1.9. Automatic boot in # second{,s}. Press a key for options.
+menu title Fedora-Workstation-armhfp-31-1.9 Boot Options.
+menu hidden
+timeout 20
+totaltimeout 600
+
+label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
+ kernel /$vmlinux
+ append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
+ fdtdir /dtb-5.3.7-301.fc31.armv7hl/
+ initrd /$initrd
+EOF
+ fat_finish
+}
+
+# Remove old devices
+for dev in $(losetup |grep $file | awk '{print $1}'); do
+ echo "Remove $dev"
+ losetup -d $dev
+done
+
+qemu-img create $file 20M
+#old
+#new
+fedora31
--
2.33.0.rc1.237.g0d66db33f3-goog
More information about the U-Boot
mailing list