summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/boot/bootdev.c1
-rw-r--r--test/boot/bootflow.c5
-rw-r--r--test/dm/acpi.c59
-rw-r--r--test/py/conftest.py22
-rw-r--r--test/py/console_base.py25
-rw-r--r--test/py/pytest.ini1
-rw-r--r--test/py/tests/test_distro.py61
-rw-r--r--test/py/tests/test_ut.py17
8 files changed, 178 insertions, 13 deletions
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 5f07430714e..d5499918249 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -509,6 +509,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);
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index eb7f00af39a..5f9c037ff53 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);
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/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/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_ut.py b/test/py/tests/test_ut.py
index ea0c43cd4fc..b8adb597e11 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -57,6 +57,17 @@ def setup_image(ubman, devnum, part_type, img_size=20, second_part=False,
stdin=spec.encode('utf-8'))
return fname, mnt
+def copy_partition(ubman, fsfile, outname):
+ """Copy a partition into a disk iamge
+
+ Args:
+ ubman (ConsoleBase): U-Boot fixture
+ fsfile (str): Name of partition file
+ outname (str): Name of full-disk file to update
+ """
+ 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
@@ -172,7 +183,7 @@ 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}')
@@ -224,7 +235,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}')
@@ -562,7 +573,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}')