u-boot/test/py/tests/fs_helper.py
Marek Vasut 6592425c6d test_fs: Allow testing FS_GENERIC
The generic filesystem interface was so far untested. The interface
is similar to the FS specific interfaces with FS specific prefixes,
like ext4ls, fatmkdir, ... but it does not have any prefixes, i.e.
it provides plain ls, mkdir, ... commands.

Extend the test parameters to include 'fs_cmd_prefix' and optionally
'fs_cmd_write' parameters. The 'fs_cmd_prefix' allow specifying the
filesystem specific command prefix, like 'ext4' in 'ext4ls'. The
'fs_cmd_write' allows selecting between 'write'/'save' command name
for storing files into the filesystem, see last paragraph.

Introduce new 'fs_generic' fs_type which is used to parametrize existing
tests and run them without any prefixes if detected, thus testing the
generic filesystem interface. Use the fatfs as the backing store for the
generic FS tests.

The check_ubconfig needs to be slightly adjusted to avoid test for
CMD_FS_GENERIC_WRITE which does not exist separately from CMD_FS_GENERIC.

The CMD_FS_GENERIC does not provide generic 'write' command, instead
the generic equivalent command is called 'save' . Add simple ternary
oeprator to use 'save' command for CMD_FS_GENERIC tests and '..write'
commands for filesystem specific tests.

Enable generic filesystem tests for basic/extended/mkdir/unlink tests.

Signed-off-by: Marek Vasut <marex@denx.de>
2025-04-02 20:00:59 -06:00

78 lines
2.6 KiB
Python

# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2018, Linaro Limited
# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
"""Helper functions for dealing with filesystems"""
import re
import os
from subprocess import call, check_call, check_output, CalledProcessError
def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
"""Create a file system volume
Args:
config (u_boot_config): U-Boot configuration
fs_type (str): File system type, e.g. 'ext4'
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
Raises:
CalledProcessError: if any error occurs when creating the filesystem
"""
fs_img = f'{prefix}.{fs_type}.img'
fs_img = os.path.join(config.persistent_data_dir, fs_img)
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 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 != 'vfat':
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'
try:
check_call(f'rm -f {fs_img}', shell=True)
check_call(f'dd if=/dev/zero of={fs_img} bs={size_gran} count={count}',
shell=True)
check_call(f'mkfs.{fs_lnxtype} {mkfs_opt} {fs_img}', shell=True)
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:
check_call(f'mcopy -i {fs_img} -vsmpQ {src_dir}/* ::/', shell=True)
return fs_img
except CalledProcessError:
call(f'rm -f {fs_img}', shell=True)
raise
# Just for trying out
if __name__ == "__main__":
import collections
CNF= collections.namedtuple('config', 'persistent_data_dir')
mk_fs(CNF('.'), 'ext4', 0x1000000, 'pref')