Extend the test_fs test suite with tests to verify operations
related to FAT file renaming.

Signed-off-by: Daniel Venzin <daniel.ven...@mt.com>

---

Changes in v3:
- Verify FAT file rename functionality with unit tests

 test/py/tests/test_fs/conftest.py    | 75 ++++++++++++++++++++++
 test/py/tests/test_fs/test_rnfile.py | 93 ++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+)
 create mode 100644 test/py/tests/test_fs/test_rnfile.py

diff --git a/test/py/tests/test_fs/conftest.py 
b/test/py/tests/test_fs/conftest.py
index af2adaf1645..e9b08c693b2 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -16,6 +16,7 @@ supported_fs_basic = ['fat16', 'fat32', 'ext4']
 supported_fs_ext = ['fat12', 'fat16', 'fat32']
 supported_fs_fat = ['fat12', 'fat16']
 supported_fs_mkdir = ['fat12', 'fat16', 'fat32']
+supported_fs_rnfile = ['fat12', 'fat16', 'fat32']
 supported_fs_unlink = ['fat12', 'fat16', 'fat32']
 supported_fs_symlink = ['ext4']
 
@@ -53,6 +54,7 @@ def pytest_configure(config):
     global supported_fs_ext
     global supported_fs_fat
     global supported_fs_mkdir
+    global supported_fs_rnfile
     global supported_fs_unlink
     global supported_fs_symlink
 
@@ -66,6 +68,7 @@ def pytest_configure(config):
         supported_fs_ext =  intersect(supported_fs, supported_fs_ext)
         supported_fs_fat =  intersect(supported_fs, supported_fs_fat)
         supported_fs_mkdir =  intersect(supported_fs, supported_fs_mkdir)
+        supported_fs_rnfile = intersect(supported_fs, supported_fs_rnfile)
         supported_fs_unlink =  intersect(supported_fs, supported_fs_unlink)
         supported_fs_symlink =  intersect(supported_fs, supported_fs_symlink)
 
@@ -93,6 +96,9 @@ def pytest_generate_tests(metafunc):
     if 'fs_obj_mkdir' in metafunc.fixturenames:
         metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir,
             indirect=True, scope='module')
+    if 'fs_obj_rnfile' in metafunc.fixturenames:
+        metafunc.parametrize('fs_obj_rnfile', supported_fs_rnfile,
+            indirect=True, scope='module')
     if 'fs_obj_unlink' in metafunc.fixturenames:
         metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
             indirect=True, scope='module')
@@ -388,6 +394,75 @@ def fs_obj_mkdir(request, u_boot_config):
         yield [fs_ubtype, fs_img]
     call('rm -f %s' % fs_img, shell=True)
 
