[PATCH 00/13] test: Create a better helper for filesystems

This series includes a few new helpers which make it easier to create filesystems and disk images for testing. The current approach requires the caller to create a temporary directory, put files in there, then call the helper. It has poor support for building disks containing multiple partitions. This new helper works by creating a temporary directory which the caller can use, then creating the filesystem and cleaning up. Most of U-Boot is moved over to use these new helpers, but two EFI tests are left alone, since they don't currently pass: - test_efi_eficonfig() has a 'return' in it, so doesn't run - TestEfiCapsuleFirmwareFit is skipped due to a failure at the start These can be moved over later when they are working. This series also includes a few quirks to the VBE tests. Simon Glass (13): vbe: Remove 'simple' from vbe_abrec vbe: Enable testing OS requests on vanilla sandbox test: Update comment for fs_helper.setup_image() test: fs_helper: Drop the size_gran argument test: Convert fs_helper to use a class test: Convert test_cat to use FsHelper test: Convert test_xxd to use FsHelper test: Add a helper class to create disk images test: Convert test_efi_bootmgr to use FsHelper test: Convert setup_bootmenu_image() to use FsHelper test: Convert setup_bootflow_image() to use FsHelper test: Convert setup_efi_image() to use FsHelper test: Convert test_ut_dm_init() to use FsHelper boot/vbe_abrec.c | 6 +- test/py/tests/fs_helper.py | 290 ++++++++++++++++++++++++------ test/py/tests/test_cat.py | 27 +-- test/py/tests/test_efi_bootmgr.py | 38 ++-- test/py/tests/test_ut.py | 78 ++++---- test/py/tests/test_vbe.py | 5 +- test/py/tests/test_xxd.py | 28 +-- 7 files changed, 312 insertions(+), 160 deletions(-) -- 2.43.0 base-commit: 8a971f9265d5433ff1e2700557a418ed17184b42 branch: loadb

It is confusing to use the word 'simple' within the ABrec driver. Rename a few identifiers to fix this. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/vbe_abrec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boot/vbe_abrec.c b/boot/vbe_abrec.c index 8593082fd79..3b5f75421ff 100644 --- a/boot/vbe_abrec.c +++ b/boot/vbe_abrec.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Verified Boot for Embedded (VBE) 'simple' method + * Verified Boot for Embedded (VBE) 'abrec' method * * Copyright 2024 Google LLC * Written by Simon Glass <sjg@chromium.org> @@ -164,7 +164,7 @@ static int bootmeth_vbe_abrec_bind(struct udevice *dev) } #if CONFIG_IS_ENABLED(OF_REAL) -static const struct udevice_id generic_simple_vbe_abrec_ids[] = { +static const struct udevice_id vbe_abrec_ids[] = { { .compatible = "fwupd,vbe-abrec" }, { } }; @@ -173,7 +173,7 @@ static const struct udevice_id generic_simple_vbe_abrec_ids[] = { U_BOOT_DRIVER(vbe_abrec) = { .name = "vbe_abrec", .id = UCLASS_BOOTMETH, - .of_match = of_match_ptr(generic_simple_vbe_abrec_ids), + .of_match = of_match_ptr(vbe_abrec_ids), .ops = &bootmeth_vbe_abrec_ops, .bind = bootmeth_vbe_abrec_bind, .probe = bootmeth_vbe_abrec_probe, -- 2.43.0

