summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2025-04-08 13:54:50 -0600
committerTom Rini <trini@konsulko.com>2025-04-08 13:54:50 -0600
commita30b54462825843a9dcc46a17df6d57099f7b61a (patch)
tree597b4d3d3c60a6dc05d8386e934b079e66226045
parentd4c3359570a698679058fc4e7d422bfa108fcbfb (diff)
parenteb1b90ec57a43ff4799d9626a1481acd01a4adb4 (diff)
Merge patch series "Improve pytest runtime"
Tom Rini <trini@konsulko.com> says: One thing that Simon Glass has noted is that our pytest run time keeps getting longer. Looking at: https://source.denx.de/u-boot/u-boot/-/pipelines/25011/test_report?job_name=sandbox%20test.py%3A%20%5Bfast%20amd64%5D we can see that some of the longest running tests are a little puzzling. It turns out that we have two ways of making filesystem images without requiring root access and one of them is significantly slower than the other. This series changes us from using virt-make-fs to only using the mk_fs helper that currently resides in test_ut.py which uses standard userspace tools. The final result can be seen at: https://source.denx.de/u-boot/u-boot/-/pipelines/25015/test_report?job_name=sandbox%20test.py%3A%20%5Bfast%20amd64%5D and the tests changed here now run much quicker. Link: https://lore.kernel.org/r/20250320140030.2052434-1-trini@konsulko.com
-rw-r--r--doc/develop/py_testing.rst25
-rw-r--r--test/py/tests/fs_helper.py34
-rw-r--r--test/py/tests/test_cat.py37
-rw-r--r--test/py/tests/test_cat/conftest.py36
-rw-r--r--test/py/tests/test_cat/test_cat.py20
-rw-r--r--test/py/tests/test_efi_bootmgr.py70
-rw-r--r--test/py/tests/test_efi_bootmgr/conftest.py38
-rw-r--r--test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py44
-rw-r--r--test/py/tests/test_efi_capsule/capsule_common.py2
-rw-r--r--test/py/tests/test_efi_capsule/conftest.py45
-rw-r--r--test/py/tests/test_efi_secboot/conftest.py52
-rw-r--r--test/py/tests/test_eficonfig.py (renamed from test/py/tests/test_eficonfig/test_eficonfig.py)53
-rw-r--r--test/py/tests/test_eficonfig/conftest.py40
-rw-r--r--test/py/tests/test_ut.py38
-rw-r--r--test/py/tests/test_xxd.py40
-rw-r--r--test/py/tests/test_xxd/conftest.py36
-rw-r--r--test/py/tests/test_xxd/test_xxd.py23
-rw-r--r--tools/docker/Dockerfile5
18 files changed, 288 insertions, 350 deletions
diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst
index 40a85380343..502053f09fc 100644
--- a/doc/develop/py_testing.rst
+++ b/doc/develop/py_testing.rst
@@ -41,13 +41,11 @@ will be required. The following is an incomplete list:
* dfu-util
* dtc
* openssl
-* sudo OR guestmount
* e2fsprogs
* util-linux
* coreutils
* dosfstools
* efitools
-* guestfs-tools
* mount
* mtools
* sbsigntool
@@ -64,23 +62,12 @@ The test script supports either:
physical board, attach to the board's console stream, and reset the board.
Further details are described later.
-The usage of command 'sudo' should be avoided in tests. To create disk images
-use command virt-make-fs which is provided by package guestfs-tools. This
-command creates a virtual machine with QEMU in which the disk image is
-generated.
-
-Command virt-make-fs needs read access to the current kernel. On Ubuntu only
-root has this privilege. You can add a script /etc/initramfs-tools/hooks/vmlinuz
-with the following content to overcome the problem:
-
-.. code-block:: bash
-
- #!/bin/sh
- echo "chmod a+r vmlinuz-*"
- chmod a+r /boot/vmlinuz-*
-
-The script should be chmod 755. It will be invoked whenever the initial RAM file
-system is updated.
+The usage of the command 'sudo' is not allowed in tests. Using elevated
+priviledges can lead to security concerns. Furthermore not all users may have
+administrator rights. Therefore the command 'sudo' must not be used in tests.
+To create disk images we have helper functions located in
+`test/py/tests/fs_helper.py` which shall be used in any tests that require
+creating disk images.
Using `virtualenv` to provide requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py
index 9c459fccf97..b8a22b22806 100644
--- a/test/py/tests/fs_helper.py
+++ b/test/py/tests/fs_helper.py
@@ -73,6 +73,40 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
call(f'rm -f {fs_img}', shell=True)
raise
+def setup_image(ubman, devnum, part_type, img_size=20, second_part=False,
+ basename='mmc'):
+ """Create a disk image with a single partition
+
+ Args:
+ ubman (ConsoleBase): Console to use
+ devnum (int): Device number to use, e.g. 1
+ part_type (int): Partition type, e.g. 0xc for FAT32
+ img_size (int): Image size in MiB
+ second_part (bool): True to contain a small second partition
+ basename (str): Base name to use in the filename, e.g. 'mmc'
+
+ Returns:
+ tuple:
+ str: Filename of MMC image
+ str: Directory name of scratch directory
+ """
+ fname = os.path.join(ubman.config.source_dir, f'{basename}{devnum}.img')
+ mnt = os.path.join(ubman.config.persistent_data_dir, 'scratch')
+
+ spec = f'type={part_type:x}, size={img_size - 2}M, start=1M, bootable'
+ if second_part:
+ spec += '\ntype=c'
+
+ try:
+ check_call(f'mkdir -p {mnt}', shell=True)
+ check_call(f'qemu-img create {fname} {img_size}M', shell=True)
+ check_call(f'printf "{spec}" | sfdisk {fname}', shell=True)
+ except CalledProcessError:
+ call(f'rm -f {fname}', shell=True)
+ raise
+
+ return fname, mnt
+
# Just for trying out
if __name__ == "__main__":
import collections
diff --git a/test/py/tests/test_cat.py b/test/py/tests/test_cat.py
new file mode 100644
index 00000000000..252c3d50a02
--- /dev/null
+++ b/test/py/tests/test_cat.py
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+""" Unit test for cat command
+"""
+
+import pytest
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_cat')
+def test_cat(ubman):
+ """ Unit test for cat
+
+ Args:
+ ubman -- U-Boot console
+ """
+ try:
+ scratch_dir = ubman.config.persistent_data_dir + '/scratch'
+
+ check_call('mkdir -p %s' % scratch_dir, shell=True)
+
+ with open(scratch_dir + '/hello', 'w', encoding = 'ascii') as file:
+ file.write('hello world\n')
+
+ cat_data = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_cat', scratch_dir)
+ response = ubman.run_command_list([ f'host bind 0 {cat_data}',
+ 'cat host 0 hello'])
+ assert 'hello world' in response
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_cat image failed')
+ call('rm -f %s' % cat_data, shell=True)
+ return
+ finally:
+ call('rm -rf %s' % scratch_dir, shell=True)
+ call('rm -f %s' % cat_data, shell=True)
diff --git a/test/py/tests/test_cat/conftest.py b/test/py/tests/test_cat/conftest.py
deleted file mode 100644
index 320e7ebd295..00000000000
--- a/test/py/tests/test_cat/conftest.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for cat command test
-"""
-
-import os
-import shutil
-from subprocess import check_call, CalledProcessError
-import pytest
-
-@pytest.fixture(scope='session')
-def cat_data(u_boot_config):
- """Set up a file system to be used in cat tests
-
- Args:
- u_boot_config -- U-Boot configuration.
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_cat'
- image_path = u_boot_config.persistent_data_dir + '/cat.img'
-
- try:
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/hello', 'w', encoding = 'ascii') as file:
- file.write('hello world\n')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- yield image_path
- except CalledProcessError:
- pytest.skip('Setup failed')
- finally:
- shutil.rmtree(mnt_point)
- if os.path.exists(image_path):
- os.remove(image_path)
diff --git a/test/py/tests/test_cat/test_cat.py b/test/py/tests/test_cat/test_cat.py
deleted file mode 100644
index 883803fece7..00000000000
--- a/test/py/tests/test_cat/test_cat.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-""" Unit test for cat command
-"""
-
-import pytest
-
-@pytest.mark.boardspec('sandbox')
-@pytest.mark.buildconfigspec('cmd_cat')
-def test_cat(ubman, cat_data):
- """ Unit test for cat
-
- Args:
- ubman -- U-Boot console
- cat_data -- Path to the disk image used for testing.
- """
- response = ubman.run_command_list([
- f'host bind 0 {cat_data}',
- 'cat host 0 hello'])
- assert 'hello world' in response
diff --git a/test/py/tests/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr.py
new file mode 100644
index 00000000000..4c10cbdf17d
--- /dev/null
+++ b/test/py/tests/test_efi_bootmgr.py
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0+
+""" Unit test for UEFI bootmanager
+"""
+
+import shutil
+import pytest
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_efidebug')
+@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
+@pytest.mark.singlethread
+def test_efi_bootmgr(ubman):
+ """ Unit test for UEFI bootmanager
+ The efidebug command is used to set up UEFI load options.
+ The bootefi bootmgr loads initrddump.efi as a payload.
+ The crc32 of the loaded initrd.img is checked
+
+ Args:
+ ubman -- U-Boot console
+ """
+ try:
+ efi_bootmgr_data, mnt = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_bootmgr')
+
+ with open(mnt + '/initrd-1.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 1")
+
+ with open(mnt + '/initrd-2.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 2")
+
+ shutil.copyfile(ubman.config.build_dir + '/lib/efi_loader/initrddump.efi',
+ mnt + '/initrddump.efi')
+
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_efi_bootmgr', mnt)
+ check_call(f'dd if={fsfile} of={efi_bootmgr_data} bs=1M seek=1', shell=True)
+
+ ubman.run_command(cmd = f'host bind 0 {efi_bootmgr_data}')
+
+ ubman.run_command(cmd = 'efidebug boot add ' \
+ '-b 0001 label-1 host 0:1 initrddump.efi ' \
+ '-i host 0:1 initrd-1.img -s nocolor')
+ ubman.run_command(cmd = 'efidebug boot dump')
+ ubman.run_command(cmd = 'efidebug boot order 0001')
+ ubman.run_command(cmd = 'bootefi bootmgr')
+ response = ubman.run_command(cmd = 'load', wait_for_echo=False)
+ assert 'crc32: 0x181464af' in response
+ ubman.run_command(cmd = 'exit', wait_for_echo=False)
+
+ ubman.run_command(cmd = 'efidebug boot add ' \
+ '-B 0002 label-2 host 0:1 initrddump.efi ' \
+ '-I host 0:1 initrd-2.img -s nocolor')
+ ubman.run_command(cmd = 'efidebug boot dump')
+ ubman.run_command(cmd = 'efidebug boot order 0002')
+ ubman.run_command(cmd = 'bootefi bootmgr')
+ response = ubman.run_command(cmd = 'load', wait_for_echo=False)
+ assert 'crc32: 0x811d3515' in response
+ ubman.run_command(cmd = 'exit', wait_for_echo=False)
+
+ ubman.run_command(cmd = 'efidebug boot rm 0001')
+ ubman.run_command(cmd = 'efidebug boot rm 0002')
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_efi_bootmgr image failed')
+ call('rm -f %s' % efi_bootmgr_data, shell=True)
+ return
+ finally:
+ call('rm -rf %s' % mnt, shell=True)
+ call('rm -f %s' % efi_bootmgr_data, shell=True)
diff --git a/test/py/tests/test_efi_bootmgr/conftest.py b/test/py/tests/test_efi_bootmgr/conftest.py
deleted file mode 100644
index 0eca025058e..00000000000
--- a/test/py/tests/test_efi_bootmgr/conftest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for UEFI bootmanager test."""
-
-import os
-import shutil
-from subprocess import check_call
-import pytest
-
-@pytest.fixture(scope='session')
-def efi_bootmgr_data(u_boot_config):
- """Set up a file system to be used in UEFI bootmanager tests.
-
- Args:
- u_boot_config -- U-Boot configuration.
-
- Return:
- A path to disk image to be used for testing
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_bootmgr'
- image_path = u_boot_config.persistent_data_dir + '/efi_bootmgr.img'
-
- shutil.rmtree(mnt_point, ignore_errors=True)
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 1")
-
- with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 2")
-
- shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
- mnt_point + '/initrddump.efi')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- return image_path
diff --git a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py
deleted file mode 100644
index 8800e9de5b4..00000000000
--- a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-""" Unit test for UEFI bootmanager
-"""
-
-import pytest
-
-@pytest.mark.boardspec('sandbox')
-@pytest.mark.buildconfigspec('cmd_efidebug')
-@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
-@pytest.mark.singlethread
-def test_efi_bootmgr(ubman, efi_bootmgr_data):
- """ Unit test for UEFI bootmanager
- The efidebug command is used to set up UEFI load options.
- The bootefi bootmgr loads initrddump.efi as a payload.
- The crc32 of the loaded initrd.img is checked
-
- Args:
- ubman -- U-Boot console
- efi_bootmgr_data -- Path to the disk image used for testing.
- """
- ubman.run_command(cmd = f'host bind 0 {efi_bootmgr_data}')
-
- ubman.run_command(cmd = 'efidebug boot add ' \
- '-b 0001 label-1 host 0:1 initrddump.efi ' \
- '-i host 0:1 initrd-1.img -s nocolor')
- ubman.run_command(cmd = 'efidebug boot dump')
- ubman.run_command(cmd = 'efidebug boot order 0001')
- ubman.run_command(cmd = 'bootefi bootmgr')
- response = ubman.run_command(cmd = 'load', wait_for_echo=False)
- assert 'crc32: 0x181464af' in response
- ubman.run_command(cmd = 'exit', wait_for_echo=False)
-
- ubman.run_command(cmd = 'efidebug boot add ' \
- '-B 0002 label-2 host 0:1 initrddump.efi ' \
- '-I host 0:1 initrd-2.img -s nocolor')
- ubman.run_command(cmd = 'efidebug boot dump')
- ubman.run_command(cmd = 'efidebug boot order 0002')
- ubman.run_command(cmd = 'bootefi bootmgr')
- response = ubman.run_command(cmd = 'load', wait_for_echo=False)
- assert 'crc32: 0x811d3515' in response
- ubman.run_command(cmd = 'exit', wait_for_echo=False)
-
- ubman.run_command(cmd = 'efidebug boot rm 0001')
- ubman.run_command(cmd = 'efidebug boot rm 0002')
diff --git a/test/py/tests/test_efi_capsule/capsule_common.py b/test/py/tests/test_efi_capsule/capsule_common.py
index 40b3fca809e..04dabc176c4 100644
--- a/test/py/tests/test_efi_capsule/capsule_common.py
+++ b/test/py/tests/test_efi_capsule/capsule_common.py
@@ -136,7 +136,7 @@ def do_reboot_dtb_specified(u_boot_config, ubman, dtb_filename):
ubman -- A console connection to U-Boot.
dtb_filename -- DTB file name.
"""
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
+ mnt_point = u_boot_config.persistent_data_dir + '/scratch'
ubman.config.dtb = mnt_point + CAPSULE_DATA_DIR \
+ f'/{dtb_filename}'
ubman.restart_uboot()
diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py
index 61eab5112a1..961d2e0b3c1 100644
--- a/test/py/tests/test_efi_capsule/conftest.py
+++ b/test/py/tests/test_efi_capsule/conftest.py
@@ -7,11 +7,12 @@
import os
from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
import pytest
from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR, EFITOOLS_PATH
-@pytest.fixture(scope='session')
-def efi_capsule_data(request, u_boot_config):
+@pytest.fixture(scope='function')
+def efi_capsule_data(request, ubman):
"""Set up a file system and return path to image.
The function sets up a file system to be used in UEFI capsule and
@@ -19,14 +20,14 @@ def efi_capsule_data(request, u_boot_config):
for testing.
request -- Pytest request object.
- u_boot_config -- U-Boot configuration.
+ ubman -- U-Boot configuration.
"""
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
- data_dir = mnt_point + CAPSULE_DATA_DIR
- install_dir = mnt_point + CAPSULE_INSTALL_DIR
- image_path = u_boot_config.persistent_data_dir + '/test_efi_capsule.img'
-
try:
+ image_path, mnt_point = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_capsule')
+ data_dir = mnt_point + CAPSULE_DATA_DIR
+ install_dir = mnt_point + CAPSULE_INSTALL_DIR
+
# Create a target device
check_call('dd if=/dev/zero of=./spi.bin bs=1MiB count=16', shell=True)
@@ -34,9 +35,9 @@ def efi_capsule_data(request, u_boot_config):
check_call('mkdir -p %s' % data_dir, shell=True)
check_call('mkdir -p %s' % install_dir, shell=True)
- capsule_auth_enabled = u_boot_config.buildconfig.get(
+ capsule_auth_enabled = ubman.config.buildconfig.get(
'config_efi_capsule_authenticate')
- key_dir = u_boot_config.source_dir + '/board/sandbox'
+ key_dir = ubman.config.source_dir + '/board/sandbox'
if capsule_auth_enabled:
# Get the keys from the board directory
check_call('cp %s/capsule_priv_key_good.key %s/SIGNER.key'
@@ -54,12 +55,12 @@ def efi_capsule_data(request, u_boot_config):
# Update dtb to add the version information
check_call('cd %s; '
'cp %s/test/py/tests/test_efi_capsule/version.dtso .'
- % (data_dir, u_boot_config.source_dir), shell=True)
+ % (data_dir, ubman.config.source_dir), shell=True)
if capsule_auth_enabled:
check_call('cd %s; '
'cp %s/arch/sandbox/dts/test.dtb test_sig.dtb'
- % (data_dir, u_boot_config.build_dir), shell=True)
+ % (data_dir, ubman.config.build_dir), shell=True)
check_call('cd %s; '
'dtc -@ -I dts -O dtb -o version.dtbo version.dtso; '
'fdtoverlay -i test_sig.dtb '
@@ -70,29 +71,33 @@ def efi_capsule_data(request, u_boot_config):
'dtc -@ -I dts -O dtb -o version.dtbo version.dtso; '
'fdtoverlay -i %s/arch/sandbox/dts/test.dtb '
'-o test_ver.dtb version.dtbo'
- % (data_dir, u_boot_config.build_dir), shell=True)
+ % (data_dir, ubman.config.build_dir), shell=True)
# two regions: one for u-boot.bin and the other for u-boot.env
check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir,
shell=True)
pythonpath = os.environ.get('PYTHONPATH', '')
- os.environ['PYTHONPATH'] = pythonpath + ':' + '%s/scripts/dtc/pylibfdt' % u_boot_config.build_dir
+ os.environ['PYTHONPATH'] = pythonpath + ':' + '%s/scripts/dtc/pylibfdt' % ubman.config.build_dir
check_call('cd %s; '
'cc -E -I %s/include -x assembler-with-cpp -o capsule_gen_tmp.dts %s/test/py/tests/test_efi_capsule/capsule_gen_binman.dts; '
'dtc -I dts -O dtb capsule_gen_tmp.dts -o capsule_binman.dtb;'
- % (data_dir, u_boot_config.source_dir, u_boot_config.source_dir), shell=True)
+ % (data_dir, ubman.config.source_dir, ubman.config.source_dir), shell=True)
check_call('cd %s; '
'./tools/binman/binman --toolpath %s/tools build -u -d %s/capsule_binman.dtb -O %s -m --allow-missing -I %s -I ./board/sandbox -I ./arch/sandbox/dts'
- % (u_boot_config.source_dir, u_boot_config.build_dir, data_dir, data_dir, data_dir), shell=True)
- check_call('cp %s/Test* %s' % (u_boot_config.build_dir, data_dir), shell=True)
+ % (ubman.config.source_dir, ubman.config.build_dir, data_dir, data_dir, data_dir), shell=True)
+ check_call('cp %s/Test* %s' % (ubman.config.build_dir, data_dir), shell=True)
os.environ['PYTHONPATH'] = pythonpath
- # Create a disk image with EFI system partition
- check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' %
- (mnt_point, image_path), shell=True)
+ # Create a 16MiB partition as the EFI system partition in the disk
+ # image
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x1000000,
+ 'test_efi_capsule', mnt_point)
+ check_call(f'dd conv=notrunc if={fsfile} of={image_path} bs=1M seek=1', shell=True)
+ check_call('sgdisk --mbrtogpt %s' % image_path, shell=True)
check_call('sgdisk %s -A 1:set:0 -t 1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B' %
image_path, shell=True)
+ call('rm -f %s' % fsfile, shell=True)
except CalledProcessError as exception:
pytest.skip('Setup failed: %s' % exception.cmd)
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
index 0fa0747fc76..aa9a3536296 100644
--- a/test/py/tests/test_efi_secboot/conftest.py
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -5,27 +5,25 @@
"""Fixture for UEFI secure boot test."""
from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
import pytest
from defs import *
-@pytest.fixture(scope='session')
-def efi_boot_env(request, u_boot_config):
+@pytest.fixture(scope='function')
+def efi_boot_env(request, ubman):
"""Set up a file system to be used in UEFI secure boot test.
Args:
request: Pytest request object.
- u_boot_config: U-Boot configuration.
+ ubman: U-Boot configuration.
Return:
A path to disk image to be used for testing
"""
- image_path = u_boot_config.persistent_data_dir
- image_path = image_path + '/test_efi_secboot.img'
try:
- mnt_point = u_boot_config.build_dir + '/mnt_efisecure'
- check_call('rm -rf {}'.format(mnt_point), shell=True)
- check_call('mkdir -p {}'.format(mnt_point), shell=True)
+ image_path, mnt_point = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_secboot')
# suffix
# *.key: RSA private key in PEM
@@ -101,7 +99,7 @@ def efi_boot_env(request, u_boot_config):
# Copy image
check_call('cp %s/lib/efi_loader/helloworld.efi %s' %
- (u_boot_config.build_dir, mnt_point), shell=True)
+ (ubman.config.build_dir, mnt_point), shell=True)
# Sign image
check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi'
@@ -111,7 +109,7 @@ def efi_boot_env(request, u_boot_config):
% mnt_point, shell=True)
# Create a corrupted signed image
check_call('cd %s; sh %s/test/py/tests/test_efi_secboot/forge_image.sh helloworld.efi.signed helloworld_forged.efi.signed'
- % (mnt_point, u_boot_config.source_dir), shell=True)
+ % (mnt_point, ubman.config.source_dir), shell=True)
# Digest image
check_call('cd %s; %shash-to-efi-sig-list helloworld.efi db_hello.hash; %ssign-efi-sig-list -t "2020-04-07" -c KEK.crt -k KEK.key db db_hello.hash db_hello.auth'
% (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH),
@@ -123,9 +121,9 @@ def efi_boot_env(request, u_boot_config):
% (mnt_point, EFITOOLS_PATH),
shell=True)
- check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat {} {}'.format(
- mnt_point, image_path), shell=True)
- check_call('rm -rf {}'.format(mnt_point), shell=True)
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x1000000,
+ 'test_efi_secboot', mnt_point)
+ check_call(f'dd if={fsfile} of={image_path} bs=1M seek=1', shell=True)
except CalledProcessError as exception:
pytest.skip('Setup failed: %s' % exception.cmd)
@@ -133,15 +131,16 @@ def efi_boot_env(request, u_boot_config):
else:
yield image_path
finally:
- call('rm -f %s' % image_path, shell=True)
+ call('rm -rf %s' % mnt_point, shell=True)
+ call('rm -f %s %s' % (image_path, fsfile), shell=True)
#
# Fixture for UEFI secure boot test of intermediate certificates
#
-@pytest.fixture(scope='session')
-def efi_boot_env_intca(request, u_boot_config):
+@pytest.fixture(scope='function')
+def efi_boot_env_intca(request, ubman):
"""Set up file system for secure boot test.
Set up a file system to be used in UEFI secure boot test
@@ -149,18 +148,15 @@ def efi_boot_env_intca(request, u_boot_config):
Args:
request: Pytest request object.
- u_boot_config: U-Boot configuration.
+ ubman: U-Boot configuration.
Return:
A path to disk image to be used for testing
"""
- image_path = u_boot_config.persistent_data_dir
- image_path = image_path + '/test_efi_secboot_intca.img'
try:
- mnt_point = u_boot_config.persistent_data_dir + '/mnt_efi_secboot_intca'
- check_call('rm -rf {}'.format(mnt_point), shell=True)
- check_call('mkdir -p {}'.format(mnt_point), shell=True)
+ image_path, mnt_point = fs_helper.setup_image(ubman, 0, 0xc,
+ basename='test_efi_secboot_intca')
# Create signature database
# PK
@@ -190,7 +186,7 @@ def efi_boot_env_intca(request, u_boot_config):
# TestRoot
check_call('cp %s/test/py/tests/test_efi_secboot/openssl.cnf %s'
- % (u_boot_config.source_dir, mnt_point), shell=True)
+ % (ubman.config.source_dir, mnt_point), shell=True)
check_call('cd %s; export OPENSSL_CONF=./openssl.cnf; openssl genrsa -out TestRoot.key 2048; openssl req -extensions v3_ca -new -x509 -days 365 -key TestRoot.key -out TestRoot.crt -subj "/CN=TEST_root/"; touch index.txt; touch index.txt.attr'
% mnt_point, shell=True)
# TestSub
@@ -231,7 +227,7 @@ def efi_boot_env_intca(request, u_boot_config):
# in SignedData
check_call('cp %s/lib/efi_loader/helloworld.efi %s' %
- (u_boot_config.build_dir, mnt_point), shell=True)
+ (ubman.config.build_dir, mnt_point), shell=True)
# signed by TestCert
check_call('cd %s; %ssbsign --key TestCert.key --cert TestCert.crt --out helloworld.efi.signed_a helloworld.efi'
% (mnt_point, SBSIGN_PATH), shell=True)
@@ -242,8 +238,9 @@ def efi_boot_env_intca(request, u_boot_config):
check_call('cd %s; cat TestSub.crt TestRoot.crt > TestSubRoot.crt; %ssbsign --key TestCert.key --cert TestCert.crt --addcert TestSubRoot.crt --out helloworld.efi.signed_abc helloworld.efi'
% (mnt_point, SBSIGN_PATH), shell=True)
- check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat {} {}'.format(mnt_point, image_path), shell=True)
- check_call('rm -rf {}'.format(mnt_point), shell=True)
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x1000000,
+ 'test_efi_secboot_intca', mnt_point)
+ check_call(f'dd if={fsfile} of={image_path} bs=1M seek=1', shell=True)
except CalledProcessError as e:
pytest.skip('Setup failed: %s' % e.cmd)
@@ -251,4 +248,5 @@ def efi_boot_env_intca(request, u_boot_config):
else:
yield image_path
finally:
- call('rm -f %s' % image_path, shell=True)
+ call('rm -rf %s' % mnt_point, shell=True)
+ call('rm -f %s %s' % (image_path, fsfile), shell=True)
diff --git a/test/py/tests/test_eficonfig/test_eficonfig.py b/test/py/tests/test_eficonfig.py
index 3ca8e27c76b..ac1600ec252 100644
--- a/test/py/tests/test_eficonfig/test_eficonfig.py
+++ b/test/py/tests/test_eficonfig.py
@@ -3,12 +3,56 @@
"""
import pytest
+import shutil
+import pytest
import time
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_eficonfig')
@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
-def test_efi_eficonfig(ubman, efi_eficonfig_data):
+def test_efi_eficonfig(ubman):
+
+ def prepare_image(u_boot_config):
+ """Set up a file system to be used in UEFI "eficonfig" command
+ tests. This creates a disk image with the following files:
+ initrd-1.img
+ initrd-2.img
+ initrddump.efi
+
+ Args:
+ u_boot_config -- U-Boot configuration.
+
+ Return:
+ A path to disk image to be used for testing
+
+ """
+ try:
+ image_path, mnt_point = fs_helper.setup_image(u_boot_config, 0,
+ 0xc,
+ basename='test_eficonfig')
+
+ with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 1")
+
+ with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
+ file.write("initrd 2")
+
+ shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
+ mnt_point + '/initrddump.efi')
+
+ fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_eficonfig', mnt_point)
+ check_call(f'dd if={fsfile} of={image_path} bs=1M seek=1', shell=True)
+
+ yield image_path
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_eficonfig image failed')
+ call('rm -f %s' % image_path, shell=True)
+ finally:
+ call('rm -rf %s' % mnt_point, shell=True)
+ call('rm -f %s' % image_path, shell=True)
def send_user_input_and_wait(user_str, expect_str):
time.sleep(0.1) # TODO: does not work correctly without sleep
@@ -57,12 +101,6 @@ def test_efi_eficonfig(ubman, efi_eficonfig_data):
Args:
ubman -- U-Boot console
- efi__data -- Path to the disk image used for testing.
- Test disk image has following files.
- initrd-1.img
- initrd-2.img
- initrddump.efi
-
"""
# This test passes for unknown reasons in the bowels of U-Boot. It needs to
# be replaced with a unit test.
@@ -71,6 +109,7 @@ def test_efi_eficonfig(ubman, efi_eficonfig_data):
# Restart the system to clean the previous state
ubman.restart_uboot()
+ efi_eficonfig_data = prepare_image(ubman.config)
with ubman.temporary_timeout(500):
#
# Test Case 1: Check the menu is displayed
diff --git a/test/py/tests/test_eficonfig/conftest.py b/test/py/tests/test_eficonfig/conftest.py
deleted file mode 100644
index 0a82fbefd75..00000000000
--- a/test/py/tests/test_eficonfig/conftest.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for UEFI eficonfig test
-"""
-
-import os
-import shutil
-from subprocess import check_call
-import pytest
-
-@pytest.fixture(scope='session')
-def efi_eficonfig_data(u_boot_config):
- """Set up a file system to be used in UEFI "eficonfig" command
- tests
-
- Args:
- u_boot_config -- U-Boot configuration.
-
- Return:
- A path to disk image to be used for testing
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_efi_eficonfig'
- image_path = u_boot_config.persistent_data_dir + '/efi_eficonfig.img'
-
- shutil.rmtree(mnt_point, ignore_errors=True)
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 1")
-
- with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 2")
-
- shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
- mnt_point + '/initrddump.efi')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- return image_path
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index b8adb597e11..cdf54adc600 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -27,36 +27,6 @@ def mkdir_cond(dirname):
if not os.path.exists(dirname):
os.mkdir(dirname)
-def setup_image(ubman, devnum, part_type, img_size=20, second_part=False,
- basename='mmc'):
- """Create a disk image with a single partition
-
- Args:
- ubman (ConsoleBase): Console to use
- devnum (int): Device number to use, e.g. 1
- part_type (int): Partition type, e.g. 0xc for FAT32
- img_size (int): Image size in MiB
- second_part (bool): True to contain a small second partition
- basename (str): Base name to use in the filename, e.g. 'mmc'
-
- Returns:
- tuple:
- str: Filename of MMC image
- str: Directory name of scratch directory
- """
- fname = os.path.join(ubman.config.source_dir, f'{basename}{devnum}.img')
- mnt = os.path.join(ubman.config.persistent_data_dir, 'scratch')
- mkdir_cond(mnt)
-
- spec = f'type={part_type:x}, size={img_size - 2}M, start=1M, bootable'
- if second_part:
- spec += '\ntype=c'
-
- utils.run_and_log(ubman, f'qemu-img create {fname} 20M')
- utils.run_and_log(ubman, f'sfdisk {fname}',
- stdin=spec.encode('utf-8'))
- return fname, mnt
-
def copy_partition(ubman, fsfile, outname):
"""Copy a partition into a disk iamge
@@ -74,7 +44,7 @@ def setup_bootmenu_image(ubman):
This is modelled on Armbian 22.08 Jammy
"""
mmc_dev = 4
- fname, mnt = setup_image(ubman, mmc_dev, 0x83)
+ fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0x83)
script = '''# DO NOT EDIT THIS FILE
#
@@ -190,7 +160,7 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
def setup_bootflow_image(ubman):
"""Create a 20MB disk image with a single FAT partition"""
mmc_dev = 1
- fname, mnt = setup_image(ubman, mmc_dev, 0xc, second_part=True)
+ fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0xc, second_part=True)
vmlinux = 'vmlinuz-5.3.7-301.fc31.armv7hl'
initrd = 'initramfs-5.3.7-301.fc31.armv7hl.img'
@@ -556,8 +526,8 @@ def setup_efi_image(ubman):
"""Create a 20MB disk image with an EFI app on it"""
devnum = 1
basename = 'flash'
- fname, mnt = setup_image(ubman, devnum, 0xc, second_part=True,
- basename=basename)
+ fname, mnt = fs_helper.setup_image(ubman, devnum, 0xc, second_part=True,
+ basename=basename)
efi_dir = os.path.join(mnt, 'EFI')
mkdir_cond(efi_dir)
diff --git a/test/py/tests/test_xxd.py b/test/py/tests/test_xxd.py
new file mode 100644
index 00000000000..c457c54146c
--- /dev/null
+++ b/test/py/tests/test_xxd.py
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+""" Unit test for xxd command
+"""
+
+import pytest
+from subprocess import call, check_call, CalledProcessError
+from tests import fs_helper
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_xxd')
+def test_xxd(ubman):
+ """ Unit test for xxd
+
+ Args:
+ ubman -- U-Boot console
+ """
+ try:
+ scratch_dir = ubman.config.persistent_data_dir + '/scratch'
+
+ check_call('mkdir -p %s' % scratch_dir, shell=True)
+
+ with open(scratch_dir + '/hello', 'w', encoding = 'ascii') as file:
+ file.write('hello world\n\x00\x01\x02\x03\x04\x05')
+
+ xxd_data = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
+ 'test_xxd', scratch_dir)
+ response = ubman.run_command_list([ f'host bind 0 {xxd_data}',
+ 'xxd host 0 hello'])
+
+ assert '00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....\r\r\n' + \
+ '00000010: 04 05 ..' \
+ in response
+ except CalledProcessError as err:
+ pytest.skip('Preparing test_xxd image failed')
+ call('rm -f %s' % xxd_data, shell=True)
+ return
+ finally:
+ call('rm -rf %s' % scratch_dir, shell=True)
+ call('rm -f %s' % xxd_data, shell=True)
diff --git a/test/py/tests/test_xxd/conftest.py b/test/py/tests/test_xxd/conftest.py
deleted file mode 100644
index 47c7cce1aa9..00000000000
--- a/test/py/tests/test_xxd/conftest.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-"""Fixture for xxd command test
-"""
-
-import os
-import shutil
-from subprocess import check_call, CalledProcessError
-import pytest
-
-@pytest.fixture(scope='session')
-def xxd_data(u_boot_config):
- """Set up a file system to be used in xxd tests
-
- Args:
- u_boot_config -- U-Boot configuration.
- """
- mnt_point = u_boot_config.persistent_data_dir + '/test_xxd'
- image_path = u_boot_config.persistent_data_dir + '/xxd.img'
-
- try:
- os.mkdir(mnt_point, mode = 0o755)
-
- with open(mnt_point + '/hello', 'w', encoding = 'ascii') as file:
- file.write('hello world\n\x00\x01\x02\x03\x04\x05')
-
- check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
- shell=True)
-
- yield image_path
- except CalledProcessError:
- pytest.skip('Setup failed')
- finally:
- shutil.rmtree(mnt_point)
- if os.path.exists(image_path):
- os.remove(image_path)
diff --git a/test/py/tests/test_xxd/test_xxd.py b/test/py/tests/test_xxd/test_xxd.py
deleted file mode 100644
index c04bf8b7a25..00000000000
--- a/test/py/tests/test_xxd/test_xxd.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-""" Unit test for xxd command
-"""
-
-import pytest
-
-@pytest.mark.boardspec('sandbox')
-@pytest.mark.buildconfigspec('cmd_xxd')
-def test_xxd(ubman, xxd_data):
- """ Unit test for xxd
-
- Args:
- ubman -- U-Boot console
- xxd_data -- Path to the disk image used for testing.
- """
- response = ubman.run_command_list([
- f'host bind 0 {xxd_data}',
- 'xxd host 0 hello'])
-
- assert '00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....\r\r\n' + \
- '00000010: 04 05 ..' \
- in response
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 80e9247aa60..e14d1640f9c 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -92,7 +92,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
libconfuse-dev \
libgit2-dev \
libjson-glib-dev \
- libguestfs-tools \
libgnutls28-dev \
libgnutls30 \
liblz4-tool \
@@ -106,7 +105,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
libtool \
libudev-dev \
libusb-1.0-0-dev \
- linux-image-generic \
lzma-alone \
lzop \
mount \
@@ -143,9 +141,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
xxd \
zip
-# Make kernels readable for libguestfs tools to work correctly
-RUN chmod +r /boot/vmlinu*
-
# Build GRUB UEFI targets for ARM & RISC-V, 32-bit and 64-bit
RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \
cd /tmp/grub && \