1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (C) 2022 Huang Jianan <jnhuang95@gmail.com> 3# Author: Huang Jianan <jnhuang95@gmail.com> 4 5import os 6import pytest 7import shutil 8import subprocess 9 10EROFS_SRC_DIR = 'erofs_src_dir' 11EROFS_IMAGE_NAME = 'erofs.img' 12 13def generate_file(name, size): 14 """ 15 Generates a file filled with 'x'. 16 """ 17 content = 'x' * size 18 file = open(name, 'w') 19 file.write(content) 20 file.close() 21 22def make_erofs_image(build_dir): 23 """ 24 Makes the EROFS images used for the test. 25 26 The image is generated at build_dir with the following structure: 27 erofs_src_dir/ 28 ├── f4096 29 ├── f7812 30 ├── subdir/ 31 │ └── subdir-file 32 ├── symdir -> subdir 33 └── symfile -> f5096 34 """ 35 root = os.path.join(build_dir, EROFS_SRC_DIR) 36 os.makedirs(root) 37 38 # 4096: uncompressed file 39 generate_file(os.path.join(root, 'f4096'), 4096) 40 41 # 7812: Compressed file 42 generate_file(os.path.join(root, 'f7812'), 7812) 43 44 # sub-directory with a single file inside 45 subdir_path = os.path.join(root, 'subdir') 46 os.makedirs(subdir_path) 47 generate_file(os.path.join(subdir_path, 'subdir-file'), 100) 48 49 # symlink 50 os.symlink('subdir', os.path.join(root, 'symdir')) 51 os.symlink('f7812', os.path.join(root, 'symfile')) 52 53 input_path = os.path.join(build_dir, EROFS_SRC_DIR) 54 output_path = os.path.join(build_dir, EROFS_IMAGE_NAME) 55 args = ' '.join([output_path, input_path]) 56 subprocess.run(['mkfs.erofs -zlz4 ' + args], shell=True, check=True, 57 stdout=subprocess.DEVNULL) 58 59def clean_erofs_image(build_dir): 60 """ 61 Deletes the image and src_dir at build_dir. 62 """ 63 path = os.path.join(build_dir, EROFS_SRC_DIR) 64 shutil.rmtree(path) 65 image_path = os.path.join(build_dir, EROFS_IMAGE_NAME) 66 os.remove(image_path) 67 68def erofs_ls_at_root(u_boot_console): 69 """ 70 Test if all the present files and directories were listed. 71 """ 72 no_slash = u_boot_console.run_command('erofsls host 0') 73 slash = u_boot_console.run_command('erofsls host 0 /') 74 assert no_slash == slash 75 76 expected_lines = ['./', '../', '4096 f4096', '7812 f7812', 'subdir/', 77 '<SYM> symdir', '<SYM> symfile', '4 file(s), 3 dir(s)'] 78 79 output = u_boot_console.run_command('erofsls host 0') 80 for line in expected_lines: 81 assert line in output 82 83def erofs_ls_at_subdir(u_boot_console): 84 """ 85 Test if the path resolution works. 86 """ 87 expected_lines = ['./', '../', '100 subdir-file', '1 file(s), 2 dir(s)'] 88 output = u_boot_console.run_command('erofsls host 0 subdir') 89 for line in expected_lines: 90 assert line in output 91 92def erofs_ls_at_symlink(u_boot_console): 93 """ 94 Test if the symbolic link's target resolution works. 95 """ 96 output = u_boot_console.run_command('erofsls host 0 symdir') 97 output_subdir = u_boot_console.run_command('erofsls host 0 subdir') 98 assert output == output_subdir 99 100 expected_lines = ['./', '../', '100 subdir-file', '1 file(s), 2 dir(s)'] 101 for line in expected_lines: 102 assert line in output 103 104def erofs_ls_at_non_existent_dir(u_boot_console): 105 """ 106 Test if the EROFS support will crash when get a nonexistent directory. 107 """ 108 out_non_existent = u_boot_console.run_command('erofsls host 0 fff') 109 out_not_dir = u_boot_console.run_command('erofsls host 0 f1000') 110 assert out_non_existent == out_not_dir 111 assert '' in out_non_existent 112 113def erofs_load_files(u_boot_console, files, sizes, address): 114 """ 115 Loads files and asserts their checksums. 116 """ 117 build_dir = u_boot_console.config.build_dir 118 for (file, size) in zip(files, sizes): 119 out = u_boot_console.run_command('erofsload host 0 {} {}'.format(address, file)) 120 121 # check if the right amount of bytes was read 122 assert size in out 123 124 # calculate u-boot file's checksum 125 out = u_boot_console.run_command('md5sum {} {}'.format(address, hex(int(size)))) 126 u_boot_checksum = out.split()[-1] 127 128 # calculate original file's checksum 129 original_file_path = os.path.join(build_dir, EROFS_SRC_DIR + '/' + file) 130 out = subprocess.run(['md5sum ' + original_file_path], shell=True, check=True, 131 capture_output=True, text=True) 132 original_checksum = out.stdout.split()[0] 133 134 # compare checksum 135 assert u_boot_checksum == original_checksum 136 137def erofs_load_files_at_root(u_boot_console): 138 """ 139 Test load file from the root directory. 140 """ 141 files = ['f4096', 'f7812'] 142 sizes = ['4096', '7812'] 143 address = '$kernel_addr_r' 144 erofs_load_files(u_boot_console, files, sizes, address) 145 146def erofs_load_files_at_subdir(u_boot_console): 147 """ 148 Test load file from the subdirectory. 149 """ 150 files = ['subdir/subdir-file'] 151 sizes = ['100'] 152 address = '$kernel_addr_r' 153 erofs_load_files(u_boot_console, files, sizes, address) 154 155def erofs_load_files_at_symlink(u_boot_console): 156 """ 157 Test load file from the symlink. 158 """ 159 files = ['symfile'] 160 sizes = ['7812'] 161 address = '$kernel_addr_r' 162 erofs_load_files(u_boot_console, files, sizes, address) 163 164def erofs_load_non_existent_file(u_boot_console): 165 """ 166 Test if the EROFS support will crash when load a nonexistent file. 167 """ 168 address = '$kernel_addr_r' 169 file = 'non-existent' 170 out = u_boot_console.run_command('erofsload host 0 {} {}'.format(address, file)) 171 assert 'Failed to load' in out 172 173def erofs_run_all_tests(u_boot_console): 174 """ 175 Runs all test cases. 176 """ 177 erofs_ls_at_root(u_boot_console) 178 erofs_ls_at_subdir(u_boot_console) 179 erofs_ls_at_symlink(u_boot_console) 180 erofs_ls_at_non_existent_dir(u_boot_console) 181 erofs_load_files_at_root(u_boot_console) 182 erofs_load_files_at_subdir(u_boot_console) 183 erofs_load_files_at_symlink(u_boot_console) 184 erofs_load_non_existent_file(u_boot_console) 185 186@pytest.mark.boardspec('sandbox') 187@pytest.mark.buildconfigspec('cmd_fs_generic') 188@pytest.mark.buildconfigspec('cmd_erofs') 189@pytest.mark.buildconfigspec('fs_erofs') 190@pytest.mark.requiredtool('mkfs.erofs') 191@pytest.mark.requiredtool('md5sum') 192 193def test_erofs(u_boot_console): 194 """ 195 Executes the erofs test suite. 196 """ 197 build_dir = u_boot_console.config.build_dir 198 199 try: 200 # setup test environment 201 make_erofs_image(build_dir) 202 image_path = os.path.join(build_dir, EROFS_IMAGE_NAME) 203 u_boot_console.run_command('host bind 0 {}'.format(image_path)) 204 # run all tests 205 erofs_run_all_tests(u_boot_console) 206 except: 207 clean_erofs_image(build_dir) 208 raise AssertionError 209 210 # clean test environment 211 clean_erofs_image(build_dir) 212