summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <[email protected]>2026-04-04 08:03:05 -0600
committerTom Rini <[email protected]>2026-04-21 15:30:38 -0600
commit7c69117337412d2477bc3f72e4042bca4a4e66b3 (patch)
treec642be9676363db07134ffe3eac5b6b1fe8713a3
parent1c1bfb1cf34bbb2a5717eb6995c55093279f9341 (diff)
test: Add a helper class to create disk images
Provide a way to create disk images which consist of multiple filesystem images. Include a cur_dir option to place the disk image in the current directory rather than in the persistent-data directory. This matches the behaviour of setup_image() which places disk images in source_dir where sandbox expects to find them. This flag is a temporary feature and should be removed once all tests are migrated to use the persistent-data directory instead. Signed-off-by: Simon Glass <[email protected]>
-rw-r--r--test/py/tests/fs_helper.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py
index 800376b1e7d..e323a97b220 100644
--- a/test/py/tests/fs_helper.py
+++ b/test/py/tests/fs_helper.py
@@ -97,6 +97,98 @@ 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, cur_dir=False):
+ """Set up a new disk image
+
+ Args:
+ config (u_boot_config): U-Boot configuration
+ devnum (int): Device number (for filename)
+ prefix (str): Prefix string of volume's file name
+ cur_dir (bool): True to put the file in the current directory,
+ instead of the persistent-data directory
+ """
+ self.fs_list = []
+ self.fname = os.path.join('' if cur_dir else 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, fs_img=None, quiet=False):
"""Create a file system volume