conftest.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. # SPDX-License-Identifier: GPL-2.0+
  2. # Copyright (c) 2018, Linaro Limited
  3. # Author: Takahiro Akashi <takahiro.akashi@linaro.org>
  4. import os
  5. import os.path
  6. import pytest
  7. import re
  8. from subprocess import call, check_call, check_output, CalledProcessError
  9. from fstest_defs import *
  10. import u_boot_utils as util
  11. supported_fs_basic = ['fat16', 'fat32', 'ext4']
  12. supported_fs_ext = ['fat16', 'fat32']
  13. supported_fs_mkdir = ['fat16', 'fat32']
  14. supported_fs_unlink = ['fat16', 'fat32']
  15. supported_fs_symlink = ['ext4']
  16. #
  17. # Filesystem test specific setup
  18. #
  19. def pytest_addoption(parser):
  20. """Enable --fs-type option.
  21. See pytest_configure() about how it works.
  22. Args:
  23. parser: Pytest command-line parser.
  24. Returns:
  25. Nothing.
  26. """
  27. parser.addoption('--fs-type', action='append', default=None,
  28. help='Targeting Filesystem Types')
  29. def pytest_configure(config):
  30. """Restrict a file system(s) to be tested.
  31. A file system explicitly named with --fs-type option is selected
  32. if it belongs to a default supported_fs_xxx list.
  33. Multiple options can be specified.
  34. Args:
  35. config: Pytest configuration.
  36. Returns:
  37. Nothing.
  38. """
  39. global supported_fs_basic
  40. global supported_fs_ext
  41. global supported_fs_mkdir
  42. global supported_fs_unlink
  43. global supported_fs_symlink
  44. def intersect(listA, listB):
  45. return [x for x in listA if x in listB]
  46. supported_fs = config.getoption('fs_type')
  47. if supported_fs:
  48. print('*** FS TYPE modified: %s' % supported_fs)
  49. supported_fs_basic = intersect(supported_fs, supported_fs_basic)
  50. supported_fs_ext = intersect(supported_fs, supported_fs_ext)
  51. supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir)
  52. supported_fs_unlink = intersect(supported_fs, supported_fs_unlink)
  53. supported_fs_symlink = intersect(supported_fs, supported_fs_symlink)
  54. def pytest_generate_tests(metafunc):
  55. """Parametrize fixtures, fs_obj_xxx
  56. Each fixture will be parametrized with a corresponding support_fs_xxx
  57. list.
  58. Args:
  59. metafunc: Pytest test function.
  60. Returns:
  61. Nothing.
  62. """
  63. if 'fs_obj_basic' in metafunc.fixturenames:
  64. metafunc.parametrize('fs_obj_basic', supported_fs_basic,
  65. indirect=True, scope='module')
  66. if 'fs_obj_ext' in metafunc.fixturenames:
  67. metafunc.parametrize('fs_obj_ext', supported_fs_ext,
  68. indirect=True, scope='module')
  69. if 'fs_obj_mkdir' in metafunc.fixturenames:
  70. metafunc.parametrize('fs_obj_mkdir', supported_fs_mkdir,
  71. indirect=True, scope='module')
  72. if 'fs_obj_unlink' in metafunc.fixturenames:
  73. metafunc.parametrize('fs_obj_unlink', supported_fs_unlink,
  74. indirect=True, scope='module')
  75. if 'fs_obj_symlink' in metafunc.fixturenames:
  76. metafunc.parametrize('fs_obj_symlink', supported_fs_symlink,
  77. indirect=True, scope='module')
  78. #
  79. # Helper functions
  80. #
  81. def fstype_to_ubname(fs_type):
  82. """Convert a file system type to an U-boot specific string
  83. A generated string can be used as part of file system related commands
  84. or a config name in u-boot. Currently fat16 and fat32 are handled
  85. specifically.
  86. Args:
  87. fs_type: File system type.
  88. Return:
  89. A corresponding string for file system type.
  90. """
  91. if re.match('fat', fs_type):
  92. return 'fat'
  93. else:
  94. return fs_type
  95. def check_ubconfig(config, fs_type):
  96. """Check whether a file system is enabled in u-boot configuration.
  97. This function is assumed to be called in a fixture function so that
  98. the whole test cases will be skipped if a given file system is not
  99. enabled.
  100. Args:
  101. fs_type: File system type.
  102. Return:
  103. Nothing.
  104. """
  105. if not config.buildconfig.get('config_cmd_%s' % fs_type, None):
  106. pytest.skip('.config feature "CMD_%s" not enabled' % fs_type.upper())
  107. if not config.buildconfig.get('config_%s_write' % fs_type, None):
  108. pytest.skip('.config feature "%s_WRITE" not enabled'
  109. % fs_type.upper())
  110. def mk_fs(config, fs_type, size, id):
  111. """Create a file system volume.
  112. Args:
  113. fs_type: File system type.
  114. size: Size of file system in MiB.
  115. id: Prefix string of volume's file name.
  116. Return:
  117. Nothing.
  118. """
  119. fs_img = '%s.%s.img' % (id, fs_type)
  120. fs_img = config.persistent_data_dir + '/' + fs_img
  121. if fs_type == 'fat16':
  122. mkfs_opt = '-F 16'
  123. elif fs_type == 'fat32':
  124. mkfs_opt = '-F 32'
  125. else:
  126. mkfs_opt = ''
  127. if re.match('fat', fs_type):
  128. fs_lnxtype = 'vfat'
  129. else:
  130. fs_lnxtype = fs_type
  131. count = (size + 1048576 - 1) / 1048576
  132. # Some distributions do not add /sbin to the default PATH, where mkfs lives
  133. if '/sbin' not in os.environ["PATH"].split(os.pathsep):
  134. os.environ["PATH"] += os.pathsep + '/sbin'
  135. try:
  136. check_call('rm -f %s' % fs_img, shell=True)
  137. check_call('dd if=/dev/zero of=%s bs=1M count=%d'
  138. % (fs_img, count), shell=True)
  139. check_call('mkfs.%s %s %s'
  140. % (fs_lnxtype, mkfs_opt, fs_img), shell=True)
  141. if fs_type == 'ext4':
  142. sb_content = check_output('tune2fs -l %s' % fs_img, shell=True).decode()
  143. if 'metadata_csum' in sb_content:
  144. check_call('tune2fs -O ^metadata_csum %s' % fs_img, shell=True)
  145. return fs_img
  146. except CalledProcessError:
  147. call('rm -f %s' % fs_img, shell=True)
  148. raise
  149. # from test/py/conftest.py
  150. def tool_is_in_path(tool):
  151. """Check whether a given command is available on host.
  152. Args:
  153. tool: Command name.
  154. Return:
  155. True if available, False if not.
  156. """
  157. for path in os.environ['PATH'].split(os.pathsep):
  158. fn = os.path.join(path, tool)
  159. if os.path.isfile(fn) and os.access(fn, os.X_OK):
  160. return True
  161. return False
  162. fuse_mounted = False
  163. def mount_fs(fs_type, device, mount_point):
  164. """Mount a volume.
  165. Args:
  166. fs_type: File system type.
  167. device: Volume's file name.
  168. mount_point: Mount point.
  169. Return:
  170. Nothing.
  171. """
  172. global fuse_mounted
  173. try:
  174. check_call('guestmount --pid-file guestmount.pid -a %s -m /dev/sda %s'
  175. % (device, mount_point), shell=True)
  176. fuse_mounted = True
  177. return
  178. except CalledProcessError:
  179. fuse_mounted = False
  180. mount_opt = 'loop,rw'
  181. if re.match('fat', fs_type):
  182. mount_opt += ',umask=0000'
  183. check_call('sudo mount -o %s %s %s'
  184. % (mount_opt, device, mount_point), shell=True)
  185. # may not be effective for some file systems
  186. check_call('sudo chmod a+rw %s' % mount_point, shell=True)
  187. def umount_fs(mount_point):
  188. """Unmount a volume.
  189. Args:
  190. mount_point: Mount point.
  191. Return:
  192. Nothing.
  193. """
  194. if fuse_mounted:
  195. call('sync')
  196. call('guestunmount %s' % mount_point, shell=True)
  197. try:
  198. with open("guestmount.pid", "r") as pidfile:
  199. pid = int(pidfile.read())
  200. util.waitpid(pid, kill=True)
  201. os.remove("guestmount.pid")
  202. except FileNotFoundError:
  203. pass
  204. else:
  205. call('sudo umount %s' % mount_point, shell=True)
  206. #
  207. # Fixture for basic fs test
  208. # derived from test/fs/fs-test.sh
  209. #
  210. @pytest.fixture()
  211. def fs_obj_basic(request, u_boot_config):
  212. """Set up a file system to be used in basic fs test.
  213. Args:
  214. request: Pytest request object.
  215. u_boot_config: U-boot configuration.
  216. Return:
  217. A fixture for basic fs test, i.e. a triplet of file system type,
  218. volume file name and a list of MD5 hashes.
  219. """
  220. fs_type = request.param
  221. fs_img = ''
  222. fs_ubtype = fstype_to_ubname(fs_type)
  223. check_ubconfig(u_boot_config, fs_ubtype)
  224. mount_dir = u_boot_config.persistent_data_dir + '/mnt'
  225. small_file = mount_dir + '/' + SMALL_FILE
  226. big_file = mount_dir + '/' + BIG_FILE
  227. try:
  228. # 3GiB volume
  229. fs_img = mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB')
  230. except CalledProcessError as err:
  231. pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
  232. return
  233. try:
  234. check_call('mkdir -p %s' % mount_dir, shell=True)
  235. except CalledProcessError as err:
  236. pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  237. call('rm -f %s' % fs_img, shell=True)
  238. return
  239. try:
  240. # Mount the image so we can populate it.
  241. mount_fs(fs_type, fs_img, mount_dir)
  242. except CalledProcessError as err:
  243. pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  244. call('rmdir %s' % mount_dir, shell=True)
  245. call('rm -f %s' % fs_img, shell=True)
  246. return
  247. try:
  248. # Create a subdirectory.
  249. check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
  250. # Create big file in this image.
  251. # Note that we work only on the start 1MB, couple MBs in the 2GB range
  252. # and the last 1 MB of the huge 2.5GB file.
  253. # So, just put random values only in those areas.
  254. check_call('dd if=/dev/urandom of=%s bs=1M count=1'
  255. % big_file, shell=True)
  256. check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
  257. % big_file, shell=True)
  258. check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
  259. % big_file, shell=True)
  260. # Create a small file in this image.
  261. check_call('dd if=/dev/urandom of=%s bs=1M count=1'
  262. % small_file, shell=True)
  263. # Delete the small file copies which possibly are written as part of a
  264. # previous test.
  265. # check_call('rm -f "%s.w"' % MB1, shell=True)
  266. # check_call('rm -f "%s.w2"' % MB1, shell=True)
  267. # Generate the md5sums of reads that we will test against small file
  268. out = check_output(
  269. 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
  270. % small_file, shell=True).decode()
  271. md5val = [ out.split()[0] ]
  272. # Generate the md5sums of reads that we will test against big file
  273. # One from beginning of file.
  274. out = check_output(
  275. 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
  276. % big_file, shell=True).decode()
  277. md5val.append(out.split()[0])
  278. # One from end of file.
  279. out = check_output(
  280. 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
  281. % big_file, shell=True).decode()
  282. md5val.append(out.split()[0])
  283. # One from the last 1MB chunk of 2GB
  284. out = check_output(
  285. 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
  286. % big_file, shell=True).decode()
  287. md5val.append(out.split()[0])
  288. # One from the start 1MB chunk from 2GB
  289. out = check_output(
  290. 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
  291. % big_file, shell=True).decode()
  292. md5val.append(out.split()[0])
  293. # One 1MB chunk crossing the 2GB boundary
  294. out = check_output(
  295. 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
  296. % big_file, shell=True).decode()
  297. md5val.append(out.split()[0])
  298. except CalledProcessError as err:
  299. pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
  300. umount_fs(mount_dir)
  301. return
  302. else:
  303. umount_fs(mount_dir)
  304. yield [fs_ubtype, fs_img, md5val]
  305. finally:
  306. call('rmdir %s' % mount_dir, shell=True)
  307. call('rm -f %s' % fs_img, shell=True)
  308. #
  309. # Fixture for extended fs test
  310. #
  311. @pytest.fixture()
  312. def fs_obj_ext(request, u_boot_config):
  313. """Set up a file system to be used in extended fs test.
  314. Args:
  315. request: Pytest request object.
  316. u_boot_config: U-boot configuration.
  317. Return:
  318. A fixture for extended fs test, i.e. a triplet of file system type,
  319. volume file name and a list of MD5 hashes.
  320. """
  321. fs_type = request.param
  322. fs_img = ''
  323. fs_ubtype = fstype_to_ubname(fs_type)
  324. check_ubconfig(u_boot_config, fs_ubtype)
  325. mount_dir = u_boot_config.persistent_data_dir + '/mnt'
  326. min_file = mount_dir + '/' + MIN_FILE
  327. tmp_file = mount_dir + '/tmpfile'
  328. try:
  329. # 128MiB volume
  330. fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
  331. except CalledProcessError as err:
  332. pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
  333. return
  334. try:
  335. check_call('mkdir -p %s' % mount_dir, shell=True)
  336. except CalledProcessError as err:
  337. pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  338. call('rm -f %s' % fs_img, shell=True)
  339. return
  340. try:
  341. # Mount the image so we can populate it.
  342. mount_fs(fs_type, fs_img, mount_dir)
  343. except CalledProcessError as err:
  344. pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  345. call('rmdir %s' % mount_dir, shell=True)
  346. call('rm -f %s' % fs_img, shell=True)
  347. return
  348. try:
  349. # Create a test directory
  350. check_call('mkdir %s/dir1' % mount_dir, shell=True)
  351. # Create a small file and calculate md5
  352. check_call('dd if=/dev/urandom of=%s bs=1K count=20'
  353. % min_file, shell=True)
  354. out = check_output(
  355. 'dd if=%s bs=1K 2> /dev/null | md5sum'
  356. % min_file, shell=True).decode()
  357. md5val = [ out.split()[0] ]
  358. # Calculate md5sum of Test Case 4
  359. check_call('dd if=%s of=%s bs=1K count=20'
  360. % (min_file, tmp_file), shell=True)
  361. check_call('dd if=%s of=%s bs=1K seek=5 count=20'
  362. % (min_file, tmp_file), shell=True)
  363. out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
  364. % tmp_file, shell=True).decode()
  365. md5val.append(out.split()[0])
  366. # Calculate md5sum of Test Case 5
  367. check_call('dd if=%s of=%s bs=1K count=20'
  368. % (min_file, tmp_file), shell=True)
  369. check_call('dd if=%s of=%s bs=1K seek=5 count=5'
  370. % (min_file, tmp_file), shell=True)
  371. out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
  372. % tmp_file, shell=True).decode()
  373. md5val.append(out.split()[0])
  374. # Calculate md5sum of Test Case 7
  375. check_call('dd if=%s of=%s bs=1K count=20'
  376. % (min_file, tmp_file), shell=True)
  377. check_call('dd if=%s of=%s bs=1K seek=20 count=20'
  378. % (min_file, tmp_file), shell=True)
  379. out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum'
  380. % tmp_file, shell=True).decode()
  381. md5val.append(out.split()[0])
  382. check_call('rm %s' % tmp_file, shell=True)
  383. except CalledProcessError:
  384. pytest.skip('Setup failed for filesystem: ' + fs_type)
  385. umount_fs(mount_dir)
  386. return
  387. else:
  388. umount_fs(mount_dir)
  389. yield [fs_ubtype, fs_img, md5val]
  390. finally:
  391. call('rmdir %s' % mount_dir, shell=True)
  392. call('rm -f %s' % fs_img, shell=True)
  393. #
  394. # Fixture for mkdir test
  395. #
  396. @pytest.fixture()
  397. def fs_obj_mkdir(request, u_boot_config):
  398. """Set up a file system to be used in mkdir test.
  399. Args:
  400. request: Pytest request object.
  401. u_boot_config: U-boot configuration.
  402. Return:
  403. A fixture for mkdir test, i.e. a duplet of file system type and
  404. volume file name.
  405. """
  406. fs_type = request.param
  407. fs_img = ''
  408. fs_ubtype = fstype_to_ubname(fs_type)
  409. check_ubconfig(u_boot_config, fs_ubtype)
  410. try:
  411. # 128MiB volume
  412. fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
  413. except:
  414. pytest.skip('Setup failed for filesystem: ' + fs_type)
  415. return
  416. else:
  417. yield [fs_ubtype, fs_img]
  418. call('rm -f %s' % fs_img, shell=True)
  419. #
  420. # Fixture for unlink test
  421. #
  422. @pytest.fixture()
  423. def fs_obj_unlink(request, u_boot_config):
  424. """Set up a file system to be used in unlink test.
  425. Args:
  426. request: Pytest request object.
  427. u_boot_config: U-boot configuration.
  428. Return:
  429. A fixture for unlink test, i.e. a duplet of file system type and
  430. volume file name.
  431. """
  432. fs_type = request.param
  433. fs_img = ''
  434. fs_ubtype = fstype_to_ubname(fs_type)
  435. check_ubconfig(u_boot_config, fs_ubtype)
  436. mount_dir = u_boot_config.persistent_data_dir + '/mnt'
  437. try:
  438. # 128MiB volume
  439. fs_img = mk_fs(u_boot_config, fs_type, 0x8000000, '128MB')
  440. except CalledProcessError as err:
  441. pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
  442. return
  443. try:
  444. check_call('mkdir -p %s' % mount_dir, shell=True)
  445. except CalledProcessError as err:
  446. pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  447. call('rm -f %s' % fs_img, shell=True)
  448. return
  449. try:
  450. # Mount the image so we can populate it.
  451. mount_fs(fs_type, fs_img, mount_dir)
  452. except CalledProcessError as err:
  453. pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  454. call('rmdir %s' % mount_dir, shell=True)
  455. call('rm -f %s' % fs_img, shell=True)
  456. return
  457. try:
  458. # Test Case 1 & 3
  459. check_call('mkdir %s/dir1' % mount_dir, shell=True)
  460. check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
  461. % mount_dir, shell=True)
  462. check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
  463. % mount_dir, shell=True)
  464. # Test Case 2
  465. check_call('mkdir %s/dir2' % mount_dir, shell=True)
  466. for i in range(0, 20):
  467. check_call('mkdir %s/dir2/0123456789abcdef%02x'
  468. % (mount_dir, i), shell=True)
  469. # Test Case 4
  470. check_call('mkdir %s/dir4' % mount_dir, shell=True)
  471. # Test Case 5, 6 & 7
  472. check_call('mkdir %s/dir5' % mount_dir, shell=True)
  473. check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
  474. % mount_dir, shell=True)
  475. except CalledProcessError:
  476. pytest.skip('Setup failed for filesystem: ' + fs_type)
  477. umount_fs(mount_dir)
  478. return
  479. else:
  480. umount_fs(mount_dir)
  481. yield [fs_ubtype, fs_img]
  482. finally:
  483. call('rmdir %s' % mount_dir, shell=True)
  484. call('rm -f %s' % fs_img, shell=True)
  485. #
  486. # Fixture for symlink fs test
  487. #
  488. @pytest.fixture()
  489. def fs_obj_symlink(request, u_boot_config):
  490. """Set up a file system to be used in symlink fs test.
  491. Args:
  492. request: Pytest request object.
  493. u_boot_config: U-boot configuration.
  494. Return:
  495. A fixture for basic fs test, i.e. a triplet of file system type,
  496. volume file name and a list of MD5 hashes.
  497. """
  498. fs_type = request.param
  499. fs_img = ''
  500. fs_ubtype = fstype_to_ubname(fs_type)
  501. check_ubconfig(u_boot_config, fs_ubtype)
  502. mount_dir = u_boot_config.persistent_data_dir + '/mnt'
  503. small_file = mount_dir + '/' + SMALL_FILE
  504. medium_file = mount_dir + '/' + MEDIUM_FILE
  505. try:
  506. # 1GiB volume
  507. fs_img = mk_fs(u_boot_config, fs_type, 0x40000000, '1GB')
  508. except CalledProcessError as err:
  509. pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
  510. return
  511. try:
  512. check_call('mkdir -p %s' % mount_dir, shell=True)
  513. except CalledProcessError as err:
  514. pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  515. call('rm -f %s' % fs_img, shell=True)
  516. return
  517. try:
  518. # Mount the image so we can populate it.
  519. mount_fs(fs_type, fs_img, mount_dir)
  520. except CalledProcessError as err:
  521. pytest.skip('Mounting to folder failed for filesystem: ' + fs_type + '. {}'.format(err))
  522. call('rmdir %s' % mount_dir, shell=True)
  523. call('rm -f %s' % fs_img, shell=True)
  524. return
  525. try:
  526. # Create a subdirectory.
  527. check_call('mkdir %s/SUBDIR' % mount_dir, shell=True)
  528. # Create a small file in this image.
  529. check_call('dd if=/dev/urandom of=%s bs=1M count=1'
  530. % small_file, shell=True)
  531. # Create a medium file in this image.
  532. check_call('dd if=/dev/urandom of=%s bs=10M count=1'
  533. % medium_file, shell=True)
  534. # Generate the md5sums of reads that we will test against small file
  535. out = check_output(
  536. 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
  537. % small_file, shell=True).decode()
  538. md5val = [out.split()[0]]
  539. out = check_output(
  540. 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum'
  541. % medium_file, shell=True).decode()
  542. md5val.extend([out.split()[0]])
  543. except CalledProcessError:
  544. pytest.skip('Setup failed for filesystem: ' + fs_type)
  545. umount_fs(mount_dir)
  546. return
  547. else:
  548. umount_fs(mount_dir)
  549. yield [fs_ubtype, fs_img, md5val]
  550. finally:
  551. call('rmdir %s' % mount_dir, shell=True)
  552. call('rm -f %s' % fs_img, shell=True)