blob: b638284e076bcb3809c7a5b661f2d36755dab0b5 [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
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090012
13supported_fs_basic = ['fat16', 'fat32', 'ext4']
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090014supported_fs_ext = ['fat16', 'fat32']
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090015supported_fs_mkdir = ['fat16', 'fat32']
Akashi, Takahirod49e7992018-09-11 16:06:03 +090016supported_fs_unlink = ['fat16', 'fat32']
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010017supported_fs_symlink = ['ext4']
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090018
19#
20# Filesystem test specific setup
21#
22def pytest_addoption(parser):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090023 """Enable --fs-type option.
24
25 See pytest_configure() about how it works.
26
27 Args:
28 parser: Pytest command-line parser.
29
30 Returns:
31 Nothing.
32 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090033 parser.addoption('--fs-type', action='append', default=None,
34 help='Targeting Filesystem Types')
35
36def pytest_configure(config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090037 """Restrict a file system(s) to be tested.
38
39 A file system explicitly named with --fs-type option is selected
40 if it belongs to a default supported_fs_xxx list.
41 Multiple options can be specified.
42
43 Args:
44 config: Pytest configuration.
45
46 Returns:
47 Nothing.
48 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090049 global supported_fs_basic
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090050 global supported_fs_ext
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090051 global supported_fs_mkdir
Akashi, Takahirod49e7992018-09-11 16:06:03 +090052 global supported_fs_unlink
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010053 global supported_fs_symlink
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090054
55 def intersect(listA, listB):
56 return [x for x in listA if x in listB]
57
58 supported_fs = config.getoption('fs_type')
59 if supported_fs:
Simon Glasse9f4d872018-12-27 08:11:13 -070060 print('*** FS TYPE modified: %s' % supported_fs)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090061 supported_fs_basic = intersect(supported_fs, supported_fs_basic)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090062 supported_fs_ext = intersect(supported_fs, supported_fs_ext)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090063 supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +090064 supported_fs_unlink = intersect(supported_fs, supported_fs_unlink)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010065 supported_fs_symlink = intersect(supported_fs, supported_fs_symlink)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090066
67def pytest_generate_tests(metafunc):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090068 """Parametrize fixtures, fs_obj_xxx
69
70 Each fixture will be parametrized with a corresponding support_fs_xxx
71 list.
72
73 Args:
74 metafunc: Pytest test function.
75
76 Returns:
77 Nothing.
78 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090079 if 'fs_obj_basic' in metafunc.fixturenames:
80 metafunc.parametrize('fs_obj_basic', supported_fs_basic,
81 indirect=True, scope='module')
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +090082 if 'fs_obj_ext' in metafunc.fixturenames:
83 metafunc.parametrize('fs_obj_ext', supported_fs_ext,
84 indirect=True, scope='module')
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +090085 if 'fs_obj_mkdir' in metafunc.fixturenames:
86 metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir,
87 indirect=True, scope='module')
Akashi, Takahirod49e7992018-09-11 16:06:03 +090088 if 'fs_obj_unlink' in metafunc.fixturenames:
89 metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
90 indirect=True, scope='module')
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +010091 if 'fs_obj_symlink' in metafunc.fixturenames:
92 metafunc.parametrize('fs_obj_symlink', supported_fs_symlink,
93 indirect=True, scope='module')
AKASHI Takahiro615af9a2018-09-11 15:59:19 +090094
95#
96# Helper functions
97#
98def fstype_to_ubname(fs_type):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +090099 """Convert a file system type to an U-boot specific string
100
101 A generated string can be used as part of file system related commands
102 or a config name in u-boot. Currently fat16 and fat32 are handled
103 specifically.
104
105 Args:
106 fs_type: File system type.
107
108 Return:
109 A corresponding string for file system type.
110 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900111 if re.match('fat', fs_type):
112 return 'fat'
113 else:
114 return fs_type
115
116def check_ubconfig(config, fs_type):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900117 """Check whether a file system is enabled in u-boot configuration.
118
119 This function is assumed to be called in a fixture function so that
120 the whole test cases will be skipped if a given file system is not
121 enabled.
122
123 Args:
124 fs_type: File system type.
125
126 Return:
127 Nothing.
128 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900129 if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
130 pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
131 if not config.buildconfig.get('config_%s_write' % fs_type, None):
132 pytest.skip('.config feature "%s_WRITE" not enabled'
133 % fs_type.upper())
134
135def mk_fs(config, fs_type, size, id):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900136 """Create a file system volume.
137
138 Args:
139 fs_type: File system type.
140 size: Size of file system in MiB.
141 id: Prefix string of volume's file name.
142
143 Return:
144 Nothing.
145 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900146 fs_img = '%s.%s.img' % (id, fs_type)
147 fs_img = config.persistent_data_dir + '/' + fs_img
148
149 if fs_type == 'fat16':
150 mkfs_opt = '-F 16'
151 elif fs_type == 'fat32':
152 mkfs_opt = '-F 32'
153 else:
154 mkfs_opt = ''
155
156 if re.match('fat', fs_type):
157 fs_lnxtype = 'vfat'
158 else:
159 fs_lnxtype = fs_type
160
161 count = (size + 1048576 - 1) / 1048576
162
Andy Shevchenko70e473f2021-06-10 18:08:42 +0300163 # Some distributions do not add /sbin to the default PATH, where mkfs lives
164 if '/sbin' not in os.environ["PATH"].split(os.pathsep):
165 os.environ["PATH"] += os.pathsep + '/sbin'
166
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900167 try:
168 check_call('rm -f %s' % fs_img, shell=True)
169 check_call('dd if=/dev/zero of=%s bs=1M count=%d'
170 % (fs_img, count), shell=True)
171 check_call('mkfs.%s %s %s'
172 % (fs_lnxtype, mkfs_opt, fs_img), shell=True)
Stephen Warrenf7d10932020-08-04 11:28:33 -0600173 if fs_type == 'ext4':
174 sb_content = check_output('tune2fs -l %s' % fs_img, shell=True).decode()
175 if 'metadata_csum' in sb_content:
176 check_call('tune2fs -O ^metadata_csum %s' % fs_img, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900177 return fs_img
178 except CalledProcessError:
179 call('rm -f %s' % fs_img, shell=True)
180 raise
181
182# from test/py/conftest.py
183def tool_is_in_path(tool):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900184 """Check whether a given command is available on host.
185
186 Args:
187 tool: Command name.
188
189 Return:
190 True if available, False if not.
191 """
Simon Glasse9f4d872018-12-27 08:11:13 -0700192 for path in os.environ['PATH'].split(os.pathsep):
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900193 fn = os.path.join(path, tool)
194 if os.path.isfile(fn) and os.access(fn, os.X_OK):
195 return True
196 return False
197
198fuse_mounted = False
199
200def mount_fs(fs_type, device, mount_point):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900201 """Mount a volume.
202
203 Args:
204 fs_type: File system type.
205 device: Volume's file name.
206 mount_point: Mount point.
207
208 Return:
209 Nothing.
210 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900211 global fuse_mounted
212
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900213 try:
Alper Nebi Yasak7ff17f22021-06-04 22:04:46 +0300214 check_call('guestmount --pid-file guestmount.pid -a %s -m /dev/sda %s'
Alper Nebi Yasak3dec7a52021-06-04 22:04:45 +0300215 % (device, mount_point), shell=True)
216 fuse_mounted = True
217 return
218 except CalledProcessError:
219 fuse_mounted = False
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900220
Alper Nebi Yasak3dec7a52021-06-04 22:04:45 +0300221 mount_opt = 'loop,rw'
222 if re.match('fat', fs_type):
223 mount_opt += ',umask=0000'
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900224
Alper Nebi Yasak3dec7a52021-06-04 22:04:45 +0300225 check_call('sudo mount -o %s %s %s'
226 % (mount_opt, device, mount_point), shell=True)
227
228 # may not be effective for some file systems
229 check_call('sudo chmod a+rw %s' % mount_point, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900230
Akashi Takahiro89101f82018-09-27 16:07:22 +0900231def umount_fs(mount_point):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900232 """Unmount a volume.
233
234 Args:
235 mount_point: Mount point.
236
237 Return:
238 Nothing.
239 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900240 if fuse_mounted:
241 call('sync')
242 call('guestunmount %s' % mount_point, shell=True)
Alper Nebi Yasak7ff17f22021-06-04 22:04:46 +0300243
244 try:
245 with open("guestmount.pid", "r") as pidfile:
246 pid = int(pidfile.read())
247 util.waitpid(pid, kill=True)
248 os.remove("guestmount.pid")
249
250 except FileNotFoundError:
251 pass
252
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900253 else:
254 call('sudo umount %s' % mount_point, shell=True)
255
256#
257# Fixture for basic fs test
258# derived from test/fs/fs-test.sh
259#
Tom Rini1b91cee2021-01-28 14:39:56 -0500260@pytest.fixture()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900261def fs_obj_basic(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900262 """Set up a file system to be used in basic fs test.
263
264 Args:
265 request: Pytest request object.
266 u_boot_config: U-boot configuration.
267
268 Return:
269 A fixture for basic fs test, i.e. a triplet of file system type,
270 volume file name and a list of MD5 hashes.
271 """
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900272 fs_type = request.param
273 fs_img = ''
274
275 fs_ubtype = fstype_to_ubname(fs_type)
276 check_ubconfig(u_boot_config, fs_ubtype)
277
278 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
279
280 small_file = mount_dir + '/' + SMALL_FILE
281 big_file = mount_dir + '/' + BIG_FILE
282
283 try:
284
285 # 3GiB volume
286 fs_img = mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200287 except CalledProcessError as err:
288 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
289 return
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900290
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200291 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900292 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200293 except CalledProcessError as err:
294 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200295 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300296 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200297
298 try:
299 # Mount the image so we can populate it.
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900300 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300301 except CalledProcessError as err:
302 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
303 call('rmdir %s' % mount_dir, shell=True)
304 call('rm -f %s' % fs_img, shell=True)
305 return
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900306
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300307 try:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900308 # Create a subdirectory.
309 check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
310
311 # Create big file in this image.
312 # Note that we work only on the start 1MB, couple MBs in the 2GB range
313 # and the last 1 MB of the huge 2.5GB file.
314 # So, just put random values only in those areas.
315 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
316 % big_file, shell=True)
317 check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
318 % big_file, shell=True)
319 check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
320 % big_file, shell=True)
321
322 # Create a small file in this image.
323 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
324 % small_file, shell=True)
325
326 # Delete the small file copies which possibly are written as part of a
327 # previous test.
328 # check_call('rm -f "%s.w"' % MB1, shell=True)
329 # check_call('rm -f "%s.w2"' % MB1, shell=True)
330
331 # Generate the md5sums of reads that we will test against small file
332 out = check_output(
333 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400334 % small_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900335 md5val = [ out.split()[0] ]
336
337 # Generate the md5sums of reads that we will test against big file
338 # One from beginning of file.
339 out = check_output(
340 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400341 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900342 md5val.append(out.split()[0])
343
344 # One from end of file.
345 out = check_output(
346 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400347 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900348 md5val.append(out.split()[0])
349
350 # One from the last 1MB chunk of 2GB
351 out = check_output(
352 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400353 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900354 md5val.append(out.split()[0])
355
356 # One from the start 1MB chunk from 2GB
357 out = check_output(
358 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400359 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900360 md5val.append(out.split()[0])
361
362 # One 1MB chunk crossing the 2GB boundary
363 out = check_output(
364 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400365 % big_file, shell=True).decode()
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900366 md5val.append(out.split()[0])
367
Heinrich Schuchardtbc856172020-04-20 20:48:40 +0200368 except CalledProcessError as err:
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200369 pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300370 umount_fs(mount_dir)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900371 return
372 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300373 umount_fs(mount_dir)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900374 yield [fs_ubtype, fs_img, md5val]
375 finally:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900376 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200377 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900378
379#
380# Fixture for extended fs test
381#
Tom Rini1b91cee2021-01-28 14:39:56 -0500382@pytest.fixture()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900383def fs_obj_ext(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900384 """Set up a file system to be used in extended fs test.
385
386 Args:
387 request: Pytest request object.
388 u_boot_config: U-boot configuration.
389
390 Return:
391 A fixture for extended fs test, i.e. a triplet of file system type,
392 volume file name and a list of MD5 hashes.
393 """
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900394 fs_type = request.param
395 fs_img = ''
396
397 fs_ubtype = fstype_to_ubname(fs_type)
398 check_ubconfig(u_boot_config, fs_ubtype)
399
400 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
401
402 min_file = mount_dir + '/' + MIN_FILE
403 tmp_file = mount_dir + '/tmpfile'
404
405 try:
406
407 # 128MiB volume
408 fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200409 except CalledProcessError as err:
410 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
411 return
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900412
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200413 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900414 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200415 except CalledProcessError as err:
416 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200417 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300418 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200419
420 try:
421 # Mount the image so we can populate it.
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900422 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300423 except CalledProcessError as err:
424 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
425 call('rmdir %s' % mount_dir, shell=True)
426 call('rm -f %s' % fs_img, shell=True)
427 return
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900428
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300429 try:
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900430 # Create a test directory
431 check_call('mkdir %s/dir1' % mount_dir, shell=True)
432
433 # Create a small file and calculate md5
434 check_call('dd if=/dev/urandom of=%s bs=1K count=20'
435 % min_file, shell=True)
436 out = check_output(
437 'dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400438 % min_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900439 md5val = [ out.split()[0] ]
440
441 # Calculate md5sum of Test Case 4
442 check_call('dd if=%s of=%s bs=1K count=20'
443 % (min_file, tmp_file), shell=True)
444 check_call('dd if=%s of=%s bs=1K seek=5 count=20'
445 % (min_file, tmp_file), shell=True)
446 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400447 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900448 md5val.append(out.split()[0])
449
450 # Calculate md5sum of Test Case 5
451 check_call('dd if=%s of=%s bs=1K count=20'
452 % (min_file, tmp_file), shell=True)
453 check_call('dd if=%s of=%s bs=1K seek=5 count=5'
454 % (min_file, tmp_file), shell=True)
455 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400456 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900457 md5val.append(out.split()[0])
458
459 # Calculate md5sum of Test Case 7
460 check_call('dd if=%s of=%s bs=1K count=20'
461 % (min_file, tmp_file), shell=True)
462 check_call('dd if=%s of=%s bs=1K seek=20 count=20'
463 % (min_file, tmp_file), shell=True)
464 out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400465 % tmp_file, shell=True).decode()
AKASHI Takahirodde5d3f2018-09-11 15:59:20 +0900466 md5val.append(out.split()[0])
467
468 check_call('rm %s' % tmp_file, shell=True)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900469 except CalledProcessError:
470 pytest.skip('Setup failed for filesystem: ' + fs_type)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300471 umount_fs(mount_dir)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900472 return
473 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300474 umount_fs(mount_dir)
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900475 yield [fs_ubtype, fs_img, md5val]
476 finally:
AKASHI Takahiro615af9a2018-09-11 15:59:19 +0900477 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200478 call('rm -f %s' % fs_img, shell=True)
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900479
480#
481# Fixture for mkdir test
482#
Tom Rini1b91cee2021-01-28 14:39:56 -0500483@pytest.fixture()
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900484def fs_obj_mkdir(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900485 """Set up a file system to be used in mkdir test.
486
487 Args:
488 request: Pytest request object.
489 u_boot_config: U-boot configuration.
490
491 Return:
492 A fixture for mkdir test, i.e. a duplet of file system type and
493 volume file name.
494 """
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900495 fs_type = request.param
496 fs_img = ''
497
498 fs_ubtype = fstype_to_ubname(fs_type)
499 check_ubconfig(u_boot_config, fs_ubtype)
500
501 try:
502 # 128MiB volume
503 fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
504 except:
505 pytest.skip('Setup failed for filesystem: ' + fs_type)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200506 return
AKASHI Takahiro1e90c2c2018-09-11 15:59:21 +0900507 else:
508 yield [fs_ubtype, fs_img]
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200509 call('rm -f %s' % fs_img, shell=True)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900510
511#
512# Fixture for unlink test
513#
Tom Rini1b91cee2021-01-28 14:39:56 -0500514@pytest.fixture()
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900515def fs_obj_unlink(request, u_boot_config):
Akashi Takahirobcdd1f22018-09-27 16:07:23 +0900516 """Set up a file system to be used in unlink test.
517
518 Args:
519 request: Pytest request object.
520 u_boot_config: U-boot configuration.
521
522 Return:
523 A fixture for unlink test, i.e. a duplet of file system type and
524 volume file name.
525 """
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900526 fs_type = request.param
527 fs_img = ''
528
529 fs_ubtype = fstype_to_ubname(fs_type)
530 check_ubconfig(u_boot_config, fs_ubtype)
531
532 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
533
534 try:
535
536 # 128MiB volume
537 fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200538 except CalledProcessError as err:
539 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
540 return
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900541
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200542 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900543 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200544 except CalledProcessError as err:
545 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200546 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300547 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200548
549 try:
550 # Mount the image so we can populate it.
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900551 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300552 except CalledProcessError as err:
553 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
554 call('rmdir %s' % mount_dir, shell=True)
555 call('rm -f %s' % fs_img, shell=True)
556 return
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900557
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300558 try:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900559 # Test Case 1 & 3
560 check_call('mkdir %s/dir1' % mount_dir, shell=True)
561 check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
562 % mount_dir, shell=True)
563 check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
564 % mount_dir, shell=True)
565
566 # Test Case 2
567 check_call('mkdir %s/dir2' % mount_dir, shell=True)
Tom Rini7f24c192019-10-24 11:59:20 -0400568 for i in range(0, 20):
569 check_call('mkdir %s/dir2/0123456789abcdef%02x'
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900570 % (mount_dir, i), shell=True)
571
572 # Test Case 4
573 check_call('mkdir %s/dir4' % mount_dir, shell=True)
574
575 # Test Case 5, 6 & 7
576 check_call('mkdir %s/dir5' % mount_dir, shell=True)
577 check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
578 % mount_dir, shell=True)
579
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900580 except CalledProcessError:
581 pytest.skip('Setup failed for filesystem: ' + fs_type)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300582 umount_fs(mount_dir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900583 return
584 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300585 umount_fs(mount_dir)
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900586 yield [fs_ubtype, fs_img]
587 finally:
Akashi, Takahirod49e7992018-09-11 16:06:03 +0900588 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200589 call('rm -f %s' % fs_img, shell=True)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100590
591#
592# Fixture for symlink fs test
593#
Tom Rini1b91cee2021-01-28 14:39:56 -0500594@pytest.fixture()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100595def fs_obj_symlink(request, u_boot_config):
596 """Set up a file system to be used in symlink fs test.
597
598 Args:
599 request: Pytest request object.
600 u_boot_config: U-boot configuration.
601
602 Return:
603 A fixture for basic fs test, i.e. a triplet of file system type,
604 volume file name and a list of MD5 hashes.
605 """
606 fs_type = request.param
607 fs_img = ''
608
609 fs_ubtype = fstype_to_ubname(fs_type)
610 check_ubconfig(u_boot_config, fs_ubtype)
611
612 mount_dir = u_boot_config.persistent_data_dir + '/mnt'
613
614 small_file = mount_dir + '/' + SMALL_FILE
615 medium_file = mount_dir + '/' + MEDIUM_FILE
616
617 try:
618
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200619 # 1GiB volume
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100620 fs_img = mk_fs(u_boot_config, fs_type, 0x40000000, '1GB')
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200621 except CalledProcessError as err:
622 pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
623 return
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100624
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200625 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100626 check_call('mkdir -p %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200627 except CalledProcessError as err:
628 pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200629 call('rm -f %s' % fs_img, shell=True)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300630 return
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200631
632 try:
633 # Mount the image so we can populate it.
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100634 mount_fs(fs_type, fs_img, mount_dir)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300635 except CalledProcessError as err:
636 pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
637 call('rmdir %s' % mount_dir, shell=True)
638 call('rm -f %s' % fs_img, shell=True)
639 return
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100640
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300641 try:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100642 # Create a subdirectory.
643 check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
644
645 # Create a small file in this image.
646 check_call('dd if=/dev/urandom of=%s bs=1M count=1'
647 % small_file, shell=True)
648
649 # Create a medium file in this image.
650 check_call('dd if=/dev/urandom of=%s bs=10M count=1'
651 % medium_file, shell=True)
652
653 # Generate the md5sums of reads that we will test against small file
654 out = check_output(
655 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400656 % small_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100657 md5val = [out.split()[0]]
658 out = check_output(
659 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
Tom Rini784e27d2019-10-24 11:59:24 -0400660 % medium_file, shell=True).decode()
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100661 md5val.extend([out.split()[0]])
662
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100663 except CalledProcessError:
664 pytest.skip('Setup failed for filesystem: ' + fs_type)
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300665 umount_fs(mount_dir)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100666 return
667 else:
Alper Nebi Yasak46132c22021-05-20 22:09:46 +0300668 umount_fs(mount_dir)
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100669 yield [fs_ubtype, fs_img, md5val]
670 finally:
Jean-Jacques Hiblot8aea8a62019-02-13 12:15:27 +0100671 call('rmdir %s' % mount_dir, shell=True)
Andy Shevchenkoe70ed8c2021-02-11 16:40:12 +0200672 call('rm -f %s' % fs_img, shell=True)