test_fatfsparse.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #!/usr/bin/env python
  2. # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. # SPDX-License-Identifier: Apache-2.0
  4. import os
  5. import shutil
  6. import sys
  7. import unittest
  8. from subprocess import STDOUT, run
  9. from test_utils import compare_folders, fill_sector, generate_local_folder_structure, generate_test_dir_2
  10. sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
  11. import fatfsgen # noqa E402 # pylint: disable=C0413
  12. class FatFSGen(unittest.TestCase):
  13. def setUp(self) -> None:
  14. os.makedirs('output_data')
  15. generate_test_dir_2()
  16. def tearDown(self) -> None:
  17. shutil.rmtree('output_data', ignore_errors=True)
  18. shutil.rmtree('Espressif', ignore_errors=True)
  19. shutil.rmtree('testf', ignore_errors=True)
  20. shutil.rmtree('testf_wl', ignore_errors=True)
  21. if os.path.exists('fatfs_image.img'):
  22. os.remove('fatfs_image.img')
  23. @staticmethod
  24. def test_gen_parse() -> None:
  25. run([
  26. 'python',
  27. f'{os.path.join(os.path.dirname(__file__), "..", "fatfsgen.py")}',
  28. 'output_data/tst_str'
  29. ], stderr=STDOUT)
  30. run(['python', '../fatfsgen.py', 'output_data/tst_str'], stderr=STDOUT)
  31. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  32. assert set(os.listdir('Espressif')) == {'TEST', 'TESTFILE'}
  33. with open('Espressif/TESTFILE', 'rb') as in_:
  34. assert in_.read() == b'ahoj\n'
  35. assert set(os.listdir('Espressif/TEST')) == {'TEST', 'TESTFIL2'}
  36. with open('Espressif/TEST/TESTFIL2', 'rb') as in_:
  37. assert in_.read() == b'thisistest\n'
  38. assert set(os.listdir('Espressif/TEST/TEST')) == {'LASTFILE.TXT'}
  39. with open('Espressif/TEST/TEST/LASTFILE.TXT', 'rb') as in_:
  40. assert in_.read() == b'deeptest\n'
  41. @staticmethod
  42. def test_file_chaining() -> None:
  43. fatfs = fatfsgen.FATFS()
  44. fatfs.create_file('WRITEF', extension='TXT')
  45. fatfs.write_content(path_from_root=['WRITEF.TXT'], content=4096 * b'a' + b'a')
  46. fatfs.write_filesystem('fatfs_image.img')
  47. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  48. with open('Espressif/WRITEF.TXT', 'rb') as in_:
  49. assert in_.read() == 4097 * b'a'
  50. @staticmethod
  51. def test_full_two_sectors_folder() -> None:
  52. fatfs = fatfsgen.FATFS(size=2 * 1024 * 1024)
  53. fatfs.create_directory('TESTFOLD')
  54. for i in range((2 * 4096) // 32):
  55. fatfs.create_file(f'A{str(i).upper()}', path_from_root=['TESTFOLD'])
  56. fatfs.write_content(path_from_root=['TESTFOLD', 'A253'], content=b'later')
  57. fatfs.write_content(path_from_root=['TESTFOLD', 'A255'], content=b'last')
  58. fatfs.write_filesystem('fatfs_image.img')
  59. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  60. assert set(os.listdir('Espressif')) == {'TESTFOLD'}
  61. assert set(os.listdir('Espressif/TESTFOLD')) == {f'A{str(i).upper()}' for i in range(256)}
  62. with open('Espressif/TESTFOLD/A253', 'rb') as in_:
  63. assert in_.read() == b'later'
  64. with open('Espressif/TESTFOLD/A255', 'rb') as in_:
  65. assert in_.read() == b'last'
  66. @staticmethod
  67. def test_empty_fat16() -> None:
  68. fatfs = fatfsgen.FATFS(size=17 * 1024 * 1024)
  69. fatfs.write_filesystem('fatfs_image.img')
  70. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  71. @staticmethod
  72. def test_chaining_fat16() -> None:
  73. fatfs = fatfsgen.FATFS(size=17 * 1024 * 1024)
  74. fatfs.create_file('WRITEF', extension='TXT')
  75. fatfs.write_content(path_from_root=['WRITEF.TXT'], content=4096 * b'a' + b'a')
  76. fatfs.write_filesystem('fatfs_image.img')
  77. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  78. with open('Espressif/WRITEF.TXT', 'rb') as in_:
  79. assert in_.read() == 4097 * b'a'
  80. @staticmethod
  81. def test_full_sector_folder_fat16() -> None:
  82. fatfs = fatfsgen.FATFS(size=17 * 1024 * 1024)
  83. fatfs.create_directory('TESTFOLD')
  84. fill_sector(fatfs)
  85. fatfs.write_content(path_from_root=['TESTFOLD', 'A0'], content=b'first')
  86. fatfs.write_content(path_from_root=['TESTFOLD', 'A126'], content=b'later')
  87. fatfs.write_filesystem('fatfs_image.img')
  88. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  89. assert set(os.listdir('Espressif')) == {'TESTFOLD'}
  90. assert set(os.listdir('Espressif/TESTFOLD')) == {f'A{str(i).upper()}' for i in range(128)}
  91. with open('Espressif/TESTFOLD/A0', 'rb') as in_:
  92. assert in_.read() == b'first'
  93. with open('Espressif/TESTFOLD/A126', 'rb') as in_:
  94. assert in_.read() == b'later'
  95. @staticmethod
  96. def file_(x: str, content_: str = 'hey this is a test') -> dict:
  97. return {
  98. 'type': 'file',
  99. 'name': x,
  100. 'content': content_
  101. }
  102. def test_e2e_file(self) -> None:
  103. struct_: dict = {
  104. 'type': 'folder',
  105. 'name': 'testf',
  106. 'content': [self.file_('NEWF')]
  107. }
  108. generate_local_folder_structure(struct_, path_='.')
  109. run([
  110. 'python',
  111. f'{os.path.join(os.path.dirname(__file__), "..", "fatfsgen.py")}',
  112. 'testf'
  113. ], stderr=STDOUT)
  114. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  115. assert compare_folders('testf', 'Espressif')
  116. shutil.rmtree('Espressif', ignore_errors=True)
  117. run([
  118. 'python',
  119. f'{os.path.join(os.path.dirname(__file__), "..", "wl_fatfsgen.py")}',
  120. 'testf'
  121. ], stderr=STDOUT)
  122. run(['python', '../fatfsparse.py', '--wear-leveling', 'fatfs_image.img'], stderr=STDOUT)
  123. assert compare_folders('testf', 'Espressif')
  124. def test_e2e_deeper(self) -> None:
  125. folder_ = {
  126. 'type': 'folder',
  127. 'name': 'XYZ',
  128. 'content': [
  129. self.file_('NEWFLE'),
  130. self.file_('NEW.TXT'),
  131. self.file_('NEWE.TXT'),
  132. self.file_('NEW4.TXT'),
  133. self.file_('NEW5.TXT'),
  134. ]
  135. }
  136. struct_: dict = {
  137. 'type': 'folder',
  138. 'name': 'testf',
  139. 'content': [
  140. self.file_('MY_NEW'),
  141. folder_
  142. ]
  143. }
  144. generate_local_folder_structure(struct_, path_='.')
  145. run([
  146. 'python',
  147. f'{os.path.join(os.path.dirname(__file__), "..", "fatfsgen.py")}',
  148. 'testf'
  149. ], stderr=STDOUT)
  150. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  151. assert compare_folders('testf', 'Espressif')
  152. shutil.rmtree('Espressif', ignore_errors=True)
  153. run([
  154. 'python',
  155. f'{os.path.join(os.path.dirname(__file__), "..", "wl_fatfsgen.py")}',
  156. 'testf'
  157. ], stderr=STDOUT)
  158. run(['python', '../fatfsparse.py', '--wear-leveling', 'fatfs_image.img'], stderr=STDOUT)
  159. assert compare_folders('testf', 'Espressif')
  160. def test_e2e_deeper_large(self) -> None:
  161. folder_ = {
  162. 'type': 'folder',
  163. 'name': 'XYZ',
  164. 'content': [
  165. self.file_('NEWFLE', content_=4097 * 'a'),
  166. self.file_('NEW.TXT', content_=2 * 4097 * 'a'),
  167. self.file_('NEWE.TXT'),
  168. self.file_('NEW4.TXT'),
  169. self.file_('NEW5.TXT'),
  170. ]
  171. }
  172. folder2_ = {
  173. 'type': 'folder',
  174. 'name': 'XYZ3',
  175. 'content': [
  176. self.file_('NEWFLE', content_=4097 * 'a'),
  177. self.file_('NEW.TXT', content_=2 * 4097 * 'a'),
  178. self.file_('NEWE.TXT'),
  179. self.file_('NEW4.TXT'),
  180. self.file_('NEW5.TXT'),
  181. ]
  182. }
  183. folder3_ = {
  184. 'type': 'folder',
  185. 'name': 'XYZ2',
  186. 'content': [self.file_(f'A{i}') for i in range(50)]
  187. }
  188. struct_: dict = {
  189. 'type': 'folder',
  190. 'name': 'testf',
  191. 'content': [
  192. self.file_('MY_NEW'),
  193. folder_,
  194. folder2_,
  195. folder3_
  196. ]
  197. }
  198. generate_local_folder_structure(struct_, path_='.')
  199. run([
  200. 'python',
  201. f'{os.path.join(os.path.dirname(__file__), "..", "fatfsgen.py")}',
  202. 'testf'
  203. ], stderr=STDOUT)
  204. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  205. assert compare_folders('testf', 'Espressif')
  206. shutil.rmtree('Espressif', ignore_errors=True)
  207. run([
  208. 'python',
  209. f'{os.path.join(os.path.dirname(__file__), "..", "wl_fatfsgen.py")}',
  210. 'testf'
  211. ], stderr=STDOUT)
  212. run(['python', '../fatfsparse.py', '--wear-leveling', 'fatfs_image.img'], stderr=STDOUT)
  213. assert compare_folders('testf', 'Espressif')
  214. def test_e2e_very_deep(self) -> None:
  215. folder_ = {
  216. 'type': 'folder',
  217. 'name': 'XYZ',
  218. 'content': [
  219. self.file_('NEWFLE', content_=4097 * 'a'),
  220. self.file_('NEW.TXT', content_=2 * 4097 * 'a'),
  221. self.file_('NEWE.TXT'),
  222. self.file_('NEW4.TXT'),
  223. self.file_('NEW5.TXT'),
  224. ]
  225. }
  226. folder2_ = {
  227. 'type': 'folder',
  228. 'name': 'XYZ3',
  229. 'content': [
  230. self.file_('NEWFLE', content_=4097 * 'a'),
  231. self.file_('NEW.TXT', content_=2 * 4097 * 'a'),
  232. self.file_('NEWE.TXT'),
  233. self.file_('NEW4.TXT'),
  234. self.file_('NEW5.TXT'),
  235. folder_,
  236. ]
  237. }
  238. folder3_ = {
  239. 'type': 'folder',
  240. 'name': 'XYZ2',
  241. 'content': [self.file_(f'A{i}') for i in range(50)] + [folder2_]
  242. }
  243. struct_: dict = {
  244. 'type': 'folder',
  245. 'name': 'testf',
  246. 'content': [
  247. self.file_('MY_NEW'),
  248. folder_,
  249. folder2_,
  250. folder3_
  251. ]
  252. }
  253. generate_local_folder_structure(struct_, path_='.')
  254. run([
  255. 'python',
  256. f'{os.path.join(os.path.dirname(__file__), "..", "fatfsgen.py")}',
  257. 'testf'
  258. ], stderr=STDOUT)
  259. run(['python', '../fatfsparse.py', 'fatfs_image.img'], stderr=STDOUT)
  260. assert compare_folders('testf', 'Espressif')
  261. def test_e2e_very_deep_long(self) -> None:
  262. folder_ = {
  263. 'type': 'folder',
  264. 'name': 'veryveryverylong111',
  265. 'content': [
  266. self.file_('myndewveryverylongfile1.txt', content_=4097 * 'a'),
  267. self.file_('mynewveryverylongfile22.txt', content_=2 * 4097 * 'a'),
  268. self.file_('mynewveryverylongfile333.txt' * 8),
  269. self.file_('mynewveryverylongfile4444.txt' * 8),
  270. self.file_('mynewveryverylongfile5555.txt'),
  271. self.file_('SHORT.TXT'),
  272. ]
  273. }
  274. struct_: dict = {
  275. 'type': 'folder',
  276. 'name': 'testf',
  277. 'content': [
  278. self.file_('mynewveryverylongfile.txt' * 5),
  279. folder_,
  280. ]
  281. }
  282. generate_local_folder_structure(struct_, path_='.')
  283. run([
  284. 'python',
  285. f'{os.path.join(os.path.dirname(__file__), "..", "fatfsgen.py")}',
  286. 'testf', '--long_name_support'
  287. ], stderr=STDOUT)
  288. run(['python', '../fatfsparse.py', 'fatfs_image.img', '--long-name-support'], stderr=STDOUT)
  289. assert compare_folders('testf', 'Espressif')
  290. if __name__ == '__main__':
  291. unittest.main()