Merge tag 'xilinx-for-v2022.07-rc1' of https://source.denx.de/u-boot/custodians/u...
[platform/kernel/u-boot.git] / test / py / tests / test_fs / test_erofs.py
1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (C) 2022 Huang Jianan <jnhuang95@gmail.com>
3 # Author: Huang Jianan <jnhuang95@gmail.com>
4
5 import os
6 import pytest
7 import shutil
8 import subprocess
9
10 EROFS_SRC_DIR = 'erofs_src_dir'
11 EROFS_IMAGE_NAME = 'erofs.img'
12
13 def 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
22 def 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
59 def 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
68 def 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
83 def 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
92 def 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
104 def 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
113 def 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
137 def 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
146 def 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
155 def 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
164 def 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
173 def 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
193 def 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)