+#
+# Fixture for rnfile test
+#
+@pytest.fixture()
+def fs_obj_rnfile(request, u_boot_config):
+    """Set up a file system to be used in rnfile test.
+
+    Args:
+        request: Pytest request object.
+       u_boot_config: U-Boot configuration.
+
+    Return:
+        A fixture for rnfile test, i.e. a duplet of file system type and
+        volume file name.
+    """
+    fs_type = request.param
+    fs_img = ''
+
+    fs_ubtype = fstype_to_ubname(fs_type)
+    check_ubconfig(u_boot_config, fs_ubtype)
+
+    scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
+
+    try:
+        check_call('mkdir -p %s' % scratch_dir, shell=True)
+    except CalledProcessError as err:
+        pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type 
+ '. {}'.format(err))
+        call('rm -f %s' % fs_img, shell=True)
+        return
+
+    try:
+        # Test Case 1
+        check_call('mkdir %s/dir1' % scratch_dir, shell=True)
+        check_call('dd if=/dev/urandom of=%s/dir1/destination bs=1K count=1'
+                                    % scratch_dir, shell=True)
+
+        # Test Case 2
+        check_call('mkdir %s/dir2' % scratch_dir, shell=True)
+        check_call('dd if=/dev/urandom of=%s/dir2/source bs=1K count=1'
+                                    % scratch_dir, shell=True)
+        check_call('dd if=/dev/urandom of=%s/dir2/destination bs=1K count=1'
+                                    % scratch_dir, shell=True)
+
+        # Test Case 3
+        check_call('mkdir %s/dir3' % scratch_dir, shell=True)
+        check_call('dd if=/dev/urandom of=%s/dir3/source bs=1K count=1'
+                                    % scratch_dir, shell=True)
+
+        # Test Case 4
+        check_call('mkdir %s/dir4' % scratch_dir, shell=True)
+        check_call('dd if=/dev/urandom of=%s/dir4/source bs=1K count=1'
+                                    % scratch_dir, shell=True)
+
+        try:
+            # 128MiB volume
+            fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, 
'128MB', scratch_dir)
+        except CalledProcessError as err:
+            pytest.skip('Creating failed for filesystem: ' + fs_type + '. 
{}'.format(err))
+            return
+
+    except CalledProcessError:
+        pytest.skip('Setup failed for filesystem: ' + fs_type)
+        return
+    else:
+        yield [fs_ubtype, fs_img]
+    finally:
+        call('rm -rf %s' % scratch_dir, shell=True)
+        call('rm -f %s' % fs_img, shell=True)
+
 #
 # Fixture for unlink test
 #
diff --git a/test/py/tests/test_fs/test_rnfile.py 
b/test/py/tests/test_fs/test_rnfile.py
new file mode 100644
index 00000000000..dac4d0e3526
--- /dev/null
+++ b/test/py/tests/test_fs/test_rnfile.py
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright (c) 2025, Mettler-Toledo
+# Author: Daniel Venzin <daniel.ven...@mt.com>
+#
+# U-Boot File System:rnfile Test
+
+"""
+This test verifies rename file operation on file system.
+"""
+
+import pytest
+from fstest_helpers import assert_fs_integrity
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.slow
+class TestRnfile(object):
+    def test_rnfile1(self, u_boot_console, fs_obj_rnfile):
+        """
+        Test Case 1 - abort if source file does not exist
+        """
+        fs_type,fs_img = fs_obj_rnfile
+        with u_boot_console.log.section('Test Case 1 - rnfile (non-existing 
source)'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sls host 0:0 dir1' % fs_type])
+            assert('1 file(s), 2 dir(s)' in ''.join(output))
+            assert ('destination' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                '%srnfile host 0:0 dir1/source destination' % fs_type,
+                '%sls host 0:0 dir1' % fs_type])
+            assert('1 file(s), 2 dir(s)' in ''.join(output))
+            assert ('destination' in ''.join(output))
+            assert('Unable to rename file' in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)
+
+    def test_rnfile2(self, u_boot_console, fs_obj_rnfile):
+        """
+        Test Case 2 - abort if destination file exist
+        """
+        fs_type,fs_img = fs_obj_rnfile
+        with u_boot_console.log.section('Test Case 2 - rnfile (existing 
destination)'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sls host 0:0 dir2' % fs_type])
+            assert('2 file(s), 2 dir(s)' in ''.join(output))
+            assert('source' in ''.join(output))
+            assert('destination' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                '%srnfile host 0:0 dir2/source destination' % fs_type,
+                '%sls host 0:0 dir2' % fs_type])
+            assert('2 file(s), 2 dir(s)' in ''.join(output))
+            assert('source' in ''.join(output))
+            assert('destination' in ''.join(output))
+            assert('Unable to rename file' in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)
+
+    def test_rnfile3(self, u_boot_console, fs_obj_rnfile):
+        """
+        Test Case 3 - abort on move operation (destination at new path)
+        """
+        fs_type,fs_img = fs_obj_rnfile
+        with u_boot_console.log.section('Test Case 3 - rnfile (abort on 
move)'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sls host 0:0 dir3' % fs_type])
+            assert('1 file(s), 2 dir(s)' in ''.join(output))
+            assert('source' in ''.join(output))
+
+            output = u_boot_console.run_command(
+                '%srnfile host 0:0 dir3/source dir3/destination' % fs_type)
+            assert('Unable to rename file' in output)
+            assert_fs_integrity(fs_type, fs_img)
+
+    def test_rnfile4(self, u_boot_console, fs_obj_rnfile):
+        """
+        Test Case 4 - rnfile
+        """
+        fs_type,fs_img = fs_obj_rnfile
+        with u_boot_console.log.section('Test Case 4 - rnfile'):
+            output = u_boot_console.run_command_list([
+                'host bind 0 %s' % fs_img,
+                '%sls host 0:0 dir4' % fs_type])
+            assert('1 file(s), 2 dir(s)' in ''.join(output))
+            assert('source' in ''.join(output))
+
+            output = u_boot_console.run_command_list([
+                '%srnfile host 0:0 dir4/source destination' % fs_type,
+                '%sls host 0:0 dir4' % fs_type])
+            assert('1 file(s), 2 dir(s)' in ''.join(output))
+            assert('destination' in ''.join(output))
+            assert_fs_integrity(fs_type, fs_img)
-- 
2.39.5

Reply via email to