summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Kconfig2
-rw-r--r--test/boot/bootdev.c11
-rw-r--r--test/boot/bootflow.c12
-rw-r--r--test/boot/bootmeth.c47
-rw-r--r--test/boot/cedit.c22
-rw-r--r--test/boot/expo.c26
-rw-r--r--test/boot/files/expo_ids.h3
-rw-r--r--test/boot/files/expo_layout.dts5
-rw-r--r--test/cmd/Makefile3
-rw-r--r--test/cmd/cpuid.c22
-rw-r--r--test/cmd/font.c21
-rw-r--r--test/cmd/msr.c38
-rw-r--r--test/dm/Makefile2
-rw-r--r--test/py/conftest.py60
-rw-r--r--test/py/tests/test_sleep.py4
-rw-r--r--test/py/u_boot_console_base.py39
-rw-r--r--test/py/u_boot_spawn.py88
-rw-r--r--test/test-main.c28
18 files changed, 355 insertions, 78 deletions
diff --git a/test/Kconfig b/test/Kconfig
index e2ec0994a2e..558a9cd49b4 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -32,7 +32,7 @@ if UT_LIB
config UT_LIB_ASN1
bool "Unit test for asn1 compiler and decoder function"
- depends on SANDBOX
+ depends on SANDBOX && !MBEDTLS_LIB_X509
default y
imply ASYMMETRIC_KEY_TYPE
imply ASYMMETRIC_PUBLIC_KEY_SUBTYPE
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index c635d06ec25..369105ca4cf 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -128,6 +128,7 @@ BOOTSTD_TEST(bootdev_test_labels, UTF_DM | UTF_SCAN_FDT | UTF_ETH_BOOTDEV);
static int bootdev_test_any(struct unit_test_state *uts)
{
struct udevice *dev, *media;
+ char *seq;
int mflags;
/*
@@ -147,8 +148,16 @@ static int bootdev_test_any(struct unit_test_state *uts)
* 8 [ ] OK mmc mmc2.bootdev
* 9 [ + ] OK mmc mmc1.bootdev
* a [ ] OK mmc mmc0.bootdev
+ *
+ * However if DSA_SANDBOX is disabled the dsa-test@{0,1} devices
+ * are not there.
*/
- ut_assertok(bootdev_find_by_any("8", &dev, &mflags));
+ if (CONFIG_IS_ENABLED(DSA_SANDBOX))
+ seq = "8";
+ else
+ seq = "6";
+
+ ut_assertok(bootdev_find_by_any(seq, &dev, &mflags));
ut_asserteq(UCLASS_BOOTDEV, device_get_uclass_id(dev));
ut_asserteq(BOOTFLOW_METHF_SINGLE_DEV, mflags);
media = dev_get_parent(dev);
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 6ad63afe90a..154dea70a59 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -109,9 +109,17 @@ static int bootflow_cmd_label(struct unit_test_state *uts)
* 8 [ ] OK mmc mmc2.bootdev
* 9 [ + ] OK mmc mmc1.bootdev
* a [ ] OK mmc mmc0.bootdev
+ *
+ * However with CONFIG_DSA_SANDBOX=n we have two fewer (dsa-test@0 and
+ * dsa-test@1).
*/
- ut_assertok(run_command("bootflow scan -lH 9", 0));
- ut_assert_nextline("Scanning for bootflows with label '9'");
+ if (CONFIG_IS_ENABLED(DSA_SANDBOX)) {
+ ut_assertok(run_command("bootflow scan -lH 9", 0));
+ ut_assert_nextline("Scanning for bootflows with label '9'");
+ } else {
+ ut_assertok(run_command("bootflow scan -lH 7", 0));
+ ut_assert_nextline("Scanning for bootflows with label '7'");
+ }
ut_assert_skip_to_line("(1 bootflow, 1 valid)");
ut_assertok(run_command("bootflow scan -lH 0", 0));
diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c
index 518d99c4a27..18ae6d7fe13 100644
--- a/test/boot/bootmeth.c
+++ b/test/boot/bootmeth.c
@@ -127,6 +127,53 @@ static int bootmeth_cmd_order_glob(struct unit_test_state *uts)
}
BOOTSTD_TEST(bootmeth_cmd_order_glob, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
+/* Check 'bootmeth set' command */
+static int bootmeth_cmd_set(struct unit_test_state *uts)
+{
+ /* Check we can enable extlinux fallback */
+ console_record_reset_enable();
+ ut_assertok(run_command("bootmeth set extlinux fallback 1", 0));
+ ut_assert_console_end();
+
+ /* Check we can disable extlinux fallback */
+ console_record_reset_enable();
+ ut_assertok(run_command("bootmeth set extlinux fallback 0", 0));
+ ut_assert_console_end();
+
+ /* Check extlinux fallback unexpected value */
+ console_record_reset_enable();
+ ut_asserteq(1, run_command("bootmeth set extlinux fallback fred", 0));
+ ut_assert_nextline("Unexpected value 'fred'");
+ ut_assert_nextline("Failed (err=-22)");
+ ut_assert_console_end();
+
+ /* Check that we need to provide right number of parameters */
+ ut_asserteq(1, run_command("bootmeth set extlinux fallback", 0));
+ ut_assert_nextline("Required parameters not provided");
+ ut_assert_console_end();
+
+ /* Check that we need to provide a valid bootmethod */
+ ut_asserteq(1, run_command("bootmeth set fred fallback 0", 0));
+ ut_assert_nextline("Unknown bootmeth 'fred'");
+ ut_assert_nextline("Failed (err=-19)");
+ ut_assert_console_end();
+
+ /* Check that we need to provide a valid property */
+ ut_asserteq(1, run_command("bootmeth set extlinux fred 0", 0));
+ ut_assert_nextline("Invalid option");
+ ut_assert_nextline("Failed (err=-22)");
+ ut_assert_console_end();
+
+ /* Check that we need to provide a bootmeth that supports properties */
+ ut_asserteq(1, run_command("bootmeth set efi fallback 0", 0));
+ ut_assert_nextline("set_property not found");
+ ut_assert_nextline("Failed (err=-19)");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTSTD_TEST(bootmeth_cmd_set, UTF_DM | UTF_SCAN_FDT);
+
/* Check 'bootmeths' env var */
static int bootmeth_env(struct unit_test_state *uts)
{
diff --git a/test/boot/cedit.c b/test/boot/cedit.c
index 1f7af8e5d79..4d1b99bc2ea 100644
--- a/test/boot/cedit.c
+++ b/test/boot/cedit.c
@@ -31,9 +31,11 @@ static int cedit_base(struct unit_test_state *uts)
* ^N Move down to second item
* ^M Select item
* \e Quit
+ *
+ * cedit_run() returns -EACCESS so this command returns CMD_RET_FAILURE
*/
console_in_puts("\x0e\x0d\x0e\x0d\e");
- ut_assertok(run_command("cedit run", 0));
+ ut_asserteq(1, run_command("cedit run", 0));
exp = cur_exp;
scn = expo_lookup_scene_id(exp, exp->scene_id);
@@ -94,14 +96,16 @@ static int cedit_fdt(struct unit_test_state *uts)
ut_asserteq(ID_CPU_SPEED_2,
ofnode_read_u32_default(node, "cpu-speed", 0));
+ ut_asserteq(3,
+ ofnode_read_u32_default(node, "cpu-speed-value", 0));
ut_asserteq_str("2.5 GHz", ofnode_read_string(node, "cpu-speed-str"));
ut_asserteq_str("my-machine", ofnode_read_string(node, "machine-name"));
- /* There should only be 5 properties */
+ /* There should only be 7 properties */
for (i = 0, ofnode_first_property(node, &prop); ofprop_valid(&prop);
i++, ofnode_next_property(&prop))
;
- ut_asserteq(5, i);
+ ut_asserteq(7, i);
ut_assert_console_end();
@@ -147,14 +151,16 @@ static int cedit_env(struct unit_test_state *uts)
strcpy(str, "my-machine");
ut_assertok(run_command("cedit write_env -v", 0));
- ut_assert_nextlinen("c.cpu-speed=7");
+ ut_assert_nextlinen("c.cpu-speed=11");
ut_assert_nextlinen("c.cpu-speed-str=2.5 GHz");
- ut_assert_nextlinen("c.power-loss=10");
+ ut_assert_nextlinen("c.cpu-speed-value=3");
+ ut_assert_nextlinen("c.power-loss=14");
ut_assert_nextlinen("c.power-loss-str=Always Off");
+ ut_assert_nextlinen("c.power-loss-value=0");
ut_assert_nextlinen("c.machine-name=my-machine");
ut_assert_console_end();
- ut_asserteq(7, env_get_ulong("c.cpu-speed", 10, 0));
+ ut_asserteq(11, env_get_ulong("c.cpu-speed", 10, 0));
ut_asserteq_str("2.5 GHz", env_get("c.cpu-speed-str"));
ut_asserteq_str("my-machine", env_get("c.machine-name"));
@@ -163,8 +169,8 @@ static int cedit_env(struct unit_test_state *uts)
*str = '\0';
ut_assertok(run_command("cedit read_env -v", 0));
- ut_assert_nextlinen("c.cpu-speed=7");
- ut_assert_nextlinen("c.power-loss=10");
+ ut_assert_nextlinen("c.cpu-speed=11");
+ ut_assert_nextlinen("c.power-loss=14");
ut_assert_nextlinen("c.machine-name=my-machine");
ut_assert_console_end();
diff --git a/test/boot/expo.c b/test/boot/expo.c
index 9b4aa803eb1..db14ff86f8b 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -91,7 +91,7 @@ static int expo_base(struct unit_test_state *uts)
*name = '\0';
ut_assertnonnull(exp);
ut_asserteq(0, exp->scene_id);
- ut_asserteq(0, exp->next_id);
+ ut_asserteq(EXPOID_BASE_ID, exp->next_id);
/* Make sure the name was allocated */
ut_assertnonnull(exp->name);
@@ -130,7 +130,7 @@ static int expo_scene(struct unit_test_state *uts)
ut_assertok(expo_new(EXPO_NAME, NULL, &exp));
scn = NULL;
- ut_asserteq(0, exp->next_id);
+ ut_asserteq(EXPOID_BASE_ID, exp->next_id);
strcpy(name, SCENE_NAME1);
id = scene_new(exp, name, SCENE1, &scn);
*name = '\0';
@@ -151,7 +151,7 @@ static int expo_scene(struct unit_test_state *uts)
scn = NULL;
id = scene_new(exp, SCENE_NAME2, 0, &scn);
ut_assertnonnull(scn);
- ut_assertok(scene_title_set(scn, title_id));
+ scn->title_id = title_id;
ut_asserteq(STR_SCENE_TITLE + 1, id);
ut_asserteq(STR_SCENE_TITLE + 2, exp->next_id);
ut_asserteq_ptr(exp, scn->expo);
@@ -167,6 +167,25 @@ static int expo_scene(struct unit_test_state *uts)
}
BOOTSTD_TEST(expo_scene, UTF_DM | UTF_SCAN_FDT);
+/* Check creating a scene with no ID */
+static int expo_scene_no_id(struct unit_test_state *uts)
+{
+ struct scene *scn;
+ struct expo *exp;
+ char name[100];
+ int id;
+
+ ut_assertok(expo_new(EXPO_NAME, NULL, &exp));
+ ut_asserteq(EXPOID_BASE_ID, exp->next_id);
+
+ strcpy(name, SCENE_NAME1);
+ id = scene_new(exp, SCENE_NAME1, 0, &scn);
+ ut_asserteq(EXPOID_BASE_ID, scn->id);
+
+ return 0;
+}
+BOOTSTD_TEST(expo_scene_no_id, UTF_DM | UTF_SCAN_FDT);
+
/* Check creating a scene with objects */
static int expo_object(struct unit_test_state *uts)
{
@@ -698,6 +717,7 @@ static int expo_test_build(struct unit_test_state *uts)
ut_asserteq(0, item->desc_id);
ut_asserteq(0, item->preview_id);
ut_asserteq(0, item->flags);
+ ut_asserteq(0, item->value);
txt = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE);
ut_asserteq_str("2 GHz", expo_get_str(exp, txt->str_id));
diff --git a/test/boot/files/expo_ids.h b/test/boot/files/expo_ids.h
index a86e0d06f6b..ffb511364b1 100644
--- a/test/boot/files/expo_ids.h
+++ b/test/boot/files/expo_ids.h
@@ -4,8 +4,7 @@
*/
enum {
- ZERO,
- ID_PROMPT,
+ ID_PROMPT = EXPOID_BASE_ID,
ID_SCENE1,
ID_SCENE1_TITLE,
diff --git a/test/boot/files/expo_layout.dts b/test/boot/files/expo_layout.dts
index bed552288f4..9bc1e4950b9 100644
--- a/test/boot/files/expo_layout.dts
+++ b/test/boot/files/expo_layout.dts
@@ -39,8 +39,11 @@
item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+ /* values for the menu items */
+ item-value = <0 3 6>;
+
start-bit = <0x400>;
- bit-length = <2>;
+ bit-length = <3>;
};
power-loss {
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index 8f2134998ad..40808350962 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -12,6 +12,7 @@ ifdef CONFIG_CONSOLE_RECORD
obj-$(CONFIG_CMD_PAUSE) += test_pause.o
endif
obj-y += exit.o mem.o
+obj-$(CONFIG_X86) += cpuid.o msr.o
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_FDT) += fdt.o
@@ -30,7 +31,9 @@ ifdef CONFIG_SANDBOX
obj-$(CONFIG_CMD_MBR) += mbr.o
obj-$(CONFIG_CMD_READ) += rw.o
obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
+ifdef CONFIG_NET
obj-$(CONFIG_CMD_WGET) += wget.o
+endif
obj-$(CONFIG_ARM_FFA_TRANSPORT) += armffa.o
endif
obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o
diff --git a/test/cmd/cpuid.c b/test/cmd/cpuid.c
new file mode 100644
index 00000000000..e07f5fd4696
--- /dev/null
+++ b/test/cmd/cpuid.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for cpuid command
+ *
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <test/cmd.h>
+#include <test/ut.h>
+
+static int cmd_test_cpuid(struct unit_test_state *uts)
+{
+ ut_assertok(run_commandf("cpuid 1"));
+ ut_assert_nextline("eax 00060fb1");
+ ut_assert_nextline("ebx 00000800");
+ ut_assert_nextline("ecx 80002001");
+ ut_assert_nextline("edx 078bfbfd");
+
+ return 0;
+}
+CMD_TEST(cmd_test_cpuid, UTF_CONSOLE);
diff --git a/test/cmd/font.c b/test/cmd/font.c
index 25d365dedd2..3335dd65bea 100644
--- a/test/cmd/font.c
+++ b/test/cmd/font.c
@@ -27,14 +27,20 @@ static int font_test_base(struct unit_test_state *uts)
ut_assertok(uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev));
ut_assertok(run_command("font list", 0));
- ut_assert_nextline("nimbus_sans_l_regular");
+ if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_NIMBUS))
+ ut_assert_nextline("nimbus_sans_l_regular");
+ if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER))
+ ut_assert_nextline("ankacoder_c75_r");
if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_CANTORAONE))
ut_assert_nextline("cantoraone_regular");
ut_assert_console_end();
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
- ut_asserteq_str("nimbus_sans_l_regular", name);
- ut_asserteq(18, size);
+ if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER))
+ ut_asserteq_str("ankacoder_c75_r", name);
+ else
+ ut_asserteq_str("nimbus_sans_l_regular", name);
+ ut_asserteq(CONFIG_CONSOLE_TRUETYPE_SIZE, size);
if (!IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_CANTORAONE))
return 0;
@@ -58,10 +64,19 @@ static int font_test_base(struct unit_test_state *uts)
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
ut_asserteq_str("cantoraone_regular", name);
ut_asserteq(40, size);
+ ut_assertok(ut_check_console_end(uts));
+
+ ut_assertok(run_command("font size", 0));
+ ut_assert_nextline("40");
+ ut_assertok(ut_check_console_end(uts));
ut_assertok(run_command("font size 30", 0));
ut_assert_console_end();
+ ut_assertok(run_command("font size", 0));
+ ut_assert_nextline("30");
+ ut_assertok(ut_check_console_end(uts));
+
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
ut_asserteq_str("cantoraone_regular", name);
ut_asserteq(30, size);
diff --git a/test/cmd/msr.c b/test/cmd/msr.c
new file mode 100644
index 00000000000..e9a152ee5bf
--- /dev/null
+++ b/test/cmd/msr.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for msr command
+ *
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <test/cmd.h>
+#include <test/ut.h>
+
+static int cmd_test_msr(struct unit_test_state *uts)
+{
+ ut_assertok(run_commandf("msr read 200"));
+ ut_assert_nextline("00000000 ffe00006");
+ ut_assert_console_end();
+
+ /* change the first variable msr and see it reflected in the mtrr cmd */
+ ut_assertok(run_commandf("mtrr"));
+ ut_assert_nextline("CPU 65537:");
+ ut_assert_nextlinen("Reg");
+ ut_assert_nextlinen("0 Y Back 00000000ffe00000");
+ ut_assertok(console_record_reset_enable());
+
+ /* change the type from 6 to 5 */
+ ut_assertok(run_commandf("msr write 200 0 ffe00005"));
+ ut_assert_console_end();
+
+ /* Now it shows 'Protect' */
+ ut_assertok(run_commandf("mtrr"));
+ ut_assert_nextline("CPU 65537:");
+ ut_assert_nextlinen("Reg");
+ ut_assert_nextlinen("0 Y Protect 00000000ffe00000");
+ ut_assertok(console_record_reset_enable());
+
+ return 0;
+}
+CMD_TEST(cmd_test_msr, UTF_CONSOLE);
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 6c9ebb8d07c..bcb52ef1067 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -48,7 +48,9 @@ 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/py/conftest.py b/test/py/conftest.py
index fc9dd3a83f8..46a410cf268 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -24,6 +24,7 @@ import pytest
import re
from _pytest.runner import runtestprotocol
import sys
+from u_boot_spawn import BootFail, Timeout, Unexpected, handle_exception
# Globals: The HTML log file, and the connection to the U-Boot console.
log = None
@@ -115,14 +116,36 @@ def run_build(config, source_dir, build_dir, board_type, log):
runner.close()
log.status_pass('OK')
-def pytest_xdist_setupnodes(config, specs):
- """Clear out any 'done' file from a previous build"""
- global build_done_file
- build_dir = config.getoption('build_dir')
+def get_details(config):
+ """Obtain salient details about the board and directories to use
+
+ Args:
+ config (pytest.Config): pytest configuration
+
+ Returns:
+ tuple:
+ str: Board type (U-Boot build name)
+ str: Identity for the lab board
+ str: Build directory
+ str: Source directory
+ """
board_type = config.getoption('board_type')
+ board_identity = config.getoption('board_identity')
+ build_dir = config.getoption('build_dir')
+
source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR))
+ default_build_dir = source_dir + '/build-' + board_type
if not build_dir:
- build_dir = source_dir + '/build-' + board_type
+ build_dir = default_build_dir
+
+ return board_type, board_identity, build_dir, source_dir
+
+def pytest_xdist_setupnodes(config, specs):
+ """Clear out any 'done' file from a previous build"""
+ global build_done_file
+
+ build_dir = get_details(config)[2]
+
build_done_file = Path(build_dir) / 'build.done'
if build_done_file.exists():
os.remove(build_done_file)
@@ -161,17 +184,10 @@ def pytest_configure(config):
global console
global ubconfig
- source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR))
+ board_type, board_identity, build_dir, source_dir = get_details(config)
- board_type = config.getoption('board_type')
board_type_filename = board_type.replace('-', '_')
-
- board_identity = config.getoption('board_identity')
board_identity_filename = board_identity.replace('-', '_')
-
- build_dir = config.getoption('build_dir')
- if not build_dir:
- build_dir = source_dir + '/build-' + board_type
mkdir_p(build_dir)
result_dir = config.getoption('result_dir')
@@ -239,6 +255,7 @@ def pytest_configure(config):
ubconfig.board_identity = board_identity
ubconfig.gdbserver = gdbserver
ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb'
+ ubconfig.connection_ok = True
env_vars = (
'board_type',
@@ -405,8 +422,21 @@ def u_boot_console(request):
Returns:
The fixture value.
"""
-
- console.ensure_spawned()
+ if not ubconfig.connection_ok:
+ pytest.skip('Cannot get target connection')
+ return None
+ try:
+ console.ensure_spawned()
+ except OSError as err:
+ handle_exception(ubconfig, console, log, err, 'Lab failure', True)
+ except Timeout as err:
+ handle_exception(ubconfig, console, log, err, 'Lab timeout', True)
+ except BootFail as err:
+ handle_exception(ubconfig, console, log, err, 'Boot fail', True,
+ console.get_spawn_output())
+ except Unexpected:
+ handle_exception(ubconfig, console, log, err, 'Unexpected test output',
+ False)
return console
anchors = {}
diff --git a/test/py/tests/test_sleep.py b/test/py/tests/test_sleep.py
index 66a57434bff..8965fc3fea9 100644
--- a/test/py/tests/test_sleep.py
+++ b/test/py/tests/test_sleep.py
@@ -27,7 +27,7 @@ def test_sleep(u_boot_console):
if not sleep_skip:
pytest.skip('sleep is not accurate')
- if u_boot_console.config.buildconfig.get('config_cmd_misc', 'n') != 'y':
+ if u_boot_console.config.buildconfig.get('config_cmd_sleep', 'n') != 'y':
pytest.skip('sleep command not supported')
# 3s isn't too long, but is enough to cross a few second boundaries.
@@ -42,7 +42,7 @@ def test_sleep(u_boot_console):
# margin is hopefully enough to account for any system overhead.
assert elapsed < (sleep_time + sleep_margin)
-@pytest.mark.buildconfigspec("cmd_misc")
+@pytest.mark.buildconfigspec("cmd_time")
def test_time(u_boot_console):
"""Test the time command, and validate that it gives approximately the
correct amount of command execution time."""
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index 76a550d45a1..d8d0bdf9fd4 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -14,6 +14,7 @@ import pytest
import re
import sys
import u_boot_spawn
+from u_boot_spawn import BootFail, Timeout, Unexpected, handle_exception
# Regexes for text we expect U-Boot to send to the console.
pattern_u_boot_spl_signon = re.compile('(U-Boot SPL \\d{4}\\.\\d{2}[^\r\n]*\\))')
@@ -26,6 +27,9 @@ pattern_error_please_reset = re.compile('### ERROR ### Please RESET the board ##
PAT_ID = 0
PAT_RE = 1
+# Timeout before expecting the console to be ready (in milliseconds)
+TIMEOUT_MS = 30000
+
bad_pattern_defs = (
('spl_signon', pattern_u_boot_spl_signon),
('main_signon', pattern_u_boot_main_signon),
@@ -109,7 +113,7 @@ class ConsoleBase(object):
Can only usefully be called by sub-classes.
Args:
- log: A mulptiplex_log.Logfile object, to which the U-Boot output
+ log: A multiplexed_log.Logfile object, to which the U-Boot output
will be logged.
config: A configuration data structure, as built by conftest.py.
max_fifo_fill: The maximum number of characters to send to U-Boot
@@ -186,13 +190,13 @@ class ConsoleBase(object):
m = self.p.expect([pattern_u_boot_spl_signon] +
self.bad_patterns)
if m != 0:
- raise Exception('Bad pattern found on SPL console: ' +
+ raise BootFail('Bad pattern found on SPL console: ' +
self.bad_pattern_ids[m - 1])
env_spl_banner_times -= 1
m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
if m != 0:
- raise Exception('Bad pattern found on console: ' +
+ raise BootFail('Bad pattern found on console: ' +
self.bad_pattern_ids[m - 1])
self.u_boot_version_string = self.p.after
while True:
@@ -203,13 +207,9 @@ class ConsoleBase(object):
if m == 1:
self.p.send(' ')
continue
- raise Exception('Bad pattern found on console: ' +
+ raise BootFail('Bad pattern found on console: ' +
self.bad_pattern_ids[m - 2])
- except Exception as ex:
- self.log.error(str(ex))
- self.cleanup_spawn()
- raise
finally:
self.log.timestamp()
@@ -275,7 +275,7 @@ class ConsoleBase(object):
m = self.p.expect([chunk] + self.bad_patterns)
if m != 0:
self.at_prompt = False
- raise Exception('Bad pattern found on console: ' +
+ raise BootFail('Bad pattern found on console: ' +
self.bad_pattern_ids[m - 1])
if not wait_for_prompt:
return
@@ -285,16 +285,20 @@ class ConsoleBase(object):
m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
if m != 0:
self.at_prompt = False
- raise Exception('Bad pattern found on console: ' +
+ raise BootFail('Missing prompt on console: ' +
self.bad_pattern_ids[m - 1])
self.at_prompt = True
self.at_prompt_logevt = self.logstream.logfile.cur_evt
# Only strip \r\n; space/TAB might be significant if testing
# indentation.
return self.p.before.strip('\r\n')
- except Exception as ex:
- self.log.error(str(ex))
- self.cleanup_spawn()
+ except Timeout as exc:
+ handle_exception(self.config, self, self.log, exc, 'Lab failure',
+ True)
+ raise
+ except BootFail as exc:
+ handle_exception(self.config, self, self.log, exc, 'Boot fail',
+ True, self.get_spawn_output())
raise
finally:
self.log.timestamp()
@@ -351,8 +355,9 @@ class ConsoleBase(object):
text = re.escape(text)
m = self.p.expect([text] + self.bad_patterns)
if m != 0:
- raise Exception('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 1])
+ raise Unexpected(
+ "Unexpected pattern found on console (exp '{text}': " +
+ self.bad_pattern_ids[m - 1])
def drain_console(self):
"""Read from and log the U-Boot console for a short time.
@@ -422,7 +427,7 @@ class ConsoleBase(object):
# Reset the console timeout value as some tests may change
# its default value during the execution
if not self.config.gdbserver:
- self.p.timeout = 30000
+ self.p.timeout = TIMEOUT_MS
return
try:
self.log.start_section('Starting U-Boot')
@@ -433,7 +438,7 @@ class ConsoleBase(object):
# future, possibly per-test to be optimal. This works for 'help'
# on board 'seaboard'.
if not self.config.gdbserver:
- self.p.timeout = 30000
+ self.p.timeout = TIMEOUT_MS
self.p.logfile_read = self.logstream
if expect_reset:
loop_num = 2
diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py
index 97e95e07c80..24d369035e5 100644
--- a/test/py/u_boot_spawn.py
+++ b/test/py/u_boot_spawn.py
@@ -8,6 +8,7 @@ Logic to spawn a sub-process and interact with its stdio.
import os
import re
import pty
+import pytest
import signal
import select
import time
@@ -16,6 +17,54 @@ import traceback
class Timeout(Exception):
"""An exception sub-class that indicates that a timeout occurred."""
+class BootFail(Exception):
+ """An exception sub-class that indicates that a boot failure occurred.
+
+ This is used when a bad pattern is seen when waiting for the boot prompt.
+ It is regarded as fatal, to avoid trying to boot the again and again to no
+ avail.
+ """
+
+class Unexpected(Exception):
+ """An exception sub-class that indicates that unexpected test was seen."""
+
+
+def handle_exception(ubconfig, console, log, err, name, fatal, output=''):
+ """Handle an exception from the console
+
+ Exceptions can occur when there is unexpected output or due to the board
+ crashing or hanging. Some exceptions are likely fatal, where retrying will
+ just chew up time to no available. In those cases it is best to cause
+ further tests be skipped.
+
+ Args:
+ ubconfig (ArbitraryAttributeContainer): ubconfig object
+ log (Logfile): Place to log errors
+ console (ConsoleBase): Console to clean up, if fatal
+ err (Exception): Exception which was thrown
+ name (str): Name of problem, to log
+ fatal (bool): True to abort all tests
+ output (str): Extra output to report on boot failure. This can show the
+ target's console output as it tried to boot
+ """
+ msg = f'{name}: '
+ if fatal:
+ msg += 'Marking connection bad - no other tests will run'
+ else:
+ msg += 'Assuming that lab is healthy'
+ print(msg)
+ log.error(msg)
+ log.error(f'Error: {err}')
+
+ if output:
+ msg += f'; output {output}'
+
+ if fatal:
+ ubconfig.connection_ok = False
+ console.cleanup_spawn()
+ pytest.exit(msg)
+
+
class Spawn:
"""Represents the stdio of a freshly created sub-process. Commands may be
sent to the process, and responses waited for.
@@ -137,6 +186,32 @@ class Spawn:
os.write(self.fd, data.encode(errors='replace'))
+ def receive(self, num_bytes):
+ """Receive data from the sub-process's stdin.
+
+ Args:
+ num_bytes (int): Maximum number of bytes to read
+
+ Returns:
+ str: The data received
+
+ Raises:
+ ValueError if U-Boot died
+ """
+ try:
+ c = os.read(self.fd, num_bytes).decode(errors='replace')
+ except OSError as err:
+ # With sandbox, try to detect when U-Boot exits when it
+ # shouldn't and explain why. This is much more friendly than
+ # just dying with an I/O error
+ if self.decode_signal and err.errno == 5: # I/O error
+ alive, _, info = self.checkalive()
+ if alive:
+ raise err
+ raise ValueError('U-Boot exited with %s' % info)
+ raise
+ return c
+
def expect(self, patterns):
"""Wait for the sub-process to emit specific data.
@@ -193,18 +268,7 @@ class Spawn:
events = self.poll.poll(poll_maxwait)
if not events:
raise Timeout()
- try:
- c = os.read(self.fd, 1024).decode(errors='replace')
- except OSError as err:
- # With sandbox, try to detect when U-Boot exits when it
- # shouldn't and explain why. This is much more friendly than
- # just dying with an I/O error
- if self.decode_signal and err.errno == 5: # I/O error
- alive, _, info = self.checkalive()
- if alive:
- raise err
- raise ValueError('U-Boot exited with %s' % info)
- raise
+ c = self.receive(1024)
if self.logfile_read:
self.logfile_read.write(c)
self.buf += c
diff --git a/test/test-main.c b/test/test-main.c
index 479dbb33b72..da5b07ce00b 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -294,27 +294,27 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
* Remove any USB keyboard, so that we can add and remove USB devices
* in tests.
*
- * For UT_TESTF_DM tests, the old driver model state is saved and
+ * For UTF_DM tests, the old driver model state is saved and
* restored across each test. Within in each test there is therefore a
* new driver model state, which means that any USB keyboard device in
* stdio points to the old state.
*
- * This is fine in most cases. But if a non-UT_TESTF_DM test starts up
+ * This is fine in most cases. But if a non-UTF_DM test starts up
* USB (thus creating a stdio record pointing to the USB keyboard
* device) then when the test finishes, the new driver model state is
* freed, meaning that there is now a stale pointer in stdio.
*
- * This means that any future UT_TESTF_DM test which uses stdin will
+ * This means that any future UTF_DM test which uses stdin will
* cause the console system to call tstc() on the stale device pointer,
* causing a crash.
*
- * We don't want to fix this by enabling UT_TESTF_DM for all tests as
+ * We don't want to fix this by enabling UTF_DM for all tests as
* this causes other problems. For example, bootflow_efi relies on
* U-Boot going through a proper init - without that we don't have the
* TCG measurement working and get an error
* 'tcg2 measurement fails(0x8000000000000007)'. Once we tidy up how EFI
* runs tests (e.g. get rid of all the restarting of U-Boot) we could
- * potentially make the bootstd tests set UT_TESTF_DM, but other tests
+ * potentially make the bootstd tests set UTF_DM, but other tests
* might do the same thing.
*
* We could add a test flag to declare that USB is being used, but that
@@ -323,7 +323,7 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
* pointers always.
*
* So just remove any USB keyboards from the console tables. This allows
- * UT_TESTF_DM and non-UT_TESTF_DM tests to coexist happily.
+ * UTF_DM and non-UTF_DM tests to coexist happily.
*/
usb_kbd_remove_for_test();
@@ -486,7 +486,7 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test,
static int ut_run_test_live_flat(struct unit_test_state *uts,
struct unit_test *test)
{
- int runs;
+ int runs, ret;
if ((test->flags & UTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX))
return skip_test(uts);
@@ -496,8 +496,11 @@ static int ut_run_test_live_flat(struct unit_test_state *uts,
if (CONFIG_IS_ENABLED(OF_LIVE)) {
if (!(test->flags & UTF_FLAT_TREE)) {
uts->of_live = true;
- ut_assertok(ut_run_test(uts, test, test->name));
- runs++;
+ ret = ut_run_test(uts, test, test->name);
+ if (ret != -EAGAIN) {
+ ut_assertok(ret);
+ runs++;
+ }
}
}
@@ -521,8 +524,11 @@ static int ut_run_test_live_flat(struct unit_test_state *uts,
(!runs || ut_test_run_on_flattree(test)) &&
!(gd->flags & GD_FLG_FDT_CHANGED)) {
uts->of_live = false;
- ut_assertok(ut_run_test(uts, test, test->name));
- runs++;
+ ret = ut_run_test(uts, test, test->name);
+ if (ret != -EAGAIN) {
+ ut_assertok(ret);
+ runs++;
+ }
}
return 0;