Rather than using the flattree build, run the OS-request tests on the main sandbox build. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_vbe.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/py/tests/test_vbe.py b/test/py/tests/test_vbe.py index a1f32f375b6..7a9a3141f07 100644 --- a/test/py/tests/test_vbe.py +++ b/test/py/tests/test_vbe.py @@ -88,9 +88,10 @@ fdt print ut bootstd -f vbe_test_fixup_norun ''' -@pytest.mark.boardspec('sandbox_flattree') +@pytest.mark.boardspec('sandbox') @pytest.mark.requiredtool('dtc') -def test_vbe(ubman): +def test_vbe_os_request(ubman): + """Test loading an OS and dealing with requests""" kernel = fit_util.make_kernel(ubman, 'vbe-kernel.bin', 'kernel') fdt = fit_util.make_dtb(ubman, base_fdt, 'vbe-fdt') fdt_out = fit_util.make_fname(ubman, 'fdt-out.dtb') -- 2.43.0

This function actually allows creating two partitions now, so update its comment to match that. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/fs_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index d124f03a7dc..aedf6af0aeb 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -83,7 +83,7 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, def setup_image(ubman, devnum, part_type, img_size=20, second_part=False, basename='mmc'): - """Create a disk image with a single partition + """Create a disk image with one or two partitions Args: ubman (ConsoleBase): Console to use -- 2.43.0

Nothing uses this argument, so make it a constant for now. Also fix a pylint warning when checking for vfat/exfat. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/fs_helper.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index aedf6af0aeb..6649aa7bc47 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -10,8 +10,11 @@ import os from subprocess import call, check_call, check_output, CalledProcessError from subprocess import DEVNULL -def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, - fs_img=None, quiet=False): +# size_gran (int): Size granularity of file system image in bytes +SIZE_GRAN = 1 << 20 + + +def mk_fs(config, fs_type, size, prefix, src_dir=None, fs_img=None, quiet=False): """Create a file system volume Args: @@ -20,7 +23,6 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, size (int): Size of file system in bytes prefix (str): Prefix string of volume's file name src_dir (str): Root directory to use, or None for none - size_gran (int): Size granularity of file system image in bytes fs_img (str or None): Filename for image, or None to invent one quiet (bool): Suppress non-error output @@ -50,10 +52,10 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, if src_dir: if fs_lnxtype == 'ext4': mkfs_opt = mkfs_opt + ' -d ' + src_dir - elif fs_lnxtype != 'vfat' and fs_lnxtype != 'exfat': + elif fs_lnxtype not in ('vfat', 'exfat'): raise ValueError(f'src_dir not implemented for fs {fs_lnxtype}') - count = (size + size_gran - 1) // size_gran + count = (size + SIZE_GRAN - 1) // SIZE_GRAN # Some distributions do not add /sbin to the default PATH, where mkfs lives if '/sbin' not in os.environ["PATH"].split(os.pathsep): @@ -61,7 +63,7 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, try: check_call(f'rm -f {fs_img}', shell=True) - check_call(f'truncate -s $(( {size_gran} * {count} )) {fs_img}', + check_call(f'truncate -s $(( {SIZE_GRAN} * {count} )) {fs_img}', shell=True) check_call(f'mkfs.{fs_lnxtype} {mkfs_opt} {fs_img}', shell=True, stdout=DEVNULL if quiet else None) -- 2.43.0

It is somewhat inconvenient that callers to mk_fs() must create their own temporary directory. Convert it to a class so this can be handled automatically, using a context manager. Rather than specifying the file size in bytes, use MB since it is rare to need a smaller file. Update mk_fs() to use this new class. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/fs_helper.py | 200 +++++++++++++++++++++++++++---------- 1 file changed, 145 insertions(+), 55 deletions(-) diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index 6649aa7bc47..7d20dbacf76 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -9,12 +9,148 @@ import re import os from subprocess import call, check_call, check_output, CalledProcessError from subprocess import DEVNULL +import tempfile -# size_gran (int): Size granularity of file system image in bytes -SIZE_GRAN = 1 << 20 +class FsHelper: + """Creating a filesystem containing test files -def mk_fs(config, fs_type, size, prefix, src_dir=None, fs_img=None, quiet=False): + Usage: + with FsHelper(ubman.config, 'ext4', 10, 'mmc1') as fsh: + # create files in the self.srcdir directory + fsh.mk_fs() + # Now use the filesystem + + # The filesystem and srcdir are erased after the 'with' statement. + + To set the image filename: + + with FsHelper(ubman.config, 'ext4', 10, 'mmc1') as fsh: + self.fs_img = 'myfile.img' + fsh.mk_fs() + ... + + It is also possible to use an existing srcdir: + + with FsHelper(ubman.config, 'fat32', 10, 'usb2') as fsh: + fsh.srcdir = src_dir + fsh.mk_fs() + ... + + Properties: + fs_img (str): Filename for the filesystem image; this is set to a + default value but can be overwritten + """ + def __init__(self, config, fs_type, size_mb, prefix): + """Set up a new object + + Args: + config (u_boot_config): U-Boot configuration + fs_type (str): File system type: one of ext2, ext3, ext4, vfat, + fat12, fat16, fat32, exfat, fs_generic (which means vfat) + size_mb (int): Size of file system in MB + prefix (str): Prefix string of volume's file name + """ + if ('fat' not in fs_type and 'ext' not in fs_type and + fs_type not in ['exfat', 'fs_generic']): + raise ValueError(f"Unsupported filesystem type '{fs_type}'") + + self.config = config + self.fs_type = fs_type + self.size_mb = size_mb + self.prefix = prefix + self.quiet = True + + # Use a default filename; the caller can adjust it + leaf = f'{prefix}.{fs_type}.img' + self.fs_img = os.path.join(config.persistent_data_dir, leaf) + + # Some distributions do not add /sbin to the default PATH, where mkfs + # lives + if '/sbin' not in os.environ["PATH"].split(os.pathsep): + os.environ["PATH"] += os.pathsep + '/sbin' + + self.srcdir = None + self.tmpdir = None + self._do_cleanup = True + + def _get_fs_args(self): + """Get the mkfs options and program to use + + Returns: + tuple: + str: mkfs options, e.g. '-F 32' for fat32 + str: mkfs program to use, e.g 'ext4' for ext4 + """ + if self.fs_type == 'fat12': + mkfs_opt = '-F 12' + elif self.fs_type == 'fat16': + mkfs_opt = '-F 16' + elif self.fs_type == 'fat32': + mkfs_opt = '-F 32' + elif self.fs_type.startswith('ext'): + mkfs_opt = f'-d {self.srcdir}' + else: + mkfs_opt = '' + + if self.fs_type == 'exfat': + fs_lnxtype = 'exfat' + elif re.match('fat', self.fs_type) or self.fs_type == 'fs_generic': + fs_lnxtype = 'vfat' + else: + fs_lnxtype = self.fs_type + return mkfs_opt, fs_lnxtype + + def mk_fs(self): + """Make a new filesystem and copy in the files""" + self.setup() + mkfs_opt, fs_lnxtype = self._get_fs_args() + fs_img = self.fs_img + with open(fs_img, 'wb') as fsi: + fsi.truncate(self.size_mb << 20) + + try: + mkfs_opt, fs_lnxtype = self._get_fs_args() + check_call(f'mkfs.{fs_lnxtype} {mkfs_opt} {fs_img}', shell=True, + stdout=DEVNULL if self.quiet else None) + + if self.fs_type.startswith('ext'): + sb_content = check_output(f'tune2fs -l {fs_img}', + shell=True).decode() + if 'metadata_csum' in sb_content: + check_call(f'tune2fs -O ^metadata_csum {fs_img}', shell=True) + elif fs_lnxtype == 'exfat': + check_call(f'fattools cp {self.srcdir}/* {fs_img}', shell=True) + elif self.srcdir and os.listdir(self.srcdir): + flags = f"-smpQ{'' if self.quiet else 'v'}" + check_call(f'mcopy -i {fs_img} {flags} {self.srcdir}/* ::/', + shell=True) + except CalledProcessError: + os.remove(fs_img) + raise + + def setup(self): + """Set up the srcdir ready to receive files""" + if not self.srcdir: + self.tmpdir = tempfile.TemporaryDirectory('fs_helper') + self.srcdir = self.tmpdir.name + + def cleanup(self): + """Remove created files""" + if self.tmpdir: + self.tmpdir.cleanup() + os.remove(self.fs_img) + + def __enter__(self): + self.setup() + return self + + def __exit__(self, extype, value, traceback): + self.cleanup() + + +def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, + fs_img=None, quiet=False): """Create a file system volume Args: @@ -29,59 +165,13 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, fs_img=None, quiet=False) Raises: CalledProcessError: if any error occurs when creating the filesystem """ - if not fs_img: - leaf = f'{prefix}.{fs_type}.img' - fs_img = os.path.join(config.persistent_data_dir, leaf) - - if fs_type == 'fat12': - mkfs_opt = '-F 12' - elif fs_type == 'fat16': - mkfs_opt = '-F 16' - elif fs_type == 'fat32': - mkfs_opt = '-F 32' - else: - mkfs_opt = '' - - if fs_type == 'exfat': - fs_lnxtype = 'exfat' - elif re.match('fat', fs_type) or fs_type == 'fs_generic': - fs_lnxtype = 'vfat' - else: - fs_lnxtype = fs_type - - if src_dir: - if fs_lnxtype == 'ext4': - mkfs_opt = mkfs_opt + ' -d ' + src_dir - elif fs_lnxtype not in ('vfat', 'exfat'): - raise ValueError(f'src_dir not implemented for fs {fs_lnxtype}') - - count = (size + SIZE_GRAN - 1) // SIZE_GRAN - - # Some distributions do not add /sbin to the default PATH, where mkfs lives - if '/sbin' not in os.environ["PATH"].split(os.pathsep): - os.environ["PATH"] += os.pathsep + '/sbin' + fsh = FsHelper(config, fs_type, size >> 20, prefix) + fsh.srcdir = src_dir + if fs_img: + fsh.fs_img = fs_img + fsh.mk_fs() + return fsh.fs_img - try: - check_call(f'rm -f {fs_img}', shell=True) - check_call(f'truncate -s $(( {SIZE_GRAN} * {count} )) {fs_img}', - shell=True) - check_call(f'mkfs.{fs_lnxtype} {mkfs_opt} {fs_img}', shell=True, - stdout=DEVNULL if quiet else None) - if fs_type == 'ext4': - sb_content = check_output(f'tune2fs -l {fs_img}', - shell=True).decode() - if 'metadata_csum' in sb_content: - check_call(f'tune2fs -O ^metadata_csum {fs_img}', shell=True) - elif fs_lnxtype == 'vfat' and src_dir: - flags = f"-smpQ{'' if quiet else 'v'}" - check_call(f'mcopy -i {fs_img} {flags} {src_dir}/* ::/', - shell=True) - elif fs_lnxtype == 'exfat' and src_dir: - check_call(f'fattools cp {src_dir}/* {fs_img}', shell=True) - return fs_img - except CalledProcessError: - call(f'rm -f {fs_img}', shell=True) - raise def setup_image(ubman, devnum, part_type, img_size=20, second_part=False, basename='mmc'): -- 2.43.0

Simplify this test by using the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_cat.py | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/test/py/tests/test_cat.py b/test/py/tests/test_cat.py index 252c3d50a02..f793b9fe0a1 100644 --- a/test/py/tests/test_cat.py +++ b/test/py/tests/test_cat.py @@ -4,8 +4,7 @@ """ import pytest -from subprocess import call, check_call, CalledProcessError -from tests import fs_helper +from tests.fs_helper import FsHelper @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_cat') @@ -15,23 +14,11 @@ def test_cat(ubman): Args: ubman -- U-Boot console """ - try: - scratch_dir = ubman.config.persistent_data_dir + '/scratch' + with FsHelper(ubman.config, 'vfat', 1, 'test_cat') as fsh: + with open(f'{fsh.srcdir}/hello', 'w', encoding = 'ascii') as outf: + outf.write('hello world\n') + fsh.mk_fs() - 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']) + response = ubman.run_command_list([f'host bind 0 {fsh.fs_img}', + '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) -- 2.43.0

Simplify this test by using the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_xxd.py | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/test/py/tests/test_xxd.py b/test/py/tests/test_xxd.py index c457c54146c..a5f63f006fe 100644 --- a/test/py/tests/test_xxd.py +++ b/test/py/tests/test_xxd.py @@ -4,8 +4,7 @@ """ import pytest -from subprocess import call, check_call, CalledProcessError -from tests import fs_helper +from tests.fs_helper import FsHelper @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_xxd') @@ -15,26 +14,13 @@ def test_xxd(ubman): 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']) + with FsHelper(ubman.config, 'vfat', 1, 'test_xxd') as fsh: + with open(f'{fsh.srcdir}/hello', 'w', encoding = 'ascii') as outf: + outf.write('hello world\n\x00\x01\x02\x03\x04\x05') + fsh.mk_fs() + response = ubman.run_command_list([f'host bind 0 {fsh.fs_img}', + '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) -- 2.43.0

Provide a way to create disk images which consist of multiple filesystem images. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/fs_helper.py | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index 7d20dbacf76..5c147e7750f 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -149,6 +149,96 @@ class FsHelper: self.cleanup() +class DiskHelper: + """Helper class for creating disk images containing filesytems + + Usage: + with DiskHelper(ubman.config, 0, 'mmc') as img, \ + FsHelper(ubman.config, 'ext1', 1, 'mmc') as fsh: + # Write files to fsh.srcdir + ... + + # Create the filesystem + fsh.mk_fs() + + # Add this filesystem to the disk + img.add_fs(fsh, DiskHelper.VFAT) + + # Add more filesystems as needed (add another 'with' clause) + ... + + # Get the final disk image + data = img.create() + """ + + # Partition-type codes + VFAT = 0xc + EXT4 = 0x83 + + def __init__(self, config, devnum, prefix): + """Set up a new disk image + + Args: + config (u_boot_config): U-Boot configuration + leaf (str): Leafname of the image, which will be placed in the + persistent-data directory + """ + self.fs_list = [] + self.fname = os.path.join(config.persistent_data_dir, + f'{prefix}{devnum}.img') + + def add_fs(self, fs_img, part_type, bootable=False): + """Add a new filesystem + + Args: + fs_img (FsHelper): Filesystem to add + part_type (DiskHelper.FAT or DiskHelper.EXT4): Partition type + bootable (bool): True to set the 'bootable' flat + """ + self.fs_list.append([fs_img, part_type, bootable]) + + def create(self): + """Create the disk image + + Create an image with a partition table and the filesystems + """ + spec = '' + pos = 1 # Reserve 1MB for the partition table itself + for fsi, part_type, bootable in self.fs_list: + if spec: + spec += '\n' + spec += f'type={part_type:x}, size={fsi.size_mb}M, start={pos}M' + if bootable: + spec += ', bootable' + pos += fsi.size_mb + + img_size = pos + try: + check_call(f'qemu-img create {self.fname} {img_size}M', shell=True) + check_call(f'printf "{spec}" | sfdisk {self.fname}', shell=True) + except CalledProcessError: + os.remove(self.fname) + raise + + pos = 1 # Reserve 1MB for the partition table itself + for fsi, part_type, bootable in self.fs_list: + check_call( + f'dd if={fsi.fs_img} of={self.fname} bs=1M seek={pos} conv=notrunc', + shell=True) + pos += fsi.size_mb + return self.fname + + def cleanup(self, remove_full_img=False): + """Remove created file""" + os.remove(self.fname) + + def __enter__(self): + return self + + def __exit__(self, extype, value, traceback): + self.cleanup() + + def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, fs_img=None, quiet=False): """Create a file system volume -- 2.43.0

Simplify this test by using the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_efi_bootmgr.py | 38 ++++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/test/py/tests/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr.py index 4c10cbdf17d..7d1f3f16d00 100644 --- a/test/py/tests/test_efi_bootmgr.py +++ b/test/py/tests/test_efi_bootmgr.py @@ -5,7 +5,7 @@ import shutil import pytest from subprocess import call, check_call, CalledProcessError -from tests import fs_helper +from tests.fs_helper import DiskHelper, FsHelper @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_efidebug') @@ -20,22 +20,19 @@ def test_efi_bootmgr(ubman): 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) + with DiskHelper(ubman.config, 0, 'test_efi_bootmgr') as img, \ + FsHelper(ubman.config, 'vfat', 1, 'test_efi_bootmgr') as fsh: + with open(f'{fsh.srcdir}/initrd-1.img', 'w', encoding = 'ascii') as outf: + outf.write("initrd 1") + with open(f'{fsh.srcdir}/initrd-2.img', 'w', encoding = 'ascii') as outf: + outf.write("initrd 2") + shutil.copyfile( + ubman.config.build_dir + '/lib/efi_loader/initrddump.efi', + f'{fsh.srcdir}/initrddump.efi') + fsh.mk_fs() + + img.add_fs(fsh, DiskHelper.VFAT) + efi_bootmgr_data = img.create() ubman.run_command(cmd = f'host bind 0 {efi_bootmgr_data}') @@ -61,10 +58,3 @@ def test_efi_bootmgr(ubman): 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) -- 2.43.0

Simplify this test-setup code by using the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_ut.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 85ba6e3f5c3..cb992a873c6 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -16,6 +16,7 @@ import pytest import utils # pylint: disable=E0611 from tests import fs_helper +from fs_helper import DiskHelper, FsHelper from test_android import test_abootimg def mkdir_cond(dirname): @@ -44,7 +45,6 @@ def setup_bootmenu_image(ubman): This is modelled on Armbian 22.08 Jammy """ mmc_dev = 4 - fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0x83) script = '''# DO NOT EDIT THIS FILE # @@ -120,7 +120,9 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} # Recompile with: # mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr ''' - bootdir = os.path.join(mnt, 'boot') + fsh = FsHelper(ubman.config, 'ext4', 18, 'mmc') + fsh.setup() + bootdir = os.path.join(fsh.srcdir, 'boot') mkdir_cond(bootdir) cmd_fname = os.path.join(bootdir, 'boot.cmd') scr_fname = os.path.join(bootdir, 'boot.scr') @@ -149,13 +151,12 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} utils.run_and_log( ubman, f'echo here {kernel} {symlink}') os.symlink(kernel, symlink) + fsh.mk_fs() + img = DiskHelper(ubman.config, mmc_dev, 'mmc') + img.add_fs(fsh, DiskHelper.EXT4) + img.create() + fsh.cleanup() - fsfile = 'ext18M.img' - utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}') - utils.run_and_log(ubman, f'mkfs.ext4 {fsfile} -d {mnt}') - copy_partition(ubman, fsfile, fname) - utils.run_and_log(ubman, f'rm -rf {mnt}') - utils.run_and_log(ubman, f'rm -f {fsfile}') def setup_bootflow_image(ubman, devnum, basename, vmlinux, initrd, dtbdir, script): -- 2.43.0

