]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
test_fs: Add exfat tests
authorMarek Vasut <marex@denx.de>
Mon, 17 Mar 2025 03:12:50 +0000 (04:12 +0100)
committerTom Rini <trini@konsulko.com>
Thu, 3 Apr 2025 02:00:59 +0000 (20:00 -0600)
Add tests for the exfat filesystem. These tests are largely an
extension of the FS_GENERIC tests with the following notable
exceptions.

The filesystem image for exfat tests is generated using combination
of exfatprogs mkfs.exfat and python fattools. The fattols are capable
of generating exfat filesystem images too, but this is not used, the
fattools are only used as a replacement for dosfstools 'mcopy' and
'mdir', which are used to insert files and directories into existing
fatfs images and list existing fatfs images respectively, without the
need for superuser access to mount such images.

The exfat filesystem has no filesystem specific command, there is only
the generic filesystem command interface, therefore check_ubconfig()
has to special case exfat and skip check for CONFIG_CMD_EXFAT and
instead check for CONFIG_FS_EXFAT.

Signed-off-by: Marek Vasut <marex@denx.de>
test/py/requirements.txt
test/py/tests/fs_helper.py
test/py/tests/test_fs/conftest.py
test/py/tests/test_fs/fstest_helpers.py
test/py/tests/test_fs/test_ext.py
tools/docker/Dockerfile

index acfe17dce9f0f7f31af9cee93cec80a55b8e52ec..804a427b3514d144450aa2d8e41e392c6c0da146 100644 (file)
@@ -2,3 +2,4 @@ filelock==3.0.12
 pycryptodomex==3.21.0
 pytest==6.2.5
 pytest-xdist==2.5.0
+FATtools==1.0.42
index 378d5ae06906d857dd3305402abc0f5dcd86db78..94a5b94f4796bc5ab0aaced756741b0c46264da5 100644 (file)
@@ -35,7 +35,9 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
     else:
         mkfs_opt = ''
 
-    if re.match('fat', fs_type) or fs_type == 'fs_generic':
+    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
@@ -43,7 +45,7 @@ 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':
+        elif fs_lnxtype != 'vfat' and fs_lnxtype != 'exfat':
             raise ValueError(f'src_dir not implemented for fs {fs_lnxtype}')
 
     count = (size + size_gran - 1) // size_gran
@@ -64,6 +66,8 @@ def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000):
                 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)
+        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)
index 691bdf41ede0203abb6b28f3463bba9682869954..c73fb4abbcbfcb81b10513020d8d871d6a668ec6 100644 (file)
@@ -11,11 +11,11 @@ from fstest_defs import *
 # pylint: disable=E0611
 from tests import fs_helper
 
-supported_fs_basic = ['fat16', 'fat32', 'ext4', 'fs_generic']
-supported_fs_ext = ['fat12', 'fat16', 'fat32', 'fs_generic']
+supported_fs_basic = ['fat16', 'fat32', 'exfat', 'ext4', 'fs_generic']
+supported_fs_ext = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
 supported_fs_fat = ['fat12', 'fat16']
-supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'fs_generic']
-supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'fs_generic']
+supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
+supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
 supported_fs_symlink = ['ext4']
 supported_fs_rename = ['fat12', 'fat16', 'fat32']
 
@@ -117,7 +117,7 @@ def fstype_to_prefix(fs_type):
     Return:
         A corresponding command prefix for file system type.
     """
-    if fs_type == 'fs_generic':
+    if fs_type == 'fs_generic' or fs_type == 'exfat':
         return ''
     elif re.match('fat', fs_type):
         return 'fat'
@@ -155,9 +155,11 @@ def check_ubconfig(config, fs_type):
     Return:
         Nothing.
     """
-    if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
+    if fs_type == 'exfat' and not config.buildconfig.get('config_fs_%s' % fs_type, None):
+        pytest.skip('.config feature "FS_%s" not enabled' % fs_type.upper())
+    if fs_type != 'exfat' and not config.buildconfig.get('config_cmd_%s' % fs_type, None):
         pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
