# SPDX-License-Identifier: GPL-2.0+ # Copyright (C) 2022 Huang Jianan # Author: Huang Jianan import os import pytest import shutil import subprocess EROFS_SRC_DIR = 'erofs_src_dir' EROFS_IMAGE_NAME = 'erofs.img' def generate_file(name, size): """ Generates a file filled with 'x'. """ content = 'x' * size file = open(name, 'w') file.write(content) file.close() def make_erofs_image(build_dir): """ Makes the EROFS images used for the test. The image is generated at build_dir with the following structure: erofs_src_dir/ ├── f4096 ├── f7812 ├── subdir/ │   └── subdir-file ├── symdir -> subdir └── symfile -> f5096 """ root = os.path.join(build_dir, EROFS_SRC_DIR) os.makedirs(root) # 4096: uncompressed file generate_file(os.path.join(root, 'f4096'), 4096) # 7812: Compressed file generate_file(os.path.join(root, 'f7812'), 7812) # sub-directory with a single file inside subdir_path = os.path.join(root, 'subdir') os.makedirs(subdir_path) generate_file(os.path.join(subdir_path, 'subdir-file'), 100) # symlink os.symlink('subdir', os.path.join(root, 'symdir')) os.symlink('f7812', os.path.join(root, 'symfile')) input_path = os.path.join(build_dir, EROFS_SRC_DIR) output_path = os.path.join(build_dir, EROFS_IMAGE_NAME) args = ' '.join([output_path, input_path]) subprocess.run(['mkfs.erofs -zlz4 ' + args], shell=True, check=True, stdout=subprocess.DEVNULL) def clean_erofs_image(build_dir): """ Deletes the image and src_dir at build_dir. """ path = os.path.join(build_dir, EROFS_SRC_DIR) shutil.rmtree(path) image_path = os.path.join(build_dir, EROFS_IMAGE_NAME) os.remove(image_path) def erofs_ls_at_root(u_boot_console): """ Test if all the present files and directories were listed. """ no_slash = u_boot_console.run_command('erofsls host 0') slash = u_boot_console.run_command('erofsls host 0 /') assert no_slash == slash expected_lines = ['./', '../', '4096 f4096', '7812 f7812', 'subdir/', ' symdir', ' symfile', '4 file(s), 3 dir(s)'] output = u_boot_console.run_command('erofsls host 0') for line in expected_lines: assert line in output def erofs_ls_at_subdir(u_boot_console): """ Test if the path resolution works. """ expected_lines = ['./', '../', '100 subdir-file', '1 file(s), 2 dir(s)'] output = u_boot_console.run_command('erofsls host 0 subdir') for line in expected_lines: assert line in output def erofs_ls_at_symlink(u_boot_console): """ Test if the symbolic link's target resolution works. """ output = u_boot_console.run_command('erofsls host 0 symdir') output_subdir = u_boot_console.run_command('erofsls host 0 subdir') assert output == output_subdir expected_lines = ['./', '../', '100 subdir-file', '1 file(s), 2 dir(s)'] for line in expected_lines: assert line in output def erofs_ls_at_non_existent_dir(u_boot_console): """ Test if the EROFS support will crash when get a nonexistent directory. """ out_non_existent = u_boot_console.run_command('erofsls host 0 fff') out_not_dir = u_boot_console.run_command('erofsls host 0 f1000') assert out_non_existent == out_not_dir assert '' in out_non_existent def erofs_load_files(u_boot_console, files, sizes, address): """ Loads files and asserts their checksums. """ build_dir = u_boot_console.config.build_dir for (file, size) in zip(files, sizes): out = u_boot_console.run_command('erofsload host 0 {} {}'.format(address, file)) # check if the right amount of bytes was read assert size in out # calculate u-boot file's checksum out = u_boot_console.run_command('md5sum {} {}'.format(address, hex(int(size)))) u_boot_checksum = out.split()[-1] # calculate original file's checksum original_file_path = os.path.join(build_dir, EROFS_SRC_DIR + '/' + file) out = subprocess.run(['md5sum ' + original_file_path], shell=True, check=True, capture_output=True, text=True) original_checksum = out.stdout.split()[0] # compare checksum assert u_boot_checksum == original_checksum def erofs_load_files_at_root(u_boot_console): """ Test load file from the root directory. """ files = ['f4096', 'f7812'] sizes = ['4096', '7812'] address = '$kernel_addr_r' erofs_load_files(u_boot_console, files, sizes, address) def erofs_load_files_at_subdir(u_boot_console): """ Test load file from the subdirectory. """ files = ['subdir/subdir-file'] sizes = ['100'] address = '$kernel_addr_r' erofs_load_files(u_boot_console, files, sizes, address) def erofs_load_files_at_symlink(u_boot_console): """ Test load file from the symlink. """ files = ['symfile'] sizes = ['7812'] address = '$kernel_addr_r' erofs_load_files(u_boot_console, files, sizes, address) def erofs_load_non_existent_file(u_boot_console): """ Test if the EROFS support will crash when load a nonexistent file. """ address = '$kernel_addr_r' file = 'non-existent' out = u_boot_console.run_command('erofsload host 0 {} {}'.format(address, file)) assert 'Failed to load' in out def erofs_run_all_tests(u_boot_console): """ Runs all test cases. """ erofs_ls_at_root(u_boot_console) erofs_ls_at_subdir(u_boot_console) erofs_ls_at_symlink(u_boot_console) erofs_ls_at_non_existent_dir(u_boot_console) erofs_load_files_at_root(u_boot_console) erofs_load_files_at_subdir(u_boot_console) erofs_load_files_at_symlink(u_boot_console) erofs_load_non_existent_file(u_boot_console) @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_fs_generic') @pytest.mark.buildconfigspec('cmd_erofs') @pytest.mark.buildconfigspec('fs_erofs') @pytest.mark.requiredtool('mkfs.erofs') @pytest.mark.requiredtool('md5sum') def test_erofs(u_boot_console): """ Executes the erofs test suite. """ build_dir = u_boot_console.config.build_dir try: # setup test environment make_erofs_image(build_dir) image_path = os.path.join(build_dir, EROFS_IMAGE_NAME) u_boot_console.run_command('host bind 0 {}'.format(image_path)) # run all tests erofs_run_all_tests(u_boot_console) except: clean_erofs_image(build_dir) raise AssertionError # clean test environment clean_erofs_image(build_dir)