diff options
Diffstat (limited to 'test/py')
-rw-r--r-- | test/py/tests/test_fs/conftest.py | 121 | ||||
-rw-r--r-- | test/py/tests/test_fs/fstest_helpers.py | 2 | ||||
-rw-r--r-- | test/py/tests/test_fs/test_rename.py | 372 |
3 files changed, 495 insertions, 0 deletions
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py index af2adaf1645..7bfcf41ed6f 100644 --- a/test/py/tests/test_fs/conftest.py +++ b/test/py/tests/test_fs/conftest.py @@ -18,6 +18,7 @@ supported_fs_fat = ['fat12', 'fat16'] supported_fs_mkdir = ['fat12', 'fat16', 'fat32'] supported_fs_unlink = ['fat12', 'fat16', 'fat32'] supported_fs_symlink = ['ext4'] +supported_fs_rename = ['fat12', 'fat16', 'fat32'] # # Filesystem test specific setup @@ -55,6 +56,7 @@ def pytest_configure(config): global supported_fs_mkdir global supported_fs_unlink global supported_fs_symlink + global supported_fs_rename def intersect(listA, listB): return [x for x in listA if x in listB] @@ -68,6 +70,7 @@ def pytest_configure(config): supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir) supported_fs_unlink = intersect(supported_fs, supported_fs_unlink) supported_fs_symlink = intersect(supported_fs, supported_fs_symlink) + supported_fs_rename = intersect(supported_fs, supported_fs_rename) def pytest_generate_tests(metafunc): """Parametrize fixtures, fs_obj_xxx @@ -99,6 +102,9 @@ def pytest_generate_tests(metafunc): if 'fs_obj_symlink' in metafunc.fixturenames: metafunc.parametrize('fs_obj_symlink', supported_fs_symlink, indirect=True, scope='module') + if 'fs_obj_rename' in metafunc.fixturenames: + metafunc.parametrize('fs_obj_rename', supported_fs_rename, + indirect=True, scope='module') # # Helper functions @@ -528,6 +534,121 @@ def fs_obj_symlink(request, u_boot_config): call('rm -f %s' % fs_img, shell=True) # +# Fixture for rename test +# +@pytest.fixture() +def fs_obj_rename(request, u_boot_config): + """Set up a file system to be used in rename tests. + + Args: + request: Pytest request object. + u_boot_config: U-Boot configuration. + + Return: + A fixture for rename tests, i.e. a triplet of file system type, + volume file name, and dictionary of test identifier and md5val. + """ + def new_rand_file(path): + check_call('dd if=/dev/urandom of=%s bs=1K count=1' % path, shell=True) + + def file_hash(path): + out = check_output( + 'dd if=%s bs=1K skip=0 count=1 2> /dev/null | md5sum' % path, + shell=True + ) + return out.decode().split()[0] + + fs_type = request.param + fs_img = '' + + fs_ubtype = fstype_to_ubname(fs_type) + check_ubconfig(u_boot_config, fs_ubtype) + + mount_dir = u_boot_config.persistent_data_dir + '/scratch' + + try: + check_call('mkdir -p %s' % mount_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: + md5val = {} + # Test Case 1 + check_call('mkdir %s/test1' % mount_dir, shell=True) + new_rand_file('%s/test1/file1' % mount_dir) + md5val['test1'] = file_hash('%s/test1/file1' % mount_dir) + + # Test Case 2 + check_call('mkdir %s/test2' % mount_dir, shell=True) + new_rand_file('%s/test2/file1' % mount_dir) + new_rand_file('%s/test2/file_exist' % mount_dir) + md5val['test2'] = file_hash('%s/test2/file1' % mount_dir) + + # Test Case 3 + check_call('mkdir -p %s/test3/dir1' % mount_dir, shell=True) + new_rand_file('%s/test3/dir1/file1' % mount_dir) + md5val['test3'] = file_hash('%s/test3/dir1/file1' % mount_dir) + + # Test Case 4 + check_call('mkdir -p %s/test4/dir1' % mount_dir, shell=True) + check_call('mkdir -p %s/test4/dir2/dir1' % mount_dir, shell=True) + new_rand_file('%s/test4/dir1/file1' % mount_dir) + md5val['test4'] = file_hash('%s/test4/dir1/file1' % mount_dir) + + # Test Case 5 + check_call('mkdir -p %s/test5/dir1' % mount_dir, shell=True) + new_rand_file('%s/test5/file2' % mount_dir) + md5val['test5'] = file_hash('%s/test5/file2' % mount_dir) + + # Test Case 6 + check_call('mkdir -p %s/test6/dir2/existing' % mount_dir, shell=True) + new_rand_file('%s/test6/existing' % mount_dir) + md5val['test6'] = file_hash('%s/test6/existing' % mount_dir) + + # Test Case 7 + check_call('mkdir -p %s/test7/dir1' % mount_dir, shell=True) + check_call('mkdir -p %s/test7/dir2/dir1' % mount_dir, shell=True) + new_rand_file('%s/test7/dir2/dir1/file1' % mount_dir) + md5val['test7'] = file_hash('%s/test7/dir2/dir1/file1' % mount_dir) + + # Test Case 8 + check_call('mkdir -p %s/test8/dir1' % mount_dir, shell=True) + new_rand_file('%s/test8/dir1/file1' % mount_dir) + md5val['test8'] = file_hash('%s/test8/dir1/file1' % mount_dir) + + # Test Case 9 + check_call('mkdir -p %s/test9/dir1/nested/inner' % mount_dir, shell=True) + new_rand_file('%s/test9/dir1/nested/inner/file1' % mount_dir) + + # Test Case 10 + check_call('mkdir -p %s/test10' % mount_dir, shell=True) + new_rand_file('%s/test10/file1' % mount_dir) + md5val['test10'] = file_hash('%s/test10/file1' % mount_dir) + + # Test Case 11 + check_call('mkdir -p %s/test11/dir1' % mount_dir, shell=True) + new_rand_file('%s/test11/dir1/file1' % mount_dir) + md5val['test11'] = file_hash('%s/test11/dir1/file1' % mount_dir) + + try: + # 128MiB volume + fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', mount_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, md5val] + finally: + call('rm -rf %s' % mount_dir, shell=True) + call('rm -f %s' % fs_img, shell=True) + +# # Fixture for fat test # @pytest.fixture() diff --git a/test/py/tests/test_fs/fstest_helpers.py b/test/py/tests/test_fs/fstest_helpers.py index faec2982489..c1447b4d43e 100644 --- a/test/py/tests/test_fs/fstest_helpers.py +++ b/test/py/tests/test_fs/fstest_helpers.py @@ -9,5 +9,7 @@ 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 in ['fat12', 'fat16', 'fat32']: + check_call('fsck.fat -n %s' % fs_img, shell=True) except CalledProcessError: raise diff --git a/test/py/tests/test_fs/test_rename.py b/test/py/tests/test_fs/test_rename.py new file mode 100644 index 00000000000..df2b2fd2945 --- /dev/null +++ b/test/py/tests/test_fs/test_rename.py @@ -0,0 +1,372 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2025 Gabriel Dalimonte <gabriel.dalimonte@gmail.com> +# +# U-Boot File System:rename Test + + +import pytest + +from fstest_defs import * +from fstest_helpers import assert_fs_integrity + +@pytest.mark.boardspec('sandbox') +@pytest.mark.slow +class TestRename(object): + def test_rename1(self, u_boot_console, fs_obj_rename): + """ + Test Case 1 - rename a file (successful mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 1 - rename a file'): + d = 'test1' + src = '%s/file1' % d + dst = '%s/file2' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s' % (ADDR, dst), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('file1' not in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test1'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename2(self, u_boot_console, fs_obj_rename): + """ + Test Case 2 - rename a file to an existing file (successful mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 2 - rename a file to an existing file'): + d = 'test2' + src = '%s/file1' % d + dst = '%s/file_exist' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s' % (ADDR, dst), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('file1' not in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test2'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename3(self, u_boot_console, fs_obj_rename): + """ + Test Case 3 - rename a directory (successful mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 3 - rename a directory'): + d = 'test3' + src = '%s/dir1' % d + dst = '%s/dir2' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s/file1' % (ADDR, dst), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir1' not in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test3'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename4(self, u_boot_console, fs_obj_rename): + """ + Test Case 4 - rename a directory to an existing directory (successful + mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 4 - rename a directory to an existing directory'): + d = 'test4' + src = '%s/dir1' % d + dst = '%s/dir2' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s/dir1/file1' % (ADDR, dst), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir1' not in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test4'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename5(self, u_boot_console, fs_obj_rename): + """ + Test Case 5 - rename a directory to an existing file (failed mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 5 - rename a directory to an existing file'): + d = 'test5' + src = '%s/dir1' % d + dst = '%s/file2' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir1' in ''.join(output)) + assert('file2' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s' % (ADDR, dst), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test5'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename6(self, u_boot_console, fs_obj_rename): + """ + Test Case 6 - rename a file to an existing empty directory (failed mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 6 - rename a file to an existing empty directory'): + d = 'test6' + src = '%s/existing' % d + dst = '%s/dir2' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s' % (ADDR, src), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir2' in ''.join(output)) + assert('existing' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test6'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename7(self, u_boot_console, fs_obj_rename): + """ + Test Case 7 - rename a directory to a non-empty directory (failed mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 7 - rename a directory to a non-empty directory'): + d = 'test7' + src = '%s/dir1' % d + dst = '%s/dir2' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s/dir1/file1' % (ADDR, dst), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir1' in ''.join(output)) + assert('dir2' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test7'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename8(self, u_boot_console, fs_obj_rename): + """ + Test Case 8 - rename a directory inside itself (failed mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 8 - rename a directory inside itself'): + d = 'test8' + src = '%s/dir1' % d + dst = '%s/dir1/dir1' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s/file1' % (ADDR, src), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir1' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (src), + ]) + assert('file1' in ''.join(output)) + assert('dir1' not in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test8'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename9(self, u_boot_console, fs_obj_rename): + """ + Test Case 9 - rename a directory inside itself with backtracks (failed + mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 9 - rename a directory inside itself with backtracks'): + d = 'test9' + src = '%s/dir1/nested' % d + dst = '%s/dir1/nested/inner/./../../../dir1/nested/inner/another' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, dst), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s/dir1' % (d), + ]) + assert('nested' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (src), + ]) + assert('inner' in ''.join(output)) + assert('nested' not in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename10(self, u_boot_console, fs_obj_rename): + """ + Test Case 10 - rename a file to itself (successful mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 10 - rename a file to itself'): + d = 'test10' + src = '%s/file1' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, src), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s' % (ADDR, src), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('file1' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test10'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) + + def test_rename11(self, u_boot_console, fs_obj_rename): + """ + Test Case 11 - rename a directory to itself (successful mv) + """ + fs_type, fs_img, md5val = fs_obj_rename + with u_boot_console.log.section('Test Case 11 - rename a directory to itself'): + # / at the end here is intentional. Ensures trailing / doesn't + # affect mv producing an updated dst path for fs_rename + d = 'test11/' + src = '%sdir1' % d + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + 'setenv filesize', + 'mv host 0:0 %s %s' % (src, d), + ]) + assert('' == ''.join(output)) + + output = u_boot_console.run_command_list([ + 'load host 0:0 %x /%s/file1' % (ADDR, src), + 'printenv filesize']) + assert('filesize=400' in output) + + output = u_boot_console.run_command_list([ + 'ls host 0:0 %s' % (d), + ]) + assert('dir1' in ''.join(output)) + + output = u_boot_console.run_command_list([ + 'md5sum %x $filesize' % ADDR, + 'setenv filesize']) + assert(md5val['test11'] in ''.join(output)) + assert_fs_integrity(fs_type, fs_img) |