blob: 47a584ffe7cdfa11dea1191abb64d9c64e254671 [file] [log] [blame]
AKASHI Takahiro615af9a2018-09-11 15:59:19 +09001# SPDX-License-Identifier: GPL-2.0+
2# Copyright (c) 2018, Linaro Limited
3# Author: Takahiro Akashi <takahiro.akashi@linaro.org>
4
5import os
6import os.path
7import pytest
8import re
9from subprocess import call, check_call, check_output, CalledProcessError
10from fstest_defs import *
Tom Rini50ad0192023-12-09 14:52:46 -050011# pylint: disable=E0611
Simon Glass1d5006c2022-10-29 19:47:05 -060012from tests import fs_helper
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090013
14supported_fs_basic = ['fat16', 'fat32', 'ext4']
Christian Taedckea1fd7352023-11-15 13:44:22 +010015supported_fs_ext = ['fat12', 'fat16', 'fat32']
Christian Taedcke570dc362023-11-15 13:44:24 +010016supported_fs_fat = ['fat12', 'fat16']
Christian Taedckea1fd7352023-11-15 13:44:22 +010017supported_fs_mkdir = ['fat12', 'fat16', 'fat32']
18supported_fs_unlink = ['fat12', 'fat16', 'fat32']
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010019supported_fs_symlink = ['ext4']
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -050020supported_fs_rename = ['fat12', 'fat16', 'fat32']
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090021
22#
23# Filesystem test specific setup
24#
25def pytest_addoption(parser):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090026 """Enable --fs-type option.
27
28 See pytest_configure() about how it works.
29
30 Args:
31 parser: Pytest command-line parser.
32
33 Returns:
34 Nothing.
35 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090036 parser.addoption('--fs-type', action='append', default=None,
37 help='Targeting Filesystem Types')
38
39def pytest_configure(config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090040 """Restrict a file system(s) to be tested.
41
42 A file system explicitly named with --fs-type option is selected
43 if it belongs to a default supported_fs_xxx list.
44 Multiple options can be specified.
45
46 Args:
47 config: Pytest configuration.
48
49 Returns:
50 Nothing.
51 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090052 global supported_fs_basic
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090053 global supported_fs_ext
Christian Taedcke570dc362023-11-15 13:44:24 +010054 global supported_fs_fat
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090055 global supported_fs_mkdir
Akashi, Takahirod49e7992018-09-11 16:06:03 +090056 global supported_fs_unlink
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010057 global supported_fs_symlink
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -050058 global supported_fs_rename
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090059
60 def intersect(listA, listB):
61 return [x for x in listA if x in listB]
62
63 supported_fs = config.getoption('fs_type')
64 if supported_fs:
Simon Glasse9f4d872018-12-27 08:11:13 -070065 print('*** FS TYPE modified: %s' % supported_fs)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090066 supported_fs_basic = intersect(supported_fs, supported_fs_basic)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090067 supported_fs_ext = intersect(supported_fs, supported_fs_ext)
Christian Taedcke570dc362023-11-15 13:44:24 +010068 supported_fs_fat = intersect(supported_fs, supported_fs_fat)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090069 supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +090070 supported_fs_unlink = intersect(supported_fs, supported_fs_unlink)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010071 supported_fs_symlink = intersect(supported_fs, supported_fs_symlink)
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -050072 supported_fs_rename = intersect(supported_fs, supported_fs_rename)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090073
74def pytest_generate_tests(metafunc):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090075 """Parametrize fixtures, fs_obj_xxx
76
77 Each fixture will be parametrized with a corresponding support_fs_xxx
78 list.
79
80 Args:
81 metafunc: Pytest test function.
82
83 Returns:
84 Nothing.
85 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090086 if 'fs_obj_basic' in metafunc.fixturenames:
87 metafunc.parametrize('fs_obj_basic', supported_fs_basic,
88 indirect=True, scope='module')
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090089 if 'fs_obj_ext' in metafunc.fixturenames:
90 metafunc.parametrize('fs_obj_ext', supported_fs_ext,
91 indirect=True, scope='module')
Christian Taedcke570dc362023-11-15 13:44:24 +010092 if 'fs_obj_fat' in metafunc.fixturenames:
93 metafunc.parametrize('fs_obj_fat', supported_fs_fat,
94 indirect=True, scope='module')
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090095 if 'fs_obj_mkdir' in metafunc.fixturenames:
96 metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir,
97 indirect=True, scope='module')
Akashi, Takahirod49e7992018-09-11 16:06:03 +090098 if 'fs_obj_unlink' in metafunc.fixturenames:
99 metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
100 indirect=True, scope='module')
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100101 if 'fs_obj_symlink' in metafunc.fixturenames:
102 metafunc.parametrize('fs_obj_symlink', supported_fs_symlink,
103 indirect=True, scope='module')
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -0500104 if 'fs_obj_rename' in metafunc.fixturenames:
105 metafunc.parametrize('fs_obj_rename', supported_fs_rename,
106 indirect=True, scope='module')
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900107
108#
109# Helper functions
110#
111def fstype_to_ubname(fs_type):
Michal Simek50fa1182023-05-17 09:17:16 +0200112 """Convert a file system type to an U-Boot specific string
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900113
114 A generated string can be used as part of file system related commands
115 or a config name in u-boot. Currently fat16 and fat32 are handled
116 specifically.
117
118 Args:
119 fs_type: File system type.
120
121 Return:
122 A corresponding string for file system type.
123 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900124 if re.match('fat', fs_type):
125 return 'fat'
126 else:
127 return fs_type
128
129def check_ubconfig(config, fs_type):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900130 """Check whether a file system is enabled in u-boot configuration.
131
132 This function is assumed to be called in a fixture function so that
133 the whole test cases will be skipped if a given file system is not
134 enabled.
135
136 Args:
137 fs_type: File system type.
138
139 Return:
140 Nothing.
141 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900142 if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
143 pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
144 if not config.buildconfig.get('config_%s_write' % fs_type, None):
145 pytest.skip('.config feature "%s_WRITE" not enabled'
146 % fs_type.upper())
147
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900148# from test/py/conftest.py
149def tool_is_in_path(tool):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900150 """Check whether a given command is available on host.
151
152 Args:
153 tool: Command name.
154
155 Return:
156 True if available, False if not.
157 """
Simon Glasse9f4d872018-12-27 08:11:13 -0700158 for path in os.environ['PATH'].split(os.pathsep):
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900159 fn = os.path.join(path, tool)
160 if os.path.isfile(fn) and os.access(fn, os.X_OK):
161 return True
162 return False
163
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900164#
165# Fixture for basic fs test
166# derived from test/fs/fs-test.sh
167#
Tom Rini1b91cee2021-01-28 14:39:56 -0500168@pytest.fixture()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900169def fs_obj_basic(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900170 """Set up a file system to be used in basic fs test.
171
172 Args:
173 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200174 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900175
176 Return:
177 A fixture for basic fs test, i.e. a triplet of file system type,
178 volume file name and a list of MD5 hashes.
179 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900180 fs_type = request.param
181 fs_img = ''
182
183 fs_ubtype = fstype_to_ubname(fs_type)
184 check_ubconfig(u_boot_config, fs_ubtype)
185
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700186 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900187
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700188 small_file = scratch_dir + '/' + SMALL_FILE
189 big_file = scratch_dir + '/' + BIG_FILE
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900190
191 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700192 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200193 except CalledProcessError as err:
194 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200195 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300196 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200197
198 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900199 # Create a subdirectory.
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700200 check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900201
202 # Create big file in this image.
203 # Note that we work only on the start 1MB, couple MBs in the 2GB range
204 # and the last 1 MB of the huge 2.5GB file.
205 # So, just put random values only in those areas.
206 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
207 % big_file, shell=True)
208 check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
209 % big_file, shell=True)
210 check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
211 % big_file, shell=True)
212
213 # Create a small file in this image.
214 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
215 % small_file, shell=True)
216
217 # Delete the small file copies which possibly are written as part of a
218 # previous test.
219 # check_call('rm -f "%s.w"' % MB1, shell=True)
220 # check_call('rm -f "%s.w2"' % MB1, shell=True)
221
222 # Generate the md5sums of reads that we will test against small file
223 out = check_output(
224 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400225 % small_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900226 md5val = [ out.split()[0] ]
227
228 # Generate the md5sums of reads that we will test against big file
229 # One from beginning of file.
230 out = check_output(
231 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400232 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900233 md5val.append(out.split()[0])
234
235 # One from end of file.
236 out = check_output(
237 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400238 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900239 md5val.append(out.split()[0])
240
241 # One from the last 1MB chunk of 2GB
242 out = check_output(
243 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400244 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900245 md5val.append(out.split()[0])
246
247 # One from the start 1MB chunk from 2GB
248 out = check_output(
249 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400250 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900251 md5val.append(out.split()[0])
252
253 # One 1MB chunk crossing the 2GB boundary
254 out = check_output(
255 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400256 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900257 md5val.append(out.split()[0])
258
Richard Weinberger41eca322024-11-21 15:32:07 -0700259 try:
260 # 3GiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700261 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700262 except CalledProcessError as err:
263 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
264 return
265
Heinrich Schuchardtbc856172020-04-20 20:48:40 +0200266 except CalledProcessError as err:
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200267 pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900268 return
269 else:
270 yield [fs_ubtype, fs_img, md5val]
271 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700272 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200273 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900274
275#
276# Fixture for extended fs test
277#
Tom Rini1b91cee2021-01-28 14:39:56 -0500278@pytest.fixture()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900279def fs_obj_ext(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900280 """Set up a file system to be used in extended fs test.
281
282 Args:
283 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200284 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900285
286 Return:
287 A fixture for extended fs test, i.e. a triplet of file system type,
288 volume file name and a list of MD5 hashes.
289 """
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900290 fs_type = request.param
291 fs_img = ''
292
293 fs_ubtype = fstype_to_ubname(fs_type)
294 check_ubconfig(u_boot_config, fs_ubtype)
295
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700296 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900297
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700298 min_file = scratch_dir + '/' + MIN_FILE
299 tmp_file = scratch_dir + '/tmpfile'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900300
301 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700302 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200303 except CalledProcessError as err:
304 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200305 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300306 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200307
308 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900309 # Create a test directory
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700310 check_call('mkdir %s/dir1' % scratch_dir, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900311
312 # Create a small file and calculate md5
313 check_call('dd if=/dev/urandom of=%s bs=1K count=20'
314 % min_file, shell=True)
315 out = check_output(
316 'dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400317 % min_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900318 md5val = [ out.split()[0] ]
319
320 # Calculate md5sum of Test Case 4
321 check_call('dd if=%s of=%s bs=1K count=20'
322 % (min_file, tmp_file), shell=True)
323 check_call('dd if=%s of=%s bs=1K seek=5 count=20'
324 % (min_file, tmp_file), shell=True)
325 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400326 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900327 md5val.append(out.split()[0])
328
329 # Calculate md5sum of Test Case 5
330 check_call('dd if=%s of=%s bs=1K count=20'
331 % (min_file, tmp_file), shell=True)
332 check_call('dd if=%s of=%s bs=1K seek=5 count=5'
333 % (min_file, tmp_file), shell=True)
334 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400335 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900336 md5val.append(out.split()[0])
337
338 # Calculate md5sum of Test Case 7
339 check_call('dd if=%s of=%s bs=1K count=20'
340 % (min_file, tmp_file), shell=True)
341 check_call('dd if=%s of=%s bs=1K seek=20 count=20'
342 % (min_file, tmp_file), shell=True)
343 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400344 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900345 md5val.append(out.split()[0])
346
347 check_call('rm %s' % tmp_file, shell=True)
Richard Weinberger41eca322024-11-21 15:32:07 -0700348
349 try:
350 # 128MiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700351 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700352 except CalledProcessError as err:
353 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
354 return
355
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900356 except CalledProcessError:
357 pytest.skip('Setup failed for filesystem: ' + fs_type)
358 return
359 else:
360 yield [fs_ubtype, fs_img, md5val]
361 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700362 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200363 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900364
365#
366# Fixture for mkdir test
367#
Tom Rini1b91cee2021-01-28 14:39:56 -0500368@pytest.fixture()
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900369def fs_obj_mkdir(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900370 """Set up a file system to be used in mkdir test.
371
372 Args:
373 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200374 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900375
376 Return:
377 A fixture for mkdir test, i.e. a duplet of file system type and
378 volume file name.
379 """
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900380 fs_type = request.param
381 fs_img = ''
382
383 fs_ubtype = fstype_to_ubname(fs_type)
384 check_ubconfig(u_boot_config, fs_ubtype)
385
386 try:
387 # 128MiB volume
Richard Weinberger41eca322024-11-21 15:32:07 -0700388 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', None)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900389 except:
390 pytest.skip('Setup failed for filesystem: ' + fs_type)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200391 return
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900392 else:
393 yield [fs_ubtype, fs_img]
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200394 call('rm -f %s' % fs_img, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900395
396#
397# Fixture for unlink test
398#
Tom Rini1b91cee2021-01-28 14:39:56 -0500399@pytest.fixture()
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900400def fs_obj_unlink(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900401 """Set up a file system to be used in unlink test.
402
403 Args:
404 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200405 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900406
407 Return:
408 A fixture for unlink test, i.e. a duplet of file system type and
409 volume file name.
410 """
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900411 fs_type = request.param
412 fs_img = ''
413
414 fs_ubtype = fstype_to_ubname(fs_type)
415 check_ubconfig(u_boot_config, fs_ubtype)
416
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700417 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900418
419 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700420 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200421 except CalledProcessError as err:
422 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200423 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300424 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200425
426 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900427 # Test Case 1 & 3
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700428 check_call('mkdir %s/dir1' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900429 check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700430 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900431 check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700432 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900433
434 # Test Case 2
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700435 check_call('mkdir %s/dir2' % scratch_dir, shell=True)
Tom Rini7f24c192019-10-24 11:59:20 -0400436 for i in range(0, 20):
437 check_call('mkdir %s/dir2/0123456789abcdef%02x'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700438 % (scratch_dir, i), shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900439
440 # Test Case 4
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700441 check_call('mkdir %s/dir4' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900442
443 # Test Case 5, 6 & 7
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700444 check_call('mkdir %s/dir5' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900445 check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700446 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900447
Richard Weinberger41eca322024-11-21 15:32:07 -0700448 try:
449 # 128MiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700450 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700451 except CalledProcessError as err:
452 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
453 return
454
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900455 except CalledProcessError:
456 pytest.skip('Setup failed for filesystem: ' + fs_type)
457 return
458 else:
459 yield [fs_ubtype, fs_img]
460 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700461 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200462 call('rm -f %s' % fs_img, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100463
464#
465# Fixture for symlink fs test
466#
Tom Rini1b91cee2021-01-28 14:39:56 -0500467@pytest.fixture()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100468def fs_obj_symlink(request, u_boot_config):
469 """Set up a file system to be used in symlink fs test.
470
471 Args:
472 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200473 u_boot_config: U-Boot configuration.
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100474
475 Return:
476 A fixture for basic fs test, i.e. a triplet of file system type,
477 volume file name and a list of MD5 hashes.
478 """
479 fs_type = request.param
480 fs_img = ''
481
482 fs_ubtype = fstype_to_ubname(fs_type)
483 check_ubconfig(u_boot_config, fs_ubtype)
484
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700485 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100486
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700487 small_file = scratch_dir + '/' + SMALL_FILE
488 medium_file = scratch_dir + '/' + MEDIUM_FILE
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100489
490 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700491 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200492 except CalledProcessError as err:
493 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200494 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300495 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200496
497 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100498 # Create a subdirectory.
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700499 check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100500
501 # Create a small file in this image.
502 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
503 % small_file, shell=True)
504
505 # Create a medium file in this image.
506 check_call('dd if=/dev/urandom of=%s bs=10M count=1'
507 % medium_file, shell=True)
508
509 # Generate the md5sums of reads that we will test against small file
510 out = check_output(
511 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400512 % small_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100513 md5val = [out.split()[0]]
514 out = check_output(
515 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400516 % medium_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100517 md5val.extend([out.split()[0]])
518
Richard Weinberger41eca322024-11-21 15:32:07 -0700519 try:
520 # 1GiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700521 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x40000000, '1GB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700522 except CalledProcessError as err:
523 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
524 return
525
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100526 except CalledProcessError:
527 pytest.skip('Setup failed for filesystem: ' + fs_type)
528 return
529 else:
530 yield [fs_ubtype, fs_img, md5val]
531 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700532 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200533 call('rm -f %s' % fs_img, shell=True)
Christian Taedcke570dc362023-11-15 13:44:24 +0100534
535#
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -0500536# Fixture for rename test
537#
538@pytest.fixture()
539def fs_obj_rename(request, u_boot_config):
540 """Set up a file system to be used in rename tests.
541
542 Args:
543 request: Pytest request object.
544 u_boot_config: U-Boot configuration.
545
546 Return:
547 A fixture for rename tests, i.e. a triplet of file system type,
548 volume file name, and dictionary of test identifier and md5val.
549 """
550 def new_rand_file(path):
551 check_call('dd if=/dev/urandom of=%s bs=1K count=1' % path, shell=True)
552
553 def file_hash(path):
554 out = check_output(
555 'dd if=%s bs=1K skip=0 count=1 2> /dev/null | md5sum' % path,
556 shell=True
557 )
558 return out.decode().split()[0]
559
560 fs_type = request.param
561 fs_img = ''
562
563 fs_ubtype = fstype_to_ubname(fs_type)
564 check_ubconfig(u_boot_config, fs_ubtype)
565
566 mount_dir = u_boot_config.persistent_data_dir + '/scratch'
567
568 try:
569 check_call('mkdir -p %s' % mount_dir, shell=True)
570 except CalledProcessError as err:
571 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
572 call('rm -f %s' % fs_img, shell=True)
573 return
574
575 try:
576 md5val = {}
577 # Test Case 1
578 check_call('mkdir %s/test1' % mount_dir, shell=True)
579 new_rand_file('%s/test1/file1' % mount_dir)
580 md5val['test1'] = file_hash('%s/test1/file1' % mount_dir)
581
582 # Test Case 2
583 check_call('mkdir %s/test2' % mount_dir, shell=True)
584 new_rand_file('%s/test2/file1' % mount_dir)
585 new_rand_file('%s/test2/file_exist' % mount_dir)
586 md5val['test2'] = file_hash('%s/test2/file1' % mount_dir)
587
588 # Test Case 3
589 check_call('mkdir -p %s/test3/dir1' % mount_dir, shell=True)
590 new_rand_file('%s/test3/dir1/file1' % mount_dir)
591 md5val['test3'] = file_hash('%s/test3/dir1/file1' % mount_dir)
592
593 # Test Case 4
594 check_call('mkdir -p %s/test4/dir1' % mount_dir, shell=True)
595 check_call('mkdir -p %s/test4/dir2/dir1' % mount_dir, shell=True)
596 new_rand_file('%s/test4/dir1/file1' % mount_dir)
597 md5val['test4'] = file_hash('%s/test4/dir1/file1' % mount_dir)
598
599 # Test Case 5
600 check_call('mkdir -p %s/test5/dir1' % mount_dir, shell=True)
601 new_rand_file('%s/test5/file2' % mount_dir)
602 md5val['test5'] = file_hash('%s/test5/file2' % mount_dir)
603
604 # Test Case 6
605 check_call('mkdir -p %s/test6/dir2/existing' % mount_dir, shell=True)
606 new_rand_file('%s/test6/existing' % mount_dir)
607 md5val['test6'] = file_hash('%s/test6/existing' % mount_dir)
608
609 # Test Case 7
610 check_call('mkdir -p %s/test7/dir1' % mount_dir, shell=True)
611 check_call('mkdir -p %s/test7/dir2/dir1' % mount_dir, shell=True)
612 new_rand_file('%s/test7/dir2/dir1/file1' % mount_dir)
613 md5val['test7'] = file_hash('%s/test7/dir2/dir1/file1' % mount_dir)
614
615 # Test Case 8
616 check_call('mkdir -p %s/test8/dir1' % mount_dir, shell=True)
617 new_rand_file('%s/test8/dir1/file1' % mount_dir)
618 md5val['test8'] = file_hash('%s/test8/dir1/file1' % mount_dir)
619
620 # Test Case 9
621 check_call('mkdir -p %s/test9/dir1/nested/inner' % mount_dir, shell=True)
622 new_rand_file('%s/test9/dir1/nested/inner/file1' % mount_dir)
623
624 # Test Case 10
625 check_call('mkdir -p %s/test10' % mount_dir, shell=True)
626 new_rand_file('%s/test10/file1' % mount_dir)
627 md5val['test10'] = file_hash('%s/test10/file1' % mount_dir)
628
629 # Test Case 11
630 check_call('mkdir -p %s/test11/dir1' % mount_dir, shell=True)
631 new_rand_file('%s/test11/dir1/file1' % mount_dir)
632 md5val['test11'] = file_hash('%s/test11/dir1/file1' % mount_dir)
633
634 try:
635 # 128MiB volume
636 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', mount_dir)
637 except CalledProcessError as err:
638 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
639 return
640
641 except CalledProcessError:
642 pytest.skip('Setup failed for filesystem: ' + fs_type)
643 return
644 else:
645 yield [fs_ubtype, fs_img, md5val]
646 finally:
647 call('rm -rf %s' % mount_dir, shell=True)
648 call('rm -f %s' % fs_img, shell=True)
649
650#
Christian Taedcke570dc362023-11-15 13:44:24 +0100651# Fixture for fat test
652#
653@pytest.fixture()
654def fs_obj_fat(request, u_boot_config):
655 """Set up a file system to be used in fat test.
656
657 Args:
658 request: Pytest request object.
659 u_boot_config: U-Boot configuration.
660
661 Return:
662 A fixture for fat test, i.e. a duplet of file system type and
663 volume file name.
664 """
665
666 # the maximum size of a FAT12 filesystem resulting in 4084 clusters
667 MAX_FAT12_SIZE = 261695 * 1024
668
669 # the minimum size of a FAT16 filesystem that can be created with
670 # mkfs.vfat resulting in 4087 clusters
671 MIN_FAT16_SIZE = 8208 * 1024
672
673 fs_type = request.param
674 fs_img = ''
675
676 fs_ubtype = fstype_to_ubname(fs_type)
677 check_ubconfig(u_boot_config, fs_ubtype)
678
679 fs_size = MAX_FAT12_SIZE if fs_type == 'fat12' else MIN_FAT16_SIZE
680
681 try:
682 # the volume size depends on the filesystem
Richard Weinberger41eca322024-11-21 15:32:07 -0700683 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, fs_size, f'{fs_size}', None, 1024)
Christian Taedcke570dc362023-11-15 13:44:24 +0100684 except:
685 pytest.skip('Setup failed for filesystem: ' + fs_type)
686 return
687 else:
688 yield [fs_ubtype, fs_img]
689 call('rm -f %s' % fs_img, shell=True)