blob: 691bdf41ede0203abb6b28f3463bba9682869954 [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
Marek Vasut8d3fb2b2025-03-17 04:12:42 +010014supported_fs_basic = ['fat16', 'fat32', 'ext4', 'fs_generic']
15supported_fs_ext = ['fat12', 'fat16', 'fat32', 'fs_generic']
Christian Taedcke570dc362023-11-15 13:44:24 +010016supported_fs_fat = ['fat12', 'fat16']
Marek Vasut8d3fb2b2025-03-17 04:12:42 +010017supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'fs_generic']
18supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'fs_generic']
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#
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100111def fstype_to_prefix(fs_type):
112 """Convert a file system type to an U-Boot command prefix
113
114 Args:
115 fs_type: File system type.
116
117 Return:
118 A corresponding command prefix for file system type.
119 """
120 if fs_type == 'fs_generic':
121 return ''
122 elif re.match('fat', fs_type):
123 return 'fat'
124 else:
125 return fs_type
126
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900127def fstype_to_ubname(fs_type):
Michal Simek50fa1182023-05-17 09:17:16 +0200128 """Convert a file system type to an U-Boot specific string
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900129
130 A generated string can be used as part of file system related commands
131 or a config name in u-boot. Currently fat16 and fat32 are handled
132 specifically.
133
134 Args:
135 fs_type: File system type.
136
137 Return:
138 A corresponding string for file system type.
139 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900140 if re.match('fat', fs_type):
141 return 'fat'
142 else:
143 return fs_type
144
145def check_ubconfig(config, fs_type):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900146 """Check whether a file system is enabled in u-boot configuration.
147
148 This function is assumed to be called in a fixture function so that
149 the whole test cases will be skipped if a given file system is not
150 enabled.
151
152 Args:
153 fs_type: File system type.
154
155 Return:
156 Nothing.
157 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900158 if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
159 pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100160 if fs_type == 'fs_generic':
161 return
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900162 if not config.buildconfig.get('config_%s_write' % fs_type, None):
163 pytest.skip('.config feature "%s_WRITE" not enabled'
164 % fs_type.upper())
165
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900166# from test/py/conftest.py
167def tool_is_in_path(tool):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900168 """Check whether a given command is available on host.
169
170 Args:
171 tool: Command name.
172
173 Return:
174 True if available, False if not.
175 """
Simon Glasse9f4d872018-12-27 08:11:13 -0700176 for path in os.environ['PATH'].split(os.pathsep):
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900177 fn = os.path.join(path, tool)
178 if os.path.isfile(fn) and os.access(fn, os.X_OK):
179 return True
180 return False
181
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900182#
183# Fixture for basic fs test
184# derived from test/fs/fs-test.sh
185#
Tom Rini1b91cee2021-01-28 14:39:56 -0500186@pytest.fixture()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900187def fs_obj_basic(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900188 """Set up a file system to be used in basic fs test.
189
190 Args:
191 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200192 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900193
194 Return:
195 A fixture for basic fs test, i.e. a triplet of file system type,
196 volume file name and a list of MD5 hashes.
197 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900198 fs_type = request.param
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100199 fs_cmd_prefix = fstype_to_prefix(fs_type)
200 fs_cmd_write = 'save' if fs_type == 'fs_generic' else 'write'
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900201 fs_img = ''
202
203 fs_ubtype = fstype_to_ubname(fs_type)
204 check_ubconfig(u_boot_config, fs_ubtype)
205
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700206 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900207
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700208 small_file = scratch_dir + '/' + SMALL_FILE
209 big_file = scratch_dir + '/' + BIG_FILE
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900210
211 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700212 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200213 except CalledProcessError as err:
214 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200215 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300216 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200217
218 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900219 # Create a subdirectory.
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700220 check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900221
222 # Create big file in this image.
223 # Note that we work only on the start 1MB, couple MBs in the 2GB range
224 # and the last 1 MB of the huge 2.5GB file.
225 # So, just put random values only in those areas.
226 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
227 % big_file, shell=True)
228 check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
229 % big_file, shell=True)
230 check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
231 % big_file, shell=True)
232
233 # Create a small file in this image.
234 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
235 % small_file, shell=True)
236
237 # Delete the small file copies which possibly are written as part of a
238 # previous test.
239 # check_call('rm -f "%s.w"' % MB1, shell=True)
240 # check_call('rm -f "%s.w2"' % MB1, shell=True)
241
242 # Generate the md5sums of reads that we will test against small file
243 out = check_output(
244 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400245 % small_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900246 md5val = [ out.split()[0] ]
247
248 # Generate the md5sums of reads that we will test against big file
249 # One from beginning of file.
250 out = check_output(
251 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400252 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900253 md5val.append(out.split()[0])
254
255 # One from end of file.
256 out = check_output(
257 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400258 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900259 md5val.append(out.split()[0])
260
261 # One from the last 1MB chunk of 2GB
262 out = check_output(
263 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400264 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900265 md5val.append(out.split()[0])
266
267 # One from the start 1MB chunk from 2GB
268 out = check_output(
269 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400270 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900271 md5val.append(out.split()[0])
272
273 # One 1MB chunk crossing the 2GB boundary
274 out = check_output(
275 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400276 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900277 md5val.append(out.split()[0])
278
Richard Weinberger41eca322024-11-21 15:32:07 -0700279 try:
280 # 3GiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700281 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700282 except CalledProcessError as err:
283 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
284 return
285
Heinrich Schuchardtbc856172020-04-20 20:48:40 +0200286 except CalledProcessError as err:
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200287 pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900288 return
289 else:
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100290 yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fs_img, md5val]
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900291 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700292 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200293 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900294
295#
296# Fixture for extended fs test
297#
Tom Rini1b91cee2021-01-28 14:39:56 -0500298@pytest.fixture()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900299def fs_obj_ext(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900300 """Set up a file system to be used in extended fs test.
301
302 Args:
303 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200304 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900305
306 Return:
307 A fixture for extended fs test, i.e. a triplet of file system type,
308 volume file name and a list of MD5 hashes.
309 """
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900310 fs_type = request.param
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100311 fs_cmd_prefix = fstype_to_prefix(fs_type)
312 fs_cmd_write = 'save' if fs_type == 'fs_generic' else 'write'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900313 fs_img = ''
314
315 fs_ubtype = fstype_to_ubname(fs_type)
316 check_ubconfig(u_boot_config, fs_ubtype)
317
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700318 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900319
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700320 min_file = scratch_dir + '/' + MIN_FILE
321 tmp_file = scratch_dir + '/tmpfile'
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900322
323 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700324 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200325 except CalledProcessError as err:
326 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200327 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300328 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200329
330 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900331 # Create a test directory
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700332 check_call('mkdir %s/dir1' % scratch_dir, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900333
334 # Create a small file and calculate md5
335 check_call('dd if=/dev/urandom of=%s bs=1K count=20'
336 % min_file, shell=True)
337 out = check_output(
338 'dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400339 % min_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900340 md5val = [ out.split()[0] ]
341
342 # Calculate md5sum of Test Case 4
343 check_call('dd if=%s of=%s bs=1K count=20'
344 % (min_file, tmp_file), shell=True)
345 check_call('dd if=%s of=%s bs=1K seek=5 count=20'
346 % (min_file, tmp_file), shell=True)
347 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400348 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900349 md5val.append(out.split()[0])
350
351 # Calculate md5sum of Test Case 5
352 check_call('dd if=%s of=%s bs=1K count=20'
353 % (min_file, tmp_file), shell=True)
354 check_call('dd if=%s of=%s bs=1K seek=5 count=5'
355 % (min_file, tmp_file), shell=True)
356 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400357 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900358 md5val.append(out.split()[0])
359
360 # Calculate md5sum of Test Case 7
361 check_call('dd if=%s of=%s bs=1K count=20'
362 % (min_file, tmp_file), shell=True)
363 check_call('dd if=%s of=%s bs=1K seek=20 count=20'
364 % (min_file, tmp_file), shell=True)
365 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400366 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900367 md5val.append(out.split()[0])
368
369 check_call('rm %s' % tmp_file, shell=True)
Richard Weinberger41eca322024-11-21 15:32:07 -0700370
371 try:
372 # 128MiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700373 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700374 except CalledProcessError as err:
375 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
376 return
377
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900378 except CalledProcessError:
379 pytest.skip('Setup failed for filesystem: ' + fs_type)
380 return
381 else:
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100382 yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fs_img, md5val]
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900383 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700384 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200385 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900386
387#
388# Fixture for mkdir test
389#
Tom Rini1b91cee2021-01-28 14:39:56 -0500390@pytest.fixture()
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900391def fs_obj_mkdir(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900392 """Set up a file system to be used in mkdir test.
393
394 Args:
395 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200396 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900397
398 Return:
399 A fixture for mkdir test, i.e. a duplet of file system type and
400 volume file name.
401 """
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900402 fs_type = request.param
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100403 fs_cmd_prefix = fstype_to_prefix(fs_type)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900404 fs_img = ''
405
406 fs_ubtype = fstype_to_ubname(fs_type)
407 check_ubconfig(u_boot_config, fs_ubtype)
408
409 try:
410 # 128MiB volume
Richard Weinberger41eca322024-11-21 15:32:07 -0700411 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', None)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900412 except:
413 pytest.skip('Setup failed for filesystem: ' + fs_type)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200414 return
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900415 else:
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100416 yield [fs_ubtype, fs_cmd_prefix, fs_img]
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200417 call('rm -f %s' % fs_img, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900418
419#
420# Fixture for unlink test
421#
Tom Rini1b91cee2021-01-28 14:39:56 -0500422@pytest.fixture()
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900423def fs_obj_unlink(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900424 """Set up a file system to be used in unlink test.
425
426 Args:
427 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200428 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900429
430 Return:
431 A fixture for unlink test, i.e. a duplet of file system type and
432 volume file name.
433 """
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900434 fs_type = request.param
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100435 fs_cmd_prefix = fstype_to_prefix(fs_type)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900436 fs_img = ''
437
438 fs_ubtype = fstype_to_ubname(fs_type)
439 check_ubconfig(u_boot_config, fs_ubtype)
440
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700441 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900442
443 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700444 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200445 except CalledProcessError as err:
446 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200447 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300448 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200449
450 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900451 # Test Case 1 & 3
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700452 check_call('mkdir %s/dir1' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900453 check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700454 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900455 check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700456 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900457
458 # Test Case 2
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700459 check_call('mkdir %s/dir2' % scratch_dir, shell=True)
Tom Rini7f24c192019-10-24 11:59:20 -0400460 for i in range(0, 20):
461 check_call('mkdir %s/dir2/0123456789abcdef%02x'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700462 % (scratch_dir, i), shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900463
464 # Test Case 4
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700465 check_call('mkdir %s/dir4' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900466
467 # Test Case 5, 6 & 7
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700468 check_call('mkdir %s/dir5' % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900469 check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700470 % scratch_dir, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900471
Richard Weinberger41eca322024-11-21 15:32:07 -0700472 try:
473 # 128MiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700474 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700475 except CalledProcessError as err:
476 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
477 return
478
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900479 except CalledProcessError:
480 pytest.skip('Setup failed for filesystem: ' + fs_type)
481 return
482 else:
Marek Vasut8d3fb2b2025-03-17 04:12:42 +0100483 yield [fs_ubtype, fs_cmd_prefix, fs_img]
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900484 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700485 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200486 call('rm -f %s' % fs_img, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100487
488#
489# Fixture for symlink fs test
490#
Tom Rini1b91cee2021-01-28 14:39:56 -0500491@pytest.fixture()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100492def fs_obj_symlink(request, u_boot_config):
493 """Set up a file system to be used in symlink fs test.
494
495 Args:
496 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200497 u_boot_config: U-Boot configuration.
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100498
499 Return:
500 A fixture for basic fs test, i.e. a triplet of file system type,
501 volume file name and a list of MD5 hashes.
502 """
503 fs_type = request.param
504 fs_img = ''
505
506 fs_ubtype = fstype_to_ubname(fs_type)
507 check_ubconfig(u_boot_config, fs_ubtype)
508
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700509 scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100510
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700511 small_file = scratch_dir + '/' + SMALL_FILE
512 medium_file = scratch_dir + '/' + MEDIUM_FILE
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100513
514 try:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700515 check_call('mkdir -p %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200516 except CalledProcessError as err:
517 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200518 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300519 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200520
521 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100522 # Create a subdirectory.
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700523 check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100524
525 # Create a small file in this image.
526 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
527 % small_file, shell=True)
528
529 # Create a medium file in this image.
530 check_call('dd if=/dev/urandom of=%s bs=10M count=1'
531 % medium_file, shell=True)
532
533 # Generate the md5sums of reads that we will test against small file
534 out = check_output(
535 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400536 % small_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100537 md5val = [out.split()[0]]
538 out = check_output(
539 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400540 % medium_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100541 md5val.extend([out.split()[0]])
542
Richard Weinberger41eca322024-11-21 15:32:07 -0700543 try:
544 # 1GiB volume
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700545 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x40000000, '1GB', scratch_dir)
Richard Weinberger41eca322024-11-21 15:32:07 -0700546 except CalledProcessError as err:
547 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
548 return
549
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100550 except CalledProcessError:
551 pytest.skip('Setup failed for filesystem: ' + fs_type)
552 return
553 else:
554 yield [fs_ubtype, fs_img, md5val]
555 finally:
Richard Weinbergerba878ce2024-11-21 15:32:08 -0700556 call('rm -rf %s' % scratch_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200557 call('rm -f %s' % fs_img, shell=True)
Christian Taedcke570dc362023-11-15 13:44:24 +0100558
559#
Gabriel Dalimonte4b93d6e2025-02-17 13:26:44 -0500560# Fixture for rename test
561#
562@pytest.fixture()
563def fs_obj_rename(request, u_boot_config):
564 """Set up a file system to be used in rename tests.
565
566 Args:
567 request: Pytest request object.
568 u_boot_config: U-Boot configuration.
569
570 Return:
571 A fixture for rename tests, i.e. a triplet of file system type,
572 volume file name, and dictionary of test identifier and md5val.
573 """
574 def new_rand_file(path):
575 check_call('dd if=/dev/urandom of=%s bs=1K count=1' % path, shell=True)
576
577 def file_hash(path):
578 out = check_output(
579 'dd if=%s bs=1K skip=0 count=1 2> /dev/null | md5sum' % path,
580 shell=True
581 )
582 return out.decode().split()[0]
583
584 fs_type = request.param
585 fs_img = ''
586
587 fs_ubtype = fstype_to_ubname(fs_type)
588 check_ubconfig(u_boot_config, fs_ubtype)
589
590 mount_dir = u_boot_config.persistent_data_dir + '/scratch'
591
592 try:
593 check_call('mkdir -p %s' % mount_dir, shell=True)
594 except CalledProcessError as err:
595 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
596 call('rm -f %s' % fs_img, shell=True)
597 return
598
599 try:
600 md5val = {}
601 # Test Case 1
602 check_call('mkdir %s/test1' % mount_dir, shell=True)
603 new_rand_file('%s/test1/file1' % mount_dir)
604 md5val['test1'] = file_hash('%s/test1/file1' % mount_dir)
605
606 # Test Case 2
607 check_call('mkdir %s/test2' % mount_dir, shell=True)
608 new_rand_file('%s/test2/file1' % mount_dir)
609 new_rand_file('%s/test2/file_exist' % mount_dir)
610 md5val['test2'] = file_hash('%s/test2/file1' % mount_dir)
611
612 # Test Case 3
613 check_call('mkdir -p %s/test3/dir1' % mount_dir, shell=True)
614 new_rand_file('%s/test3/dir1/file1' % mount_dir)
615 md5val['test3'] = file_hash('%s/test3/dir1/file1' % mount_dir)
616
617 # Test Case 4
618 check_call('mkdir -p %s/test4/dir1' % mount_dir, shell=True)
619 check_call('mkdir -p %s/test4/dir2/dir1' % mount_dir, shell=True)
620 new_rand_file('%s/test4/dir1/file1' % mount_dir)
621 md5val['test4'] = file_hash('%s/test4/dir1/file1' % mount_dir)
622
623 # Test Case 5
624 check_call('mkdir -p %s/test5/dir1' % mount_dir, shell=True)
625 new_rand_file('%s/test5/file2' % mount_dir)
626 md5val['test5'] = file_hash('%s/test5/file2' % mount_dir)
627
628 # Test Case 6
629 check_call('mkdir -p %s/test6/dir2/existing' % mount_dir, shell=True)
630 new_rand_file('%s/test6/existing' % mount_dir)
631 md5val['test6'] = file_hash('%s/test6/existing' % mount_dir)
632
633 # Test Case 7
634 check_call('mkdir -p %s/test7/dir1' % mount_dir, shell=True)
635 check_call('mkdir -p %s/test7/dir2/dir1' % mount_dir, shell=True)
636 new_rand_file('%s/test7/dir2/dir1/file1' % mount_dir)
637 md5val['test7'] = file_hash('%s/test7/dir2/dir1/file1' % mount_dir)
638
639 # Test Case 8
640 check_call('mkdir -p %s/test8/dir1' % mount_dir, shell=True)
641 new_rand_file('%s/test8/dir1/file1' % mount_dir)
642 md5val['test8'] = file_hash('%s/test8/dir1/file1' % mount_dir)
643
644 # Test Case 9
645 check_call('mkdir -p %s/test9/dir1/nested/inner' % mount_dir, shell=True)
646 new_rand_file('%s/test9/dir1/nested/inner/file1' % mount_dir)
647
648 # Test Case 10
649 check_call('mkdir -p %s/test10' % mount_dir, shell=True)
650 new_rand_file('%s/test10/file1' % mount_dir)
651 md5val['test10'] = file_hash('%s/test10/file1' % mount_dir)
652
653 # Test Case 11
654 check_call('mkdir -p %s/test11/dir1' % mount_dir, shell=True)
655 new_rand_file('%s/test11/dir1/file1' % mount_dir)
656 md5val['test11'] = file_hash('%s/test11/dir1/file1' % mount_dir)
657
658 try:
659 # 128MiB volume
660 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', mount_dir)
661 except CalledProcessError as err:
662 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
663 return
664
665 except CalledProcessError:
666 pytest.skip('Setup failed for filesystem: ' + fs_type)
667 return
668 else:
669 yield [fs_ubtype, fs_img, md5val]
670 finally:
671 call('rm -rf %s' % mount_dir, shell=True)
672 call('rm -f %s' % fs_img, shell=True)
673
674#
Christian Taedcke570dc362023-11-15 13:44:24 +0100675# Fixture for fat test
676#
677@pytest.fixture()
678def fs_obj_fat(request, u_boot_config):
679 """Set up a file system to be used in fat test.
680
681 Args:
682 request: Pytest request object.
683 u_boot_config: U-Boot configuration.
684
685 Return:
686 A fixture for fat test, i.e. a duplet of file system type and
687 volume file name.
688 """
689
690 # the maximum size of a FAT12 filesystem resulting in 4084 clusters
691 MAX_FAT12_SIZE = 261695 * 1024
692
693 # the minimum size of a FAT16 filesystem that can be created with
694 # mkfs.vfat resulting in 4087 clusters
695 MIN_FAT16_SIZE = 8208 * 1024
696
697 fs_type = request.param
698 fs_img = ''
699
700 fs_ubtype = fstype_to_ubname(fs_type)
701 check_ubconfig(u_boot_config, fs_ubtype)
702
703 fs_size = MAX_FAT12_SIZE if fs_type == 'fat12' else MIN_FAT16_SIZE
704
705 try:
706 # the volume size depends on the filesystem
Richard Weinberger41eca322024-11-21 15:32:07 -0700707 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 +0100708 except:
709 pytest.skip('Setup failed for filesystem: ' + fs_type)
710 return
711 else:
712 yield [fs_ubtype, fs_img]
713 call('rm -f %s' % fs_img, shell=True)