blob: fdd138d6ee4d9652a81d8f7b42862c54ac76ff25 [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
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']
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090020
21#
22# Filesystem test specific setup
23#
24def pytest_addoption(parser):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090025 """Enable --fs-type option.
26
27 See pytest_configure() about how it works.
28
29 Args:
30 parser: Pytest command-line parser.
31
32 Returns:
33 Nothing.
34 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090035 parser.addoption('--fs-type', action='append', default=None,
36 help='Targeting Filesystem Types')
37
38def pytest_configure(config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090039 """Restrict a file system(s) to be tested.
40
41 A file system explicitly named with --fs-type option is selected
42 if it belongs to a default supported_fs_xxx list.
43 Multiple options can be specified.
44
45 Args:
46 config: Pytest configuration.
47
48 Returns:
49 Nothing.
50 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090051 global supported_fs_basic
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090052 global supported_fs_ext
Christian Taedcke570dc362023-11-15 13:44:24 +010053 global supported_fs_fat
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090054 global supported_fs_mkdir
Akashi, Takahirod49e7992018-09-11 16:06:03 +090055 global supported_fs_unlink
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010056 global supported_fs_symlink
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090057
58 def intersect(listA, listB):
59 return [x for x in listA if x in listB]
60
61 supported_fs = config.getoption('fs_type')
62 if supported_fs:
Simon Glasse9f4d872018-12-27 08:11:13 -070063 print('*** FS TYPE modified: %s' % supported_fs)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090064 supported_fs_basic = intersect(supported_fs, supported_fs_basic)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090065 supported_fs_ext = intersect(supported_fs, supported_fs_ext)
Christian Taedcke570dc362023-11-15 13:44:24 +010066 supported_fs_fat = intersect(supported_fs, supported_fs_fat)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090067 supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +090068 supported_fs_unlink = intersect(supported_fs, supported_fs_unlink)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010069 supported_fs_symlink = intersect(supported_fs, supported_fs_symlink)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090070
71def pytest_generate_tests(metafunc):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090072 """Parametrize fixtures, fs_obj_xxx
73
74 Each fixture will be parametrized with a corresponding support_fs_xxx
75 list.
76
77 Args:
78 metafunc: Pytest test function.
79
80 Returns:
81 Nothing.
82 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090083 if 'fs_obj_basic' in metafunc.fixturenames:
84 metafunc.parametrize('fs_obj_basic', supported_fs_basic,
85 indirect=True, scope='module')
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090086 if 'fs_obj_ext' in metafunc.fixturenames:
87 metafunc.parametrize('fs_obj_ext', supported_fs_ext,
88 indirect=True, scope='module')
Christian Taedcke570dc362023-11-15 13:44:24 +010089 if 'fs_obj_fat' in metafunc.fixturenames:
90 metafunc.parametrize('fs_obj_fat', supported_fs_fat,
91 indirect=True, scope='module')
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090092 if 'fs_obj_mkdir' in metafunc.fixturenames:
93 metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir,
94 indirect=True, scope='module')
Akashi, Takahirod49e7992018-09-11 16:06:03 +090095 if 'fs_obj_unlink' in metafunc.fixturenames:
96 metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
97 indirect=True, scope='module')
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010098 if 'fs_obj_symlink' in metafunc.fixturenames:
99 metafunc.parametrize('fs_obj_symlink', supported_fs_symlink,
100 indirect=True, scope='module')
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900101
102#
103# Helper functions
104#
105def fstype_to_ubname(fs_type):
Michal Simek50fa1182023-05-17 09:17:16 +0200106 """Convert a file system type to an U-Boot specific string
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900107
108 A generated string can be used as part of file system related commands
109 or a config name in u-boot. Currently fat16 and fat32 are handled
110 specifically.
111
112 Args:
113 fs_type: File system type.
114
115 Return:
116 A corresponding string for file system type.
117 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900118 if re.match('fat', fs_type):
119 return 'fat'
120 else:
121 return fs_type
122
123def check_ubconfig(config, fs_type):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900124 """Check whether a file system is enabled in u-boot configuration.
125
126 This function is assumed to be called in a fixture function so that
127 the whole test cases will be skipped if a given file system is not
128 enabled.
129
130 Args:
131 fs_type: File system type.
132
133 Return:
134 Nothing.
135 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900136 if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
137 pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
138 if not config.buildconfig.get('config_%s_write' % fs_type, None):
139 pytest.skip('.config feature "%s_WRITE" not enabled'
140 % fs_type.upper())
141
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900142# from test/py/conftest.py
143def tool_is_in_path(tool):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900144 """Check whether a given command is available on host.
145
146 Args:
147 tool: Command name.
148
149 Return:
150 True if available, False if not.
151 """
Simon Glasse9f4d872018-12-27 08:11:13 -0700152 for path in os.environ['PATH'].split(os.pathsep):
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900153 fn = os.path.join(path, tool)
154 if os.path.isfile(fn) and os.access(fn, os.X_OK):
155 return True
156 return False
157
158fuse_mounted = False
159
160def mount_fs(fs_type, device, mount_point):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900161 """Mount a volume.
162
163 Args:
164 fs_type: File system type.
165 device: Volume's file name.
166 mount_point: Mount point.
167
168 Return:
169 Nothing.
170 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900171 global fuse_mounted
172
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900173 try:
Alper Nebi Yasak7ff17f22021-06-04 22:04:46 +0300174 check_call('guestmount --pid-file guestmount.pid -a %s -m /dev/sda %s'
Alper Nebi Yasak3dec7a52021-06-04 22:04:45 +0300175 % (device, mount_point), shell=True)
176 fuse_mounted = True
177 return
178 except CalledProcessError:
179 fuse_mounted = False
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900180
Alper Nebi Yasak3dec7a52021-06-04 22:04:45 +0300181 mount_opt = 'loop,rw'
182 if re.match('fat', fs_type):
183 mount_opt += ',umask=0000'
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900184
Alper Nebi Yasak3dec7a52021-06-04 22:04:45 +0300185 check_call('sudo mount -o %s %s %s'
186 % (mount_opt, device, mount_point), shell=True)
187
188 # may not be effective for some file systems
189 check_call('sudo chmod a+rw %s' % mount_point, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900190
Akashi Takahiro89101f82018-09-27 16:07:22 +0900191def umount_fs(mount_point):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900192 """Unmount a volume.
193
194 Args:
195 mount_point: Mount point.
196
197 Return:
198 Nothing.
199 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900200 if fuse_mounted:
201 call('sync')
202 call('guestunmount %s' % mount_point, shell=True)
Alper Nebi Yasak7ff17f22021-06-04 22:04:46 +0300203
204 try:
205 with open("guestmount.pid", "r") as pidfile:
206 pid = int(pidfile.read())
207 util.waitpid(pid, kill=True)
208 os.remove("guestmount.pid")
209
210 except FileNotFoundError:
211 pass
212
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900213 else:
214 call('sudo umount %s' % mount_point, shell=True)
215
216#
217# Fixture for basic fs test
218# derived from test/fs/fs-test.sh
219#
Tom Rini1b91cee2021-01-28 14:39:56 -0500220@pytest.fixture()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900221def fs_obj_basic(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900222 """Set up a file system to be used in basic fs test.
223
224 Args:
225 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200226 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900227
228 Return:
229 A fixture for basic fs test, i.e. a triplet of file system type,
230 volume file name and a list of MD5 hashes.
231 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900232 fs_type = request.param
233 fs_img = ''
234
235 fs_ubtype = fstype_to_ubname(fs_type)
236 check_ubconfig(u_boot_config, fs_ubtype)
237
238 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
239
240 small_file = mount_dir + '/' + SMALL_FILE
241 big_file = mount_dir + '/' + BIG_FILE
242
243 try:
244
245 # 3GiB volume
Simon Glass1d5006c2022-10-29 19:47:05 -0600246 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200247 except CalledProcessError as err:
248 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
249 return
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900250
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200251 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900252 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200253 except CalledProcessError as err:
254 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200255 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300256 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200257
258 try:
259 # Mount the image so we can populate it.
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900260 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300261 except CalledProcessError as err:
262 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
263 call('rmdir %s' % mount_dir, shell=True)
264 call('rm -f %s' % fs_img, shell=True)
265 return
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900266
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300267 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900268 # Create a subdirectory.
269 check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
270
271 # Create big file in this image.
272 # Note that we work only on the start 1MB, couple MBs in the 2GB range
273 # and the last 1 MB of the huge 2.5GB file.
274 # So, just put random values only in those areas.
275 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
276 % big_file, shell=True)
277 check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
278 % big_file, shell=True)
279 check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
280 % big_file, shell=True)
281
282 # Create a small file in this image.
283 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
284 % small_file, shell=True)
285
286 # Delete the small file copies which possibly are written as part of a
287 # previous test.
288 # check_call('rm -f "%s.w"' % MB1, shell=True)
289 # check_call('rm -f "%s.w2"' % MB1, shell=True)
290
291 # Generate the md5sums of reads that we will test against small file
292 out = check_output(
293 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400294 % small_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900295 md5val = [ out.split()[0] ]
296
297 # Generate the md5sums of reads that we will test against big file
298 # One from beginning of file.
299 out = check_output(
300 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400301 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900302 md5val.append(out.split()[0])
303
304 # One from end of file.
305 out = check_output(
306 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400307 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900308 md5val.append(out.split()[0])
309
310 # One from the last 1MB chunk of 2GB
311 out = check_output(
312 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400313 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900314 md5val.append(out.split()[0])
315
316 # One from the start 1MB chunk from 2GB
317 out = check_output(
318 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400319 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900320 md5val.append(out.split()[0])
321
322 # One 1MB chunk crossing the 2GB boundary
323 out = check_output(
324 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400325 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900326 md5val.append(out.split()[0])
327
Heinrich Schuchardtbc856172020-04-20 20:48:40 +0200328 except CalledProcessError as err:
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200329 pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300330 umount_fs(mount_dir)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900331 return
332 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300333 umount_fs(mount_dir)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900334 yield [fs_ubtype, fs_img, md5val]
335 finally:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900336 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200337 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900338
339#
340# Fixture for extended fs test
341#
Tom Rini1b91cee2021-01-28 14:39:56 -0500342@pytest.fixture()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900343def fs_obj_ext(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900344 """Set up a file system to be used in extended fs test.
345
346 Args:
347 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200348 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900349
350 Return:
351 A fixture for extended fs test, i.e. a triplet of file system type,
352 volume file name and a list of MD5 hashes.
353 """
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900354 fs_type = request.param
355 fs_img = ''
356
357 fs_ubtype = fstype_to_ubname(fs_type)
358 check_ubconfig(u_boot_config, fs_ubtype)
359
360 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
361
362 min_file = mount_dir + '/' + MIN_FILE
363 tmp_file = mount_dir + '/tmpfile'
364
365 try:
366
367 # 128MiB volume
Simon Glass1d5006c2022-10-29 19:47:05 -0600368 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200369 except CalledProcessError as err:
370 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
371 return
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900372
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200373 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900374 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200375 except CalledProcessError as err:
376 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200377 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300378 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200379
380 try:
381 # Mount the image so we can populate it.
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900382 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300383 except CalledProcessError as err:
384 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
385 call('rmdir %s' % mount_dir, shell=True)
386 call('rm -f %s' % fs_img, shell=True)
387 return
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900388
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300389 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900390 # Create a test directory
391 check_call('mkdir %s/dir1' % mount_dir, shell=True)
392
393 # Create a small file and calculate md5
394 check_call('dd if=/dev/urandom of=%s bs=1K count=20'
395 % min_file, shell=True)
396 out = check_output(
397 'dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400398 % min_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900399 md5val = [ out.split()[0] ]
400
401 # Calculate md5sum of Test Case 4
402 check_call('dd if=%s of=%s bs=1K count=20'
403 % (min_file, tmp_file), shell=True)
404 check_call('dd if=%s of=%s bs=1K seek=5 count=20'
405 % (min_file, tmp_file), shell=True)
406 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400407 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900408 md5val.append(out.split()[0])
409
410 # Calculate md5sum of Test Case 5
411 check_call('dd if=%s of=%s bs=1K count=20'
412 % (min_file, tmp_file), shell=True)
413 check_call('dd if=%s of=%s bs=1K seek=5 count=5'
414 % (min_file, tmp_file), shell=True)
415 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400416 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900417 md5val.append(out.split()[0])
418
419 # Calculate md5sum of Test Case 7
420 check_call('dd if=%s of=%s bs=1K count=20'
421 % (min_file, tmp_file), shell=True)
422 check_call('dd if=%s of=%s bs=1K seek=20 count=20'
423 % (min_file, tmp_file), shell=True)
424 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400425 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900426 md5val.append(out.split()[0])
427
428 check_call('rm %s' % tmp_file, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900429 except CalledProcessError:
430 pytest.skip('Setup failed for filesystem: ' + fs_type)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300431 umount_fs(mount_dir)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900432 return
433 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300434 umount_fs(mount_dir)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900435 yield [fs_ubtype, fs_img, md5val]
436 finally:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900437 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200438 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900439
440#
441# Fixture for mkdir test
442#
Tom Rini1b91cee2021-01-28 14:39:56 -0500443@pytest.fixture()
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900444def fs_obj_mkdir(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900445 """Set up a file system to be used in mkdir test.
446
447 Args:
448 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200449 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900450
451 Return:
452 A fixture for mkdir test, i.e. a duplet of file system type and
453 volume file name.
454 """
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900455 fs_type = request.param
456 fs_img = ''
457
458 fs_ubtype = fstype_to_ubname(fs_type)
459 check_ubconfig(u_boot_config, fs_ubtype)
460
461 try:
462 # 128MiB volume
Simon Glass1d5006c2022-10-29 19:47:05 -0600463 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900464 except:
465 pytest.skip('Setup failed for filesystem: ' + fs_type)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200466 return
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900467 else:
468 yield [fs_ubtype, fs_img]
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200469 call('rm -f %s' % fs_img, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900470
471#
472# Fixture for unlink test
473#
Tom Rini1b91cee2021-01-28 14:39:56 -0500474@pytest.fixture()
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900475def fs_obj_unlink(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900476 """Set up a file system to be used in unlink test.
477
478 Args:
479 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200480 u_boot_config: U-Boot configuration.
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900481
482 Return:
483 A fixture for unlink test, i.e. a duplet of file system type and
484 volume file name.
485 """
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900486 fs_type = request.param
487 fs_img = ''
488
489 fs_ubtype = fstype_to_ubname(fs_type)
490 check_ubconfig(u_boot_config, fs_ubtype)
491
492 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
493
494 try:
495
496 # 128MiB volume
Simon Glass1d5006c2022-10-29 19:47:05 -0600497 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200498 except CalledProcessError as err:
499 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
500 return
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900501
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200502 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900503 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200504 except CalledProcessError as err:
505 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200506 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300507 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200508
509 try:
510 # Mount the image so we can populate it.
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900511 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300512 except CalledProcessError as err:
513 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
514 call('rmdir %s' % mount_dir, shell=True)
515 call('rm -f %s' % fs_img, shell=True)
516 return
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900517
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300518 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900519 # Test Case 1 & 3
520 check_call('mkdir %s/dir1' % mount_dir, shell=True)
521 check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
522 % mount_dir, shell=True)
523 check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
524 % mount_dir, shell=True)
525
526 # Test Case 2
527 check_call('mkdir %s/dir2' % mount_dir, shell=True)
Tom Rini7f24c192019-10-24 11:59:20 -0400528 for i in range(0, 20):
529 check_call('mkdir %s/dir2/0123456789abcdef%02x'
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900530 % (mount_dir, i), shell=True)
531
532 # Test Case 4
533 check_call('mkdir %s/dir4' % mount_dir, shell=True)
534
535 # Test Case 5, 6 & 7
536 check_call('mkdir %s/dir5' % mount_dir, shell=True)
537 check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
538 % mount_dir, shell=True)
539
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900540 except CalledProcessError:
541 pytest.skip('Setup failed for filesystem: ' + fs_type)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300542 umount_fs(mount_dir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900543 return
544 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300545 umount_fs(mount_dir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900546 yield [fs_ubtype, fs_img]
547 finally:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900548 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200549 call('rm -f %s' % fs_img, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100550
551#
552# Fixture for symlink fs test
553#
Tom Rini1b91cee2021-01-28 14:39:56 -0500554@pytest.fixture()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100555def fs_obj_symlink(request, u_boot_config):
556 """Set up a file system to be used in symlink fs test.
557
558 Args:
559 request: Pytest request object.
Michal Simek50fa1182023-05-17 09:17:16 +0200560 u_boot_config: U-Boot configuration.
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100561
562 Return:
563 A fixture for basic fs test, i.e. a triplet of file system type,
564 volume file name and a list of MD5 hashes.
565 """
566 fs_type = request.param
567 fs_img = ''
568
569 fs_ubtype = fstype_to_ubname(fs_type)
570 check_ubconfig(u_boot_config, fs_ubtype)
571
572 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
573
574 small_file = mount_dir + '/' + SMALL_FILE
575 medium_file = mount_dir + '/' + MEDIUM_FILE
576
577 try:
578
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200579 # 1GiB volume
Simon Glass1d5006c2022-10-29 19:47:05 -0600580 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x40000000, '1GB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200581 except CalledProcessError as err:
582 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
583 return
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100584
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200585 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100586 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200587 except CalledProcessError as err:
588 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200589 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300590 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200591
592 try:
593 # Mount the image so we can populate it.
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100594 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300595 except CalledProcessError as err:
596 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
597 call('rmdir %s' % mount_dir, shell=True)
598 call('rm -f %s' % fs_img, shell=True)
599 return
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100600
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300601 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100602 # Create a subdirectory.
603 check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
604
605 # Create a small file in this image.
606 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
607 % small_file, shell=True)
608
609 # Create a medium file in this image.
610 check_call('dd if=/dev/urandom of=%s bs=10M count=1'
611 % medium_file, shell=True)
612
613 # Generate the md5sums of reads that we will test against small file
614 out = check_output(
615 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400616 % small_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100617 md5val = [out.split()[0]]
618 out = check_output(
619 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400620 % medium_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100621 md5val.extend([out.split()[0]])
622
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100623 except CalledProcessError:
624 pytest.skip('Setup failed for filesystem: ' + fs_type)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300625 umount_fs(mount_dir)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100626 return
627 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300628 umount_fs(mount_dir)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100629 yield [fs_ubtype, fs_img, md5val]
630 finally:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100631 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200632 call('rm -f %s' % fs_img, shell=True)
Christian Taedcke570dc362023-11-15 13:44:24 +0100633
634#
635# Fixture for fat test
636#
637@pytest.fixture()
638def fs_obj_fat(request, u_boot_config):
639 """Set up a file system to be used in fat test.
640
641 Args:
642 request: Pytest request object.
643 u_boot_config: U-Boot configuration.
644
645 Return:
646 A fixture for fat test, i.e. a duplet of file system type and
647 volume file name.
648 """
649
650 # the maximum size of a FAT12 filesystem resulting in 4084 clusters
651 MAX_FAT12_SIZE = 261695 * 1024
652
653 # the minimum size of a FAT16 filesystem that can be created with
654 # mkfs.vfat resulting in 4087 clusters
655 MIN_FAT16_SIZE = 8208 * 1024
656
657 fs_type = request.param
658 fs_img = ''
659
660 fs_ubtype = fstype_to_ubname(fs_type)
661 check_ubconfig(u_boot_config, fs_ubtype)
662
663 fs_size = MAX_FAT12_SIZE if fs_type == 'fat12' else MIN_FAT16_SIZE
664
665 try:
666 # the volume size depends on the filesystem
667 fs_img = fs_helper.mk_fs(u_boot_config, fs_type, fs_size, f'{fs_size}', 1024)
668 except:
669 pytest.skip('Setup failed for filesystem: ' + fs_type)
670 return
671 else:
672 yield [fs_ubtype, fs_img]
673 call('rm -f %s' % fs_img, shell=True)