summaryrefslogtreecommitdiff
path: root/test/py
diff options
context:
space:
mode:
Diffstat (limited to 'test/py')
-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
5 files changed, 115 insertions, 11 deletions
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}')