blob: 7bfcf41ed6fa34c2f5f4e10cf620bb71089dc3ae [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 *
Alper Nebi Yasak7ff17f22021-06-04 22:04:46 +030011import u_boot_utils as util
Tom Rini50ad0192023-12-09 14:52:46 -050012# pylint: disable=E0611
Simon Glass1d5006c2022-10-29 19:47:05 -060013from tests import fs_helper
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090014
15supported_fs_basic = ['fat16', 'fat32', 'ext4']
Christian Taedckea1fd7352023-11-15 13:44:22 +010016supported_fs_ext = ['fat12', 'fat16', 'fat32']
Christian Taedcke570dc362023-11-15 13:44:24 +010017supported_fs_fat = ['fat12', 'fat16']
Christian Taedckea1fd7352023-11-15 13:44:22 +010018supported_fs_mkdir = ['fat12', 'fat16', 'fat32']
19supported_fs_unlink = ['fat12', 'fat16', 'fat32']
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010020supported_fs_symlink = ['ext4']
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -050021supported_fs_rename = ['fat12', 'fat16', 'fat32']
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090022
23#
24# Filesystem test specific setup
25#
26def pytest_addoption(parser):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090027 """Enable --fs-type option.
28
29 See pytest_configure() about how it works.
30
31 Args:
32 parser: Pytest command-line parser.
33
34 Returns:
35 Nothing.
36 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090037 parser.addoption('--fs-type', action='append', default=None,
38 help='Targeting Filesystem Types')
39
40def pytest_configure(config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090041 """Restrict a file system(s) to be tested.
42
43 A file system explicitly named with --fs-type option is selected
44 if it belongs to a default supported_fs_xxx list.
45 Multiple options can be specified.
46
47 Args:
48 config: Pytest configuration.
49
50 Returns:
51 Nothing.
52 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090053 global supported_fs_basic
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090054 global supported_fs_ext
Christian Taedcke570dc362023-11-15 13:44:24 +010055 global supported_fs_fat
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090056 global supported_fs_mkdir
Akashi, Takahirod49e7992018-09-11 16:06:03 +090057 global supported_fs_unlink
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010058 global supported_fs_symlink
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -050059 global supported_fs_rename
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090060
61 def intersect(listA, listB):
62 return [x for x in listA if x in listB]
63
64 supported_fs = config.getoption('fs_type')
65 if supported_fs:
Simon Glasse9f4d872018-12-27 08:11:13 -070066 print('*** FS TYPE modified: %s' % supported_fs)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090067 supported_fs_basic = intersect(supported_fs, supported_fs_basic)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090068 supported_fs_ext = intersect(supported_fs, supported_fs_ext)
Christian Taedcke570dc362023-11-15 13:44:24 +010069 supported_fs_fat = intersect(supported_fs, supported_fs_fat)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090070 supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +090071 supported_fs_unlink = intersect(supported_fs, supported_fs_unlink)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010072 supported_fs_symlink = intersect(supported_fs, supported_fs_symlink)
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -050073 supported_fs_rename = intersect(supported_fs, supported_fs_rename)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090074
75def pytest_generate_tests(metafunc):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090076 """Parametrize fixtures, fs_obj_xxx
77
78 Each fixture will be parametrized with a corresponding support_fs_xxx
79 list.
80
81 Args:
82 metafunc: Pytest test function.
83
84 Returns:
85 Nothing.
86 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090087 if 'fs_obj_basic' in metafunc.fixturenames:
88 metafunc.parametrize('fs_obj_basic', supported_fs_basic,
89 indirect=True, scope='module')
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090090 if 'fs_obj_ext' in metafunc.fixturenames:
91 metafunc.parametrize('fs_obj_ext', supported_fs_ext,
92 indirect=True, scope='module')
Christian Taedcke570dc362023-11-15 13:44:24 +010093 if 'fs_obj_fat' in metafunc.fixturenames:
94 metafunc.parametrize('fs_obj_fat', supported_fs_fat,
95 indirect=True, scope='module')
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090096 if 'fs_obj_mkdir' in metafunc.fixturenames:
97 metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir,
98 indirect=True, scope='module')
Akashi, Takahirod49e7992018-09-11 16:06:03 +090099 if 'fs_obj_unlink' in metafunc.fixturenames:
100 metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
101 indirect=True, scope='module')
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100102 if 'fs_obj_symlink' in metafunc.fixturenames:
103 metafunc.parametrize('fs_obj_symlink', supported_fs_symlink,
104 indirect=True, scope='module')
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -0500105 if 'fs_obj_rename' in metafunc.fixturenames:
106 metafunc.parametrize('fs_obj_rename', supported_fs_rename,
107 indirect=True, scope='module')
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900108
109#
110# Helper functions
111#
112def fstype_to_ubname(fs_type):
Michal Simek50fa1182023-05-17 09:17:16 +0200113 """Convert a file system type to an U-Boot specific string
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900114
115 A generated string can be used as part of file system related commands
116 or a config name in u-boot. Currently fat16 and fat32 are handled
117 specifically.
118
119 Args:
120 fs_type: File system type.
121
122 Return:
123 A corresponding string for file system type.
124 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900125 if re.match('fat', fs_type):
126 return 'fat'
127 else:
128 return fs_type
129
130def check_ubconfig(config, fs_type):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900131 """Check whether a file system is enabled in u-boot configuration.
132
133 This function is assumed to be called in a fixture function so that
134 the whole test cases will be skipped if a given file system is not
135 enabled.
136
137 Args:
138 fs_type: File system type.
139
140 Return:
141 Nothing.
142 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900143 if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
144 pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
145 if not config.buildconfig.get('config_%s_write' % fs_type, None):
146 pytest.skip('.config feature "%s_WRITE" not enabled'
147 % fs_type.upper())
148
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900149# from test/py/conftest.py
150def tool_is_in_path(tool):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900151 """Check whether a given command is available on host.
152
153 Args:
154 tool: Command name.
155
156 Return:
157 True if available, False if not.
158 """
Simon Glasse9f4d872018-12-27 08:11:13 -0700159 for path in os.environ['PATH'].split(os.pathsep):
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900160 fn = os.path.join(path, tool)
161 if os.path.isfile(fn) and os.access(fn, os.X_OK):
162 return True
163 return False
164
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900165#
166# Fixture for basic fs test
167# derived from test/fs/fs-test.sh
168#
Tom Rini1b91cee2021-01-28 14:39:56 -0500169@pytest.fixture()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900170def fs_obj_basic(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900171 """Set up a file system to be used in basic fs test.
172
173 Args:
174 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200175 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900176
177 Return:
178 A fixture for basic fs test, i.e. a triplet of file system type,
179 volume file name and a list of MD5 hashes.
180 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900181 fs_type = request.param
182 fs_img = ''
183
184 fs_ubtype = fstype_to_ubname(fs_type)
185 check_ubconfig(u_boot_config, fs_ubtype)
186
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700187 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900188
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700189 small_file = scratch_dir + '/' + SMALL_FILE
190 big_file = scratch_dir + '/' + BIG_FILE
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900191
192 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700193 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200194 except CalledProcessError as err:
195 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200196 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300197 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200198
199 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900200 # Create a subdirectory.
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700201 check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900202
203 # Create big file in this image.
204 # Note that we work only on the start 1MB, couple MBs in the 2GB range
205 # and the last 1 MB of the huge 2.5GB file.
206 # So, just put random values only in those areas.
207 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
208 % big_file, shell=True)
209 check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
210 % big_file, shell=True)
211 check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
212 % big_file, shell=True)
213
214 # Create a small file in this image.
215 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
216 % small_file, shell=True)
217
218 # Delete the small file copies which possibly are written as part of a
219 # previous test.
220 # check_call('rm -f "%s.w"' % MB1, shell=True)
221 # check_call('rm -f "%s.w2"' % MB1, shell=True)
222
223 # Generate the md5sums of reads that we will test against small file
224 out = check_output(
225 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400226 % small_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900227 md5val = [ out.split()[0] ]
228
229 # Generate the md5sums of reads that we will test against big file
230 # One from beginning of file.
231 out = check_output(
232 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400233 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900234 md5val.append(out.split()[0])
235
236 # One from end of file.
237 out = check_output(
238 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400239 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900240 md5val.append(out.split()[0])
241
242 # One from the last 1MB chunk of 2GB
243 out = check_output(
244 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400245 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900246 md5val.append(out.split()[0])
247
248 # One from the start 1MB chunk from 2GB
249 out = check_output(
250 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400251 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900252 md5val.append(out.split()[0])
253
254 # One 1MB chunk crossing the 2GB boundary
255 out = check_output(
256 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400257 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900258 md5val.append(out.split()[0])
259
Richard Weinberger41eca322024-11-21 15:32:07 -0700260 try:
261 # 3GiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700262 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700263 except CalledProcessError as err:
264 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
265 return
266
Heinrich Schuchardtbc856172020-04-20 20:48:40 +0200267 except CalledProcessError as err:
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200268 pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900269 return
270 else:
271 yield [fs_ubtype, fs_img, md5val]
272 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700273 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200274 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900275
276#
277# Fixture for extended fs test
278#
Tom Rini1b91cee2021-01-28 14:39:56 -0500279@pytest.fixture()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900280def fs_obj_ext(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900281 """Set up a file system to be used in extended fs test.
282
283 Args:
284 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200285 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900286
287 Return:
288 A fixture for extended fs test, i.e. a triplet of file system type,
289 volume file name and a list of MD5 hashes.
290 """
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900291 fs_type = request.param
292 fs_img = ''
293
294 fs_ubtype = fstype_to_ubname(fs_type)
295 check_ubconfig(u_boot_config, fs_ubtype)
296
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700297 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900298
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700299 min_file = scratch_dir + '/' + MIN_FILE
300 tmp_file = scratch_dir + '/tmpfile'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900301
302 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700303 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200304 except CalledProcessError as err:
305 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200306 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300307 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200308
309 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900310 # Create a test directory
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700311 check_call('mkdir %s/dir1' % scratch_dir, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900312
313 # Create a small file and calculate md5
314 check_call('dd if=/dev/urandom of=%s bs=1K count=20'
315 % min_file, shell=True)
316 out = check_output(
317 'dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400318 % min_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900319 md5val = [ out.split()[0] ]
320
321 # Calculate md5sum of Test Case 4
322 check_call('dd if=%s of=%s bs=1K count=20'
323 % (min_file, tmp_file), shell=True)
324 check_call('dd if=%s of=%s bs=1K seek=5 count=20'
325 % (min_file, tmp_file), shell=True)
326 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400327 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900328 md5val.append(out.split()[0])
329
330 # Calculate md5sum of Test Case 5
331 check_call('dd if=%s of=%s bs=1K count=20'
332 % (min_file, tmp_file), shell=True)
333 check_call('dd if=%s of=%s bs=1K seek=5 count=5'
334 % (min_file, tmp_file), shell=True)
335 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400336 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900337 md5val.append(out.split()[0])
338
339 # Calculate md5sum of Test Case 7
340 check_call('dd if=%s of=%s bs=1K count=20'
341 % (min_file, tmp_file), shell=True)
342 check_call('dd if=%s of=%s bs=1K seek=20 count=20'
343 % (min_file, tmp_file), shell=True)
344 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400345 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900346 md5val.append(out.split()[0])
347
348 check_call('rm %s' % tmp_file, shell=True)
Richard Weinberger41eca322024-11-21 15:32:07 -0700349
350 try:
351 # 128MiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700352 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700353 except CalledProcessError as err:
354 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
355 return
356
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900357 except CalledProcessError:
358 pytest.skip('Setup failed for filesystem: ' + fs_type)
359 return
360 else:
361 yield [fs_ubtype, fs_img, md5val]
362 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700363 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200364 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900365
366#
367# Fixture for mkdir test
368#
Tom Rini1b91cee2021-01-28 14:39:56 -0500369@pytest.fixture()
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900370def fs_obj_mkdir(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900371 """Set up a file system to be used in mkdir test.
372
373 Args:
374 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200375 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900376
377 Return:
378 A fixture for mkdir test, i.e. a duplet of file system type and
379 volume file name.
380 """
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900381 fs_type = request.param
382 fs_img = ''
383
384 fs_ubtype = fstype_to_ubname(fs_type)
385 check_ubconfig(u_boot_config, fs_ubtype)
386
387 try:
388 # 128MiB volume
Richard Weinberger41eca322024-11-21 15:32:07 -0700389 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', None)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900390 except:
391 pytest.skip('Setup failed for filesystem: ' + fs_type)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200392 return
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900393 else:
394 yield [fs_ubtype, fs_img]
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200395 call('rm -f %s' % fs_img, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900396
397#
398# Fixture for unlink test
399#
Tom Rini1b91cee2021-01-28 14:39:56 -0500400@pytest.fixture()
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900401def fs_obj_unlink(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900402 """Set up a file system to be used in unlink test.
403
404 Args:
405 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200406 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900407
408 Return:
409 A fixture for unlink test, i.e. a duplet of file system type and
410 volume file name.
411 """
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900412 fs_type = request.param
413 fs_img = ''
414
415 fs_ubtype = fstype_to_ubname(fs_type)
416 check_ubconfig(u_boot_config, fs_ubtype)
417
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700418 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900419
420 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700421 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200422 except CalledProcessError as err:
423 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200424 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300425 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200426
427 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900428 # Test Case 1 & 3
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700429 check_call('mkdir %s/dir1' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900430 check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700431 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900432 check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700433 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900434
435 # Test Case 2
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700436 check_call('mkdir %s/dir2' % scratch_dir, shell=True)
Tom Rini7f24c192019-10-24 11:59:20 -0400437 for i in range(0, 20):
438 check_call('mkdir %s/dir2/0123456789abcdef%02x'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700439 % (scratch_dir, i), shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900440
441 # Test Case 4
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700442 check_call('mkdir %s/dir4' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900443
444 # Test Case 5, 6 & 7
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700445 check_call('mkdir %s/dir5' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900446 check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700447 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900448
Richard Weinberger41eca322024-11-21 15:32:07 -0700449 try:
450 # 128MiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700451 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700452 except CalledProcessError as err:
453 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
454 return
455
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900456 except CalledProcessError:
457 pytest.skip('Setup failed for filesystem: ' + fs_type)
458 return
459 else:
460 yield [fs_ubtype, fs_img]
461 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700462 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200463 call('rm -f %s' % fs_img, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100464
465#
466# Fixture for symlink fs test
467#
Tom Rini1b91cee2021-01-28 14:39:56 -0500468@pytest.fixture()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100469def fs_obj_symlink(request, u_boot_config):
470 """Set up a file system to be used in symlink fs test.
471
472 Args:
473 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200474 u_boot_config: U-Boot configuration.
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100475
476 Return:
477 A fixture for basic fs test, i.e. a triplet of file system type,
478 volume file name and a list of MD5 hashes.
479 """
480 fs_type = request.param
481 fs_img = ''
482
483 fs_ubtype = fstype_to_ubname(fs_type)
484 check_ubconfig(u_boot_config, fs_ubtype)
485
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700486 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100487
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700488 small_file = scratch_dir + '/' + SMALL_FILE
489 medium_file = scratch_dir + '/' + MEDIUM_FILE
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100490
491 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700492 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200493 except CalledProcessError as err:
494 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200495 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300496 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200497
498 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100499 # Create a subdirectory.
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700500 check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100501
502 # Create a small file in this image.
503 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
504 % small_file, shell=True)
505
506 # Create a medium file in this image.
507 check_call('dd if=/dev/urandom of=%s bs=10M count=1'
508 % medium_file, shell=True)
509
510 # Generate the md5sums of reads that we will test against small file
511 out = check_output(
512 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400513 % small_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100514 md5val = [out.split()[0]]
515 out = check_output(
516 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400517 % medium_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100518 md5val.extend([out.split()[0]])
519
Richard Weinberger41eca322024-11-21 15:32:07 -0700520 try:
521 # 1GiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700522 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x40000000, '1GB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700523 except CalledProcessError as err:
524 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
525 return
526
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100527 except CalledProcessError:
528 pytest.skip('Setup failed for filesystem: ' + fs_type)
529 return
530 else:
531 yield [fs_ubtype, fs_img, md5val]
532 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700533 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200534 call('rm -f %s' % fs_img, shell=True)
Christian Taedcke570dc362023-11-15 13:44:24 +0100535
536#
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -0500537# Fixture for rename test
538#
539@pytest.fixture()
540def fs_obj_rename(request, u_boot_config):
541 """Set up a file system to be used in rename tests.
542
543 Args:
544 request: Pytest request object.
545 u_boot_config: U-Boot configuration.
546
547 Return:
548 A fixture for rename tests, i.e. a triplet of file system type,
549 volume file name, and dictionary of test identifier and md5val.
550 """
551 def new_rand_file(path):
552 check_call('dd if=/dev/urandom of=%s bs=1K count=1' % path, shell=True)
553
554 def file_hash(path):
555 out = check_output(
556 'dd if=%s bs=1K skip=0 count=1 2> /dev/null | md5sum' % path,
557 shell=True
558 )
559 return out.decode().split()[0]
560
561 fs_type = request.param
562 fs_img = ''
563
564 fs_ubtype = fstype_to_ubname(fs_type)
565 check_ubconfig(u_boot_config, fs_ubtype)
566
567 mount_dir = u_boot_config.persistent_data_dir + '/scratch'
568
569 try:
570 check_call('mkdir -p %s' % mount_dir, shell=True)
571 except CalledProcessError as err:
572 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
573 call('rm -f %s' % fs_img, shell=True)
574 return
575
576 try:
577 md5val = {}
578 # Test Case 1
579 check_call('mkdir %s/test1' % mount_dir, shell=True)
580 new_rand_file('%s/test1/file1' % mount_dir)
581 md5val['test1'] = file_hash('%s/test1/file1' % mount_dir)
582
583 # Test Case 2
584 check_call('mkdir %s/test2' % mount_dir, shell=True)
585 new_rand_file('%s/test2/file1' % mount_dir)
586 new_rand_file('%s/test2/file_exist' % mount_dir)
587 md5val['test2'] = file_hash('%s/test2/file1' % mount_dir)
588
589 # Test Case 3
590 check_call('mkdir -p %s/test3/dir1' % mount_dir, shell=True)
591 new_rand_file('%s/test3/dir1/file1' % mount_dir)
592 md5val['test3'] = file_hash('%s/test3/dir1/file1' % mount_dir)
593
594 # Test Case 4
595 check_call('mkdir -p %s/test4/dir1' % mount_dir, shell=True)
596 check_call('mkdir -p %s/test4/dir2/dir1' % mount_dir, shell=True)
597 new_rand_file('%s/test4/dir1/file1' % mount_dir)
598 md5val['test4'] = file_hash('%s/test4/dir1/file1' % mount_dir)
599
600 # Test Case 5
601 check_call('mkdir -p %s/test5/dir1' % mount_dir, shell=True)
602 new_rand_file('%s/test5/file2' % mount_dir)
603 md5val['test5'] = file_hash('%s/test5/file2' % mount_dir)
604
605 # Test Case 6
606 check_call('mkdir -p %s/test6/dir2/existing' % mount_dir, shell=True)
607 new_rand_file('%s/test6/existing' % mount_dir)
608 md5val['test6'] = file_hash('%s/test6/existing' % mount_dir)
609
610 # Test Case 7
611 check_call('mkdir -p %s/test7/dir1' % mount_dir, shell=True)
612 check_call('mkdir -p %s/test7/dir2/dir1' % mount_dir, shell=True)
613 new_rand_file('%s/test7/dir2/dir1/file1' % mount_dir)
614 md5val['test7'] = file_hash('%s/test7/dir2/dir1/file1' % mount_dir)
615
616 # Test Case 8
617 check_call('mkdir -p %s/test8/dir1' % mount_dir, shell=True)
618 new_rand_file('%s/test8/dir1/file1' % mount_dir)
619 md5val['test8'] = file_hash('%s/test8/dir1/file1' % mount_dir)
620
621 # Test Case 9
622 check_call('mkdir -p %s/test9/dir1/nested/inner' % mount_dir, shell=True)
623 new_rand_file('%s/test9/dir1/nested/inner/file1' % mount_dir)
624
625 # Test Case 10
626 check_call('mkdir -p %s/test10' % mount_dir, shell=True)
627 new_rand_file('%s/test10/file1' % mount_dir)
628 md5val['test10'] = file_hash('%s/test10/file1' % mount_dir)
629
630 # Test Case 11
631 check_call('mkdir -p %s/test11/dir1' % mount_dir, shell=True)
632 new_rand_file('%s/test11/dir1/file1' % mount_dir)
633 md5val['test11'] = file_hash('%s/test11/dir1/file1' % mount_dir)
634
635 try:
636 # 128MiB volume
637 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', mount_dir)
638 except CalledProcessError as err:
639 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
640 return
641
642 except CalledProcessError:
643 pytest.skip('Setup failed for filesystem: ' + fs_type)
644 return
645 else:
646 yield [fs_ubtype, fs_img, md5val]
647 finally:
648 call('rm -rf %s' % mount_dir, shell=True)
649 call('rm -f %s' % fs_img, shell=True)
650
651#
Christian Taedcke570dc362023-11-15 13:44:24 +0100652# Fixture for fat test
653#
654@pytest.fixture()
655def fs_obj_fat(request, u_boot_config):
656 """Set up a file system to be used in fat test.
657
658 Args:
659 request: Pytest request object.
660 u_boot_config: U-Boot configuration.
661
662 Return:
663 A fixture for fat test, i.e. a duplet of file system type and
664 volume file name.
665 """
666
667 # the maximum size of a FAT12 filesystem resulting in 4084 clusters
668 MAX_FAT12_SIZE = 261695 * 1024
669
670 # the minimum size of a FAT16 filesystem that can be created with
671 # mkfs.vfat resulting in 4087 clusters
672 MIN_FAT16_SIZE = 8208 * 1024
673
674 fs_type = request.param
675 fs_img = ''
676
677 fs_ubtype = fstype_to_ubname(fs_type)
678 check_ubconfig(u_boot_config, fs_ubtype)
679
680 fs_size = MAX_FAT12_SIZE if fs_type == 'fat12' else MIN_FAT16_SIZE
681
682 try:
683 # the volume size depends on the filesystem
Richard Weinberger41eca322024-11-21 15:32:07 -0700684 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 +0100685 except:
686 pytest.skip('Setup failed for filesystem: ' + fs_type)
687 return
688 else:
689 yield [fs_ubtype, fs_img]
690 call('rm -f %s' % fs_img, shell=True)