-    if fs_type == 'fs_generic':
+    if fs_type == 'fs_generic' or fs_type == 'exfat':
         return
     if not config.buildconfig.get('config_%s_write' % fs_type, None):
         pytest.skip('.config feature "%s_WRITE" not enabled'
@@ -197,7 +199,7 @@ def fs_obj_basic(request, u_boot_config):
     """
     fs_type = request.param
     fs_cmd_prefix = fstype_to_prefix(fs_type)
-    fs_cmd_write = 'save' if fs_type == 'fs_generic' else 'write'
+    fs_cmd_write = 'save' if fs_type == 'fs_generic' or fs_type == 'exfat' else 'write'
     fs_img = ''
 
     fs_ubtype = fstype_to_ubname(fs_type)
@@ -309,7 +311,7 @@ def fs_obj_ext(request, u_boot_config):
     """
     fs_type = request.param
     fs_cmd_prefix = fstype_to_prefix(fs_type)
-    fs_cmd_write = 'save' if fs_type == 'fs_generic' else 'write'
+    fs_cmd_write = 'save' if fs_type == 'fs_generic' or fs_type == 'exfat' else 'write'
     fs_img = ''
 
     fs_ubtype = fstype_to_ubname(fs_type)
index c1447b4d43e02b1084ddce07eec9591bd62d8b82..d25326ee993a499590f58e86c9e9b475ee0e7df5 100644 (file)
@@ -9,6 +9,8 @@ def assert_fs_integrity(fs_type, fs_img):
     try:
         if fs_type == 'ext4':
             check_call('fsck.ext4 -n -f %s' % fs_img, shell=True)
+        elif fs_type == 'exfat':
+            check_call('fsck.exfat -n %s' % fs_img, shell=True)
         elif fs_type in ['fat12', 'fat16', 'fat32']:
             check_call('fsck.fat -n %s' % fs_img, shell=True)
     except CalledProcessError:
index a75cd74dade8f8fec8484bc5fb92e2f4706fe455..41f126e7876ec7cbcac5b8a321b4b5e7a2438cbb 100644 (file)
@@ -345,11 +345,19 @@ class TestFsExt(object):
                 '%s%s host 0:0 %x /%s 0'
                     % (fs_cmd_prefix, fs_cmd_write, ADDR, MANGLE_FILE)])
             assert('0 bytes written' in ''.join(output))
-            # Test Case 12b - Read file system content
-            output = check_output('mdir -i %s' % fs_img, shell=True).decode()
-            # Test Case 12c - Check if short filename is not mangled
-            assert(str2fat(PLAIN_FILE) in ''.join(output))
-            # Test Case 12d - Check if long filename is mangled
-            assert(str2fat(MANGLE_FILE) in ''.join(output))
+            if fs_type == 'exfat':
+                # Test Case 12b - Read file system content
+                output = check_output('fattools ls %s' % fs_img, shell=True).decode()
+                # Test Case 12c - Check if short filename is not mangled
+                assert(PLAIN_FILE in ''.join(output))
+                # Test Case 12d - Check if long filename is mangled
+                assert(MANGLE_FILE in ''.join(output))
+            else:
+                # Test Case 12b - Read file system content
+                output = check_output('mdir -i %s' % fs_img, shell=True).decode()
+                # Test Case 12c - Check if short filename is not mangled
+                assert(str2fat(PLAIN_FILE) in ''.join(output))
+                # Test Case 12d - Check if long filename is mangled
+                assert(str2fat(MANGLE_FILE) in ''.join(output))
 
             assert_fs_integrity(fs_type, fs_img)
index 569912303fc971131cc4afc1b760a5dfe963989a..80e9247aa6055ca513fea82fda31cefcdf162930 100644 (file)
@@ -74,6 +74,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
        e2fsprogs \
        efitools \
        erofs-utils \
+       exfatprogs \
        expect \
        fakeroot \
        flex \