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