Simplify this test-setup code by using the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_ut.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index cb992a873c6..c3ed4bc6a11 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -171,10 +171,10 @@ def setup_bootflow_image(ubman, devnum, basename, vmlinux, initrd, dtbdir, dtbdir (str or None): Devicetree filename script (str): Script to place in the extlinux.conf file """ - fname, mnt = fs_helper.setup_image(ubman, devnum, 0xc, second_part=True, - basename=basename) + fsh = FsHelper(ubman.config, 'vfat', 18, prefix=basename) + fsh.setup() - ext = os.path.join(mnt, 'extlinux') + ext = os.path.join(fsh.srcdir, 'extlinux') mkdir_cond(ext) conf = os.path.join(ext, 'extlinux.conf') @@ -186,25 +186,31 @@ def setup_bootflow_image(ubman, devnum, basename, vmlinux, initrd, dtbdir, fd.write(gzip.compress(b'vmlinux')) mkimage = ubman.config.build_dir + '/tools/mkimage' utils.run_and_log( - ubman, f'{mkimage} -f auto -d {inf} {os.path.join(mnt, vmlinux)}') + ubman, f'{mkimage} -f auto -d {inf} {os.path.join(fsh.srcdir, vmlinux)}') - with open(os.path.join(mnt, initrd), 'w', encoding='ascii') as fd: + with open(os.path.join(fsh.srcdir, initrd), 'w', encoding='ascii') as fd: print('initrd', file=fd) if dtbdir: - mkdir_cond(os.path.join(mnt, dtbdir)) + mkdir_cond(os.path.join(fsh.srcdir, dtbdir)) - dtb_file = os.path.join(mnt, f'{dtbdir}/sandbox.dtb') + dtb_file = os.path.join(fsh.srcdir, f'{dtbdir}/sandbox.dtb') utils.run_and_log( ubman, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};') - fsfile = 'vfat18M.img' - 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}/* ::/']) - copy_partition(ubman, fsfile, fname) - utils.run_and_log(ubman, f'rm -rf {mnt}') - utils.run_and_log(ubman, f'rm -f {fsfile}') + fsh.mk_fs() + + img = DiskHelper(ubman.config, devnum, basename) + img.add_fs(fsh, DiskHelper.VFAT) + + ext4 = FsHelper(ubman.config, 'ext4', 1, prefix=basename) + ext4.setup() + ext4.mk_fs() + + img.add_fs(fsh, DiskHelper.VFAT) + img.add_fs(ext4, DiskHelper.EXT4) + img.create() + fsh.cleanup() def setup_fedora_image(ubman, devnum, basename): """Create a 20MB Fedora disk image with a single FAT partition -- 2.43.0

Simplify this test-setup code by using the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_ut.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index c3ed4bc6a11..7e2f224bac6 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -594,11 +594,9 @@ def test_ut_dm_init(ubman): def setup_efi_image(ubman): """Create a 20MB disk image with an EFI app on it""" devnum = 1 - basename = 'flash' - fname, mnt = fs_helper.setup_image(ubman, devnum, 0xc, second_part=True, - basename=basename) - - efi_dir = os.path.join(mnt, 'EFI') + fsh = FsHelper(ubman.config, 'vfat', 18, 'flash') + fsh.setup() + efi_dir = os.path.join(fsh.srcdir, 'EFI') mkdir_cond(efi_dir) bootdir = os.path.join(efi_dir, 'BOOT') mkdir_cond(bootdir) @@ -608,13 +606,14 @@ def setup_efi_image(ubman): with open(efi_src, 'rb') as inf: with open(efi_dst, 'wb') as outf: outf.write(inf.read()) - fsfile = 'vfat18M.img' - 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}/* ::/']) - copy_partition(ubman, fsfile, fname) - utils.run_and_log(ubman, f'rm -rf {mnt}') - utils.run_and_log(ubman, f'rm -f {fsfile}') + + fsh.mk_fs() + + img = DiskHelper(ubman.config, devnum, 'flash') + img.add_fs(fsh, DiskHelper.VFAT) + img.create() + fsh.cleanup() + @pytest.mark.buildconfigspec('cmd_bootflow') @pytest.mark.buildconfigspec('sandbox') -- 2.43.0

Use the helper here, for consistency. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/test_ut.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 7e2f224bac6..54813579db2 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -581,8 +581,8 @@ def test_ut_dm_init(ubman): utils.run_and_log( ubman, f'sfdisk {fn}', stdin=b'type=83') - fs_helper.mk_fs(ubman.config, 'ext2', 0x200000, '2MB', None) - fs_helper.mk_fs(ubman.config, 'fat32', 0x100000, '1MB', None) + FsHelper(ubman.config, 'ext2', 2, 'mmc').mk_fs() + FsHelper(ubman.config, 'fat32', 1, 'mmc').mk_fs() mmc_dev = 6 fn = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img') -- 2.43.0
participants (1)
-
Simon Glass