test_dirs.toml 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. [[case]] # root
  2. code = '''
  3. lfs_format(&lfs, &cfg) => 0;
  4. lfs_mount(&lfs, &cfg) => 0;
  5. lfs_dir_open(&lfs, &dir, "/") => 0;
  6. lfs_dir_read(&lfs, &dir, &info) => 1;
  7. assert(info.type == LFS_TYPE_DIR);
  8. assert(strcmp(info.name, ".") == 0);
  9. lfs_dir_read(&lfs, &dir, &info) => 1;
  10. assert(info.type == LFS_TYPE_DIR);
  11. assert(strcmp(info.name, "..") == 0);
  12. lfs_dir_read(&lfs, &dir, &info) => 0;
  13. lfs_dir_close(&lfs, &dir) => 0;
  14. lfs_unmount(&lfs) => 0;
  15. '''
  16. [[case]] # many directory creation
  17. define.N = 'range(0, 100, 3)'
  18. code = '''
  19. lfs_format(&lfs, &cfg) => 0;
  20. lfs_mount(&lfs, &cfg) => 0;
  21. for (int i = 0; i < N; i++) {
  22. sprintf(path, "dir%03d", i);
  23. lfs_mkdir(&lfs, path) => 0;
  24. }
  25. lfs_unmount(&lfs) => 0;
  26. lfs_mount(&lfs, &cfg) => 0;
  27. lfs_dir_open(&lfs, &dir, "/") => 0;
  28. lfs_dir_read(&lfs, &dir, &info) => 1;
  29. assert(info.type == LFS_TYPE_DIR);
  30. assert(strcmp(info.name, ".") == 0);
  31. lfs_dir_read(&lfs, &dir, &info) => 1;
  32. assert(info.type == LFS_TYPE_DIR);
  33. assert(strcmp(info.name, "..") == 0);
  34. for (int i = 0; i < N; i++) {
  35. sprintf(path, "dir%03d", i);
  36. lfs_dir_read(&lfs, &dir, &info) => 1;
  37. assert(info.type == LFS_TYPE_DIR);
  38. assert(strcmp(info.name, path) == 0);
  39. }
  40. lfs_dir_read(&lfs, &dir, &info) => 0;
  41. lfs_dir_close(&lfs, &dir) => 0;
  42. lfs_unmount(&lfs) => 0;
  43. '''
  44. [[case]] # many directory removal
  45. define.N = 'range(3, 100, 11)'
  46. code = '''
  47. lfs_format(&lfs, &cfg) => 0;
  48. lfs_mount(&lfs, &cfg) => 0;
  49. for (int i = 0; i < N; i++) {
  50. sprintf(path, "removeme%03d", i);
  51. lfs_mkdir(&lfs, path) => 0;
  52. }
  53. lfs_unmount(&lfs) => 0;
  54. lfs_mount(&lfs, &cfg) => 0;
  55. lfs_dir_open(&lfs, &dir, "/") => 0;
  56. lfs_dir_read(&lfs, &dir, &info) => 1;
  57. assert(info.type == LFS_TYPE_DIR);
  58. assert(strcmp(info.name, ".") == 0);
  59. lfs_dir_read(&lfs, &dir, &info) => 1;
  60. assert(info.type == LFS_TYPE_DIR);
  61. assert(strcmp(info.name, "..") == 0);
  62. for (int i = 0; i < N; i++) {
  63. sprintf(path, "removeme%03d", i);
  64. lfs_dir_read(&lfs, &dir, &info) => 1;
  65. assert(info.type == LFS_TYPE_DIR);
  66. assert(strcmp(info.name, path) == 0);
  67. }
  68. lfs_dir_read(&lfs, &dir, &info) => 0;
  69. lfs_dir_close(&lfs, &dir) => 0;
  70. lfs_unmount(&lfs);
  71. lfs_mount(&lfs, &cfg) => 0;
  72. for (int i = 0; i < N; i++) {
  73. sprintf(path, "removeme%03d", i);
  74. lfs_remove(&lfs, path) => 0;
  75. }
  76. lfs_unmount(&lfs);
  77. lfs_mount(&lfs, &cfg) => 0;
  78. lfs_dir_open(&lfs, &dir, "/") => 0;
  79. lfs_dir_read(&lfs, &dir, &info) => 1;
  80. assert(info.type == LFS_TYPE_DIR);
  81. assert(strcmp(info.name, ".") == 0);
  82. lfs_dir_read(&lfs, &dir, &info) => 1;
  83. assert(info.type == LFS_TYPE_DIR);
  84. assert(strcmp(info.name, "..") == 0);
  85. lfs_dir_read(&lfs, &dir, &info) => 0;
  86. lfs_dir_close(&lfs, &dir) => 0;
  87. lfs_unmount(&lfs) => 0;
  88. '''
  89. [[case]] # many directory rename
  90. define.N = 'range(3, 100, 11)'
  91. code = '''
  92. lfs_format(&lfs, &cfg) => 0;
  93. lfs_mount(&lfs, &cfg) => 0;
  94. for (int i = 0; i < N; i++) {
  95. sprintf(path, "test%03d", i);
  96. lfs_mkdir(&lfs, path) => 0;
  97. }
  98. lfs_unmount(&lfs) => 0;
  99. lfs_mount(&lfs, &cfg) => 0;
  100. lfs_dir_open(&lfs, &dir, "/") => 0;
  101. lfs_dir_read(&lfs, &dir, &info) => 1;
  102. assert(info.type == LFS_TYPE_DIR);
  103. assert(strcmp(info.name, ".") == 0);
  104. lfs_dir_read(&lfs, &dir, &info) => 1;
  105. assert(info.type == LFS_TYPE_DIR);
  106. assert(strcmp(info.name, "..") == 0);
  107. for (int i = 0; i < N; i++) {
  108. sprintf(path, "test%03d", i);
  109. lfs_dir_read(&lfs, &dir, &info) => 1;
  110. assert(info.type == LFS_TYPE_DIR);
  111. assert(strcmp(info.name, path) == 0);
  112. }
  113. lfs_dir_read(&lfs, &dir, &info) => 0;
  114. lfs_dir_close(&lfs, &dir) => 0;
  115. lfs_unmount(&lfs);
  116. lfs_mount(&lfs, &cfg) => 0;
  117. for (int i = 0; i < N; i++) {
  118. char oldpath[128];
  119. char newpath[128];
  120. sprintf(oldpath, "test%03d", i);
  121. sprintf(newpath, "tedd%03d", i);
  122. lfs_rename(&lfs, oldpath, newpath) => 0;
  123. }
  124. lfs_unmount(&lfs);
  125. lfs_mount(&lfs, &cfg) => 0;
  126. lfs_dir_open(&lfs, &dir, "/") => 0;
  127. lfs_dir_read(&lfs, &dir, &info) => 1;
  128. assert(info.type == LFS_TYPE_DIR);
  129. assert(strcmp(info.name, ".") == 0);
  130. lfs_dir_read(&lfs, &dir, &info) => 1;
  131. assert(info.type == LFS_TYPE_DIR);
  132. assert(strcmp(info.name, "..") == 0);
  133. for (int i = 0; i < N; i++) {
  134. sprintf(path, "tedd%03d", i);
  135. lfs_dir_read(&lfs, &dir, &info) => 1;
  136. assert(info.type == LFS_TYPE_DIR);
  137. assert(strcmp(info.name, path) == 0);
  138. }
  139. lfs_dir_read(&lfs, &dir, &info) => 0;
  140. lfs_dir_close(&lfs, &dir) => 0;
  141. lfs_unmount(&lfs);
  142. '''
  143. [[case]] # reentrant many directory creation/rename/removal
  144. define.N = [5, 11]
  145. reentrant = true
  146. if = 'LFS_CACHE_SIZE >= 4' # these just take too long with byte-level writes
  147. code = '''
  148. err = lfs_mount(&lfs, &cfg);
  149. if (err) {
  150. lfs_format(&lfs, &cfg) => 0;
  151. lfs_mount(&lfs, &cfg) => 0;
  152. }
  153. for (int i = 0; i < N; i++) {
  154. sprintf(path, "hi%03d", i);
  155. err = lfs_mkdir(&lfs, path);
  156. assert(err == 0 || err == LFS_ERR_EXIST);
  157. }
  158. for (int i = 0; i < N; i++) {
  159. sprintf(path, "hello%03d", i);
  160. err = lfs_remove(&lfs, path);
  161. assert(err == 0 || err == LFS_ERR_NOENT);
  162. }
  163. lfs_dir_open(&lfs, &dir, "/") => 0;
  164. lfs_dir_read(&lfs, &dir, &info) => 1;
  165. assert(info.type == LFS_TYPE_DIR);
  166. assert(strcmp(info.name, ".") == 0);
  167. lfs_dir_read(&lfs, &dir, &info) => 1;
  168. assert(info.type == LFS_TYPE_DIR);
  169. assert(strcmp(info.name, "..") == 0);
  170. for (int i = 0; i < N; i++) {
  171. sprintf(path, "hi%03d", i);
  172. lfs_dir_read(&lfs, &dir, &info) => 1;
  173. assert(info.type == LFS_TYPE_DIR);
  174. assert(strcmp(info.name, path) == 0);
  175. }
  176. lfs_dir_read(&lfs, &dir, &info) => 0;
  177. lfs_dir_close(&lfs, &dir) => 0;
  178. for (int i = 0; i < N; i++) {
  179. char oldpath[128];
  180. char newpath[128];
  181. sprintf(oldpath, "hi%03d", i);
  182. sprintf(newpath, "hello%03d", i);
  183. // YES this can overwrite an existing newpath
  184. lfs_rename(&lfs, oldpath, newpath) => 0;
  185. }
  186. lfs_dir_open(&lfs, &dir, "/") => 0;
  187. lfs_dir_read(&lfs, &dir, &info) => 1;
  188. assert(info.type == LFS_TYPE_DIR);
  189. assert(strcmp(info.name, ".") == 0);
  190. lfs_dir_read(&lfs, &dir, &info) => 1;
  191. assert(info.type == LFS_TYPE_DIR);
  192. assert(strcmp(info.name, "..") == 0);
  193. for (int i = 0; i < N; i++) {
  194. sprintf(path, "hello%03d", i);
  195. lfs_dir_read(&lfs, &dir, &info) => 1;
  196. assert(info.type == LFS_TYPE_DIR);
  197. assert(strcmp(info.name, path) == 0);
  198. }
  199. lfs_dir_read(&lfs, &dir, &info) => 0;
  200. lfs_dir_close(&lfs, &dir) => 0;
  201. for (int i = 0; i < N; i++) {
  202. sprintf(path, "hello%03d", i);
  203. lfs_remove(&lfs, path) => 0;
  204. }
  205. lfs_dir_open(&lfs, &dir, "/") => 0;
  206. lfs_dir_read(&lfs, &dir, &info) => 1;
  207. assert(info.type == LFS_TYPE_DIR);
  208. assert(strcmp(info.name, ".") == 0);
  209. lfs_dir_read(&lfs, &dir, &info) => 1;
  210. assert(info.type == LFS_TYPE_DIR);
  211. assert(strcmp(info.name, "..") == 0);
  212. lfs_dir_read(&lfs, &dir, &info) => 0;
  213. lfs_dir_close(&lfs, &dir) => 0;
  214. lfs_unmount(&lfs) => 0;
  215. '''
  216. [[case]] # file creation
  217. define.N = 'range(3, 100, 11)'
  218. code = '''
  219. lfs_format(&lfs, &cfg) => 0;
  220. lfs_mount(&lfs, &cfg) => 0;
  221. for (int i = 0; i < N; i++) {
  222. sprintf(path, "file%03d", i);
  223. lfs_file_open(&lfs, &file, path,
  224. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
  225. lfs_file_close(&lfs, &file) => 0;
  226. }
  227. lfs_unmount(&lfs) => 0;
  228. lfs_mount(&lfs, &cfg) => 0;
  229. lfs_dir_open(&lfs, &dir, "/") => 0;
  230. lfs_dir_read(&lfs, &dir, &info) => 1;
  231. assert(info.type == LFS_TYPE_DIR);
  232. assert(strcmp(info.name, ".") == 0);
  233. lfs_dir_read(&lfs, &dir, &info) => 1;
  234. assert(info.type == LFS_TYPE_DIR);
  235. assert(strcmp(info.name, "..") == 0);
  236. for (int i = 0; i < N; i++) {
  237. sprintf(path, "file%03d", i);
  238. lfs_dir_read(&lfs, &dir, &info) => 1;
  239. assert(info.type == LFS_TYPE_REG);
  240. assert(strcmp(info.name, path) == 0);
  241. }
  242. lfs_dir_read(&lfs, &dir, &info) => 0;
  243. lfs_dir_close(&lfs, &dir) => 0;
  244. lfs_unmount(&lfs);
  245. '''
  246. [[case]] # file removal
  247. define.N = 'range(0, 100, 3)'
  248. code = '''
  249. lfs_format(&lfs, &cfg) => 0;
  250. lfs_mount(&lfs, &cfg) => 0;
  251. for (int i = 0; i < N; i++) {
  252. sprintf(path, "removeme%03d", i);
  253. lfs_file_open(&lfs, &file, path,
  254. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
  255. lfs_file_close(&lfs, &file) => 0;
  256. }
  257. lfs_unmount(&lfs) => 0;
  258. lfs_mount(&lfs, &cfg) => 0;
  259. lfs_dir_open(&lfs, &dir, "/") => 0;
  260. lfs_dir_read(&lfs, &dir, &info) => 1;
  261. assert(info.type == LFS_TYPE_DIR);
  262. assert(strcmp(info.name, ".") == 0);
  263. lfs_dir_read(&lfs, &dir, &info) => 1;
  264. assert(info.type == LFS_TYPE_DIR);
  265. assert(strcmp(info.name, "..") == 0);
  266. for (int i = 0; i < N; i++) {
  267. sprintf(path, "removeme%03d", i);
  268. lfs_dir_read(&lfs, &dir, &info) => 1;
  269. assert(info.type == LFS_TYPE_REG);
  270. assert(strcmp(info.name, path) == 0);
  271. }
  272. lfs_dir_read(&lfs, &dir, &info) => 0;
  273. lfs_dir_close(&lfs, &dir) => 0;
  274. lfs_unmount(&lfs);
  275. lfs_mount(&lfs, &cfg) => 0;
  276. for (int i = 0; i < N; i++) {
  277. sprintf(path, "removeme%03d", i);
  278. lfs_remove(&lfs, path) => 0;
  279. }
  280. lfs_unmount(&lfs);
  281. lfs_mount(&lfs, &cfg) => 0;
  282. lfs_dir_open(&lfs, &dir, "/") => 0;
  283. lfs_dir_read(&lfs, &dir, &info) => 1;
  284. assert(info.type == LFS_TYPE_DIR);
  285. assert(strcmp(info.name, ".") == 0);
  286. lfs_dir_read(&lfs, &dir, &info) => 1;
  287. assert(info.type == LFS_TYPE_DIR);
  288. assert(strcmp(info.name, "..") == 0);
  289. lfs_dir_read(&lfs, &dir, &info) => 0;
  290. lfs_dir_close(&lfs, &dir) => 0;
  291. lfs_unmount(&lfs) => 0;
  292. '''
  293. [[case]] # file rename
  294. define.N = 'range(0, 100, 3)'
  295. code = '''
  296. lfs_format(&lfs, &cfg) => 0;
  297. lfs_mount(&lfs, &cfg) => 0;
  298. for (int i = 0; i < N; i++) {
  299. sprintf(path, "test%03d", i);
  300. lfs_file_open(&lfs, &file, path,
  301. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
  302. lfs_file_close(&lfs, &file) => 0;
  303. }
  304. lfs_unmount(&lfs) => 0;
  305. lfs_mount(&lfs, &cfg) => 0;
  306. lfs_dir_open(&lfs, &dir, "/") => 0;
  307. lfs_dir_read(&lfs, &dir, &info) => 1;
  308. assert(info.type == LFS_TYPE_DIR);
  309. assert(strcmp(info.name, ".") == 0);
  310. lfs_dir_read(&lfs, &dir, &info) => 1;
  311. assert(info.type == LFS_TYPE_DIR);
  312. assert(strcmp(info.name, "..") == 0);
  313. for (int i = 0; i < N; i++) {
  314. sprintf(path, "test%03d", i);
  315. lfs_dir_read(&lfs, &dir, &info) => 1;
  316. assert(info.type == LFS_TYPE_REG);
  317. assert(strcmp(info.name, path) == 0);
  318. }
  319. lfs_dir_read(&lfs, &dir, &info) => 0;
  320. lfs_dir_close(&lfs, &dir) => 0;
  321. lfs_unmount(&lfs);
  322. lfs_mount(&lfs, &cfg) => 0;
  323. for (int i = 0; i < N; i++) {
  324. char oldpath[128];
  325. char newpath[128];
  326. sprintf(oldpath, "test%03d", i);
  327. sprintf(newpath, "tedd%03d", i);
  328. lfs_rename(&lfs, oldpath, newpath) => 0;
  329. }
  330. lfs_unmount(&lfs);
  331. lfs_mount(&lfs, &cfg) => 0;
  332. lfs_dir_open(&lfs, &dir, "/") => 0;
  333. lfs_dir_read(&lfs, &dir, &info) => 1;
  334. assert(info.type == LFS_TYPE_DIR);
  335. assert(strcmp(info.name, ".") == 0);
  336. lfs_dir_read(&lfs, &dir, &info) => 1;
  337. assert(info.type == LFS_TYPE_DIR);
  338. assert(strcmp(info.name, "..") == 0);
  339. for (int i = 0; i < N; i++) {
  340. sprintf(path, "tedd%03d", i);
  341. lfs_dir_read(&lfs, &dir, &info) => 1;
  342. assert(info.type == LFS_TYPE_REG);
  343. assert(strcmp(info.name, path) == 0);
  344. }
  345. lfs_dir_read(&lfs, &dir, &info) => 0;
  346. lfs_dir_close(&lfs, &dir) => 0;
  347. lfs_unmount(&lfs);
  348. '''
  349. [[case]] # reentrant file creation/rename/removal
  350. define.N = [5, 25]
  351. reentrant = true
  352. if = 'LFS_CACHE_SIZE >= 4' # these just take too long with byte-level writes
  353. code = '''
  354. err = lfs_mount(&lfs, &cfg);
  355. if (err) {
  356. lfs_format(&lfs, &cfg) => 0;
  357. lfs_mount(&lfs, &cfg) => 0;
  358. }
  359. for (int i = 0; i < N; i++) {
  360. sprintf(path, "hi%03d", i);
  361. lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
  362. lfs_file_close(&lfs, &file) => 0;
  363. }
  364. for (int i = 0; i < N; i++) {
  365. sprintf(path, "hello%03d", i);
  366. err = lfs_remove(&lfs, path);
  367. assert(err == 0 || err == LFS_ERR_NOENT);
  368. }
  369. lfs_dir_open(&lfs, &dir, "/") => 0;
  370. lfs_dir_read(&lfs, &dir, &info) => 1;
  371. assert(info.type == LFS_TYPE_DIR);
  372. assert(strcmp(info.name, ".") == 0);
  373. lfs_dir_read(&lfs, &dir, &info) => 1;
  374. assert(info.type == LFS_TYPE_DIR);
  375. assert(strcmp(info.name, "..") == 0);
  376. for (int i = 0; i < N; i++) {
  377. sprintf(path, "hi%03d", i);
  378. lfs_dir_read(&lfs, &dir, &info) => 1;
  379. assert(info.type == LFS_TYPE_REG);
  380. assert(strcmp(info.name, path) == 0);
  381. }
  382. lfs_dir_read(&lfs, &dir, &info) => 0;
  383. lfs_dir_close(&lfs, &dir) => 0;
  384. for (int i = 0; i < N; i++) {
  385. char oldpath[128];
  386. char newpath[128];
  387. sprintf(oldpath, "hi%03d", i);
  388. sprintf(newpath, "hello%03d", i);
  389. // YES this can overwrite an existing newpath
  390. lfs_rename(&lfs, oldpath, newpath) => 0;
  391. }
  392. lfs_dir_open(&lfs, &dir, "/") => 0;
  393. lfs_dir_read(&lfs, &dir, &info) => 1;
  394. assert(info.type == LFS_TYPE_DIR);
  395. assert(strcmp(info.name, ".") == 0);
  396. lfs_dir_read(&lfs, &dir, &info) => 1;
  397. assert(info.type == LFS_TYPE_DIR);
  398. assert(strcmp(info.name, "..") == 0);
  399. for (int i = 0; i < N; i++) {
  400. sprintf(path, "hello%03d", i);
  401. lfs_dir_read(&lfs, &dir, &info) => 1;
  402. assert(info.type == LFS_TYPE_REG);
  403. assert(strcmp(info.name, path) == 0);
  404. }
  405. lfs_dir_read(&lfs, &dir, &info) => 0;
  406. lfs_dir_close(&lfs, &dir) => 0;
  407. for (int i = 0; i < N; i++) {
  408. sprintf(path, "hello%03d", i);
  409. lfs_remove(&lfs, path) => 0;
  410. }
  411. lfs_dir_open(&lfs, &dir, "/") => 0;
  412. lfs_dir_read(&lfs, &dir, &info) => 1;
  413. assert(info.type == LFS_TYPE_DIR);
  414. assert(strcmp(info.name, ".") == 0);
  415. lfs_dir_read(&lfs, &dir, &info) => 1;
  416. assert(info.type == LFS_TYPE_DIR);
  417. assert(strcmp(info.name, "..") == 0);
  418. lfs_dir_read(&lfs, &dir, &info) => 0;
  419. lfs_dir_close(&lfs, &dir) => 0;
  420. lfs_unmount(&lfs) => 0;
  421. '''
  422. [[case]] # nested directories
  423. code = '''
  424. lfs_format(&lfs, &cfg) => 0;
  425. lfs_mount(&lfs, &cfg) => 0;
  426. lfs_mkdir(&lfs, "potato") => 0;
  427. lfs_file_open(&lfs, &file, "burito",
  428. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
  429. lfs_file_close(&lfs, &file) => 0;
  430. lfs_unmount(&lfs) => 0;
  431. lfs_mount(&lfs, &cfg) => 0;
  432. lfs_mkdir(&lfs, "potato/baked") => 0;
  433. lfs_mkdir(&lfs, "potato/sweet") => 0;
  434. lfs_mkdir(&lfs, "potato/fried") => 0;
  435. lfs_unmount(&lfs) => 0;
  436. lfs_mount(&lfs, &cfg) => 0;
  437. lfs_dir_open(&lfs, &dir, "potato") => 0;
  438. lfs_dir_read(&lfs, &dir, &info) => 1;
  439. assert(strcmp(info.name, ".") == 0);
  440. info.type => LFS_TYPE_DIR;
  441. lfs_dir_read(&lfs, &dir, &info) => 1;
  442. assert(strcmp(info.name, "..") == 0);
  443. info.type => LFS_TYPE_DIR;
  444. lfs_dir_read(&lfs, &dir, &info) => 1;
  445. assert(strcmp(info.name, "baked") == 0);
  446. info.type => LFS_TYPE_DIR;
  447. lfs_dir_read(&lfs, &dir, &info) => 1;
  448. assert(strcmp(info.name, "fried") == 0);
  449. info.type => LFS_TYPE_DIR;
  450. lfs_dir_read(&lfs, &dir, &info) => 1;
  451. assert(strcmp(info.name, "sweet") == 0);
  452. info.type => LFS_TYPE_DIR;
  453. lfs_dir_read(&lfs, &dir, &info) => 0;
  454. lfs_dir_close(&lfs, &dir) => 0;
  455. lfs_unmount(&lfs) => 0;
  456. // try removing?
  457. lfs_mount(&lfs, &cfg) => 0;
  458. lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY;
  459. lfs_unmount(&lfs) => 0;
  460. // try renaming?
  461. lfs_mount(&lfs, &cfg) => 0;
  462. lfs_rename(&lfs, "potato", "coldpotato") => 0;
  463. lfs_unmount(&lfs) => 0;
  464. lfs_mount(&lfs, &cfg) => 0;
  465. lfs_rename(&lfs, "coldpotato", "warmpotato") => 0;
  466. lfs_rename(&lfs, "warmpotato", "hotpotato") => 0;
  467. lfs_unmount(&lfs) => 0;
  468. lfs_mount(&lfs, &cfg) => 0;
  469. lfs_remove(&lfs, "potato") => LFS_ERR_NOENT;
  470. lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT;
  471. lfs_remove(&lfs, "warmpotato") => LFS_ERR_NOENT;
  472. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  473. lfs_unmount(&lfs) => 0;
  474. // try cross-directory renaming
  475. lfs_mount(&lfs, &cfg) => 0;
  476. lfs_mkdir(&lfs, "coldpotato") => 0;
  477. lfs_rename(&lfs, "hotpotato/baked", "coldpotato/baked") => 0;
  478. lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY;
  479. lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY;
  480. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  481. lfs_rename(&lfs, "hotpotato/fried", "coldpotato/fried") => 0;
  482. lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY;
  483. lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY;
  484. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  485. lfs_rename(&lfs, "hotpotato/sweet", "coldpotato/sweet") => 0;
  486. lfs_rename(&lfs, "coldpotato", "hotpotato") => 0;
  487. lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT;
  488. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  489. lfs_unmount(&lfs) => 0;
  490. lfs_mount(&lfs, &cfg) => 0;
  491. lfs_dir_open(&lfs, &dir, "hotpotato") => 0;
  492. lfs_dir_read(&lfs, &dir, &info) => 1;
  493. assert(strcmp(info.name, ".") == 0);
  494. info.type => LFS_TYPE_DIR;
  495. lfs_dir_read(&lfs, &dir, &info) => 1;
  496. assert(strcmp(info.name, "..") == 0);
  497. info.type => LFS_TYPE_DIR;
  498. lfs_dir_read(&lfs, &dir, &info) => 1;
  499. assert(strcmp(info.name, "baked") == 0);
  500. info.type => LFS_TYPE_DIR;
  501. lfs_dir_read(&lfs, &dir, &info) => 1;
  502. assert(strcmp(info.name, "fried") == 0);
  503. info.type => LFS_TYPE_DIR;
  504. lfs_dir_read(&lfs, &dir, &info) => 1;
  505. assert(strcmp(info.name, "sweet") == 0);
  506. info.type => LFS_TYPE_DIR;
  507. lfs_dir_read(&lfs, &dir, &info) => 0;
  508. lfs_dir_close(&lfs, &dir) => 0;
  509. lfs_unmount(&lfs) => 0;
  510. // final remove
  511. lfs_mount(&lfs, &cfg) => 0;
  512. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  513. lfs_remove(&lfs, "hotpotato/baked") => 0;
  514. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  515. lfs_remove(&lfs, "hotpotato/fried") => 0;
  516. lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
  517. lfs_remove(&lfs, "hotpotato/sweet") => 0;
  518. lfs_remove(&lfs, "hotpotato") => 0;
  519. lfs_unmount(&lfs) => 0;
  520. lfs_mount(&lfs, &cfg) => 0;
  521. lfs_dir_open(&lfs, &dir, "/") => 0;
  522. lfs_dir_read(&lfs, &dir, &info) => 1;
  523. assert(strcmp(info.name, ".") == 0);
  524. info.type => LFS_TYPE_DIR;
  525. lfs_dir_read(&lfs, &dir, &info) => 1;
  526. assert(strcmp(info.name, "..") == 0);
  527. info.type => LFS_TYPE_DIR;
  528. lfs_dir_read(&lfs, &dir, &info) => 1;
  529. assert(strcmp(info.name, "burito") == 0);
  530. info.type => LFS_TYPE_REG;
  531. lfs_dir_read(&lfs, &dir, &info) => 0;
  532. lfs_dir_close(&lfs, &dir) => 0;
  533. lfs_unmount(&lfs) => 0;
  534. '''
  535. [[case]] # recursive remove
  536. define.N = [10, 100]
  537. code = '''
  538. lfs_format(&lfs, &cfg) => 0;
  539. lfs_mount(&lfs, &cfg) => 0;
  540. lfs_mkdir(&lfs, "prickly-pear") => 0;
  541. for (int i = 0; i < N; i++) {
  542. sprintf(path, "prickly-pear/cactus%03d", i);
  543. lfs_mkdir(&lfs, path) => 0;
  544. }
  545. lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
  546. lfs_dir_read(&lfs, &dir, &info) => 1;
  547. assert(info.type == LFS_TYPE_DIR);
  548. assert(strcmp(info.name, ".") == 0);
  549. lfs_dir_read(&lfs, &dir, &info) => 1;
  550. assert(info.type == LFS_TYPE_DIR);
  551. assert(strcmp(info.name, "..") == 0);
  552. for (int i = 0; i < N; i++) {
  553. sprintf(path, "cactus%03d", i);
  554. lfs_dir_read(&lfs, &dir, &info) => 1;
  555. assert(info.type == LFS_TYPE_DIR);
  556. assert(strcmp(info.name, path) == 0);
  557. }
  558. lfs_dir_read(&lfs, &dir, &info) => 0;
  559. lfs_dir_close(&lfs, &dir) => 0;
  560. lfs_unmount(&lfs);
  561. lfs_mount(&lfs, &cfg) => 0;
  562. lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY;
  563. lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
  564. lfs_dir_read(&lfs, &dir, &info) => 1;
  565. assert(info.type == LFS_TYPE_DIR);
  566. assert(strcmp(info.name, ".") == 0);
  567. lfs_dir_read(&lfs, &dir, &info) => 1;
  568. assert(info.type == LFS_TYPE_DIR);
  569. assert(strcmp(info.name, "..") == 0);
  570. for (int i = 0; i < N; i++) {
  571. sprintf(path, "cactus%03d", i);
  572. lfs_dir_read(&lfs, &dir, &info) => 1;
  573. assert(info.type == LFS_TYPE_DIR);
  574. assert(strcmp(info.name, path) == 0);
  575. sprintf(path, "prickly-pear/%s", info.name);
  576. lfs_remove(&lfs, path) => 0;
  577. }
  578. lfs_dir_read(&lfs, &dir, &info) => 0;
  579. lfs_dir_close(&lfs, &dir) => 0;
  580. lfs_remove(&lfs, "prickly-pear") => 0;
  581. lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
  582. lfs_unmount(&lfs) => 0;
  583. lfs_mount(&lfs, &cfg) => 0;
  584. lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
  585. lfs_unmount(&lfs) => 0;
  586. '''
  587. [[case]] # other error cases
  588. code = '''
  589. lfs_format(&lfs, &cfg) => 0;
  590. lfs_mount(&lfs, &cfg) => 0;
  591. lfs_mkdir(&lfs, "potato") => 0;
  592. lfs_file_open(&lfs, &file, "burito",
  593. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
  594. lfs_file_close(&lfs, &file) => 0;
  595. lfs_unmount(&lfs) => 0;
  596. lfs_mount(&lfs, &cfg) => 0;
  597. lfs_mkdir(&lfs, "potato") => LFS_ERR_EXIST;
  598. lfs_mkdir(&lfs, "burito") => LFS_ERR_EXIST;
  599. lfs_file_open(&lfs, &file, "burito",
  600. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
  601. lfs_file_open(&lfs, &file, "potato",
  602. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
  603. lfs_dir_open(&lfs, &dir, "tomato") => LFS_ERR_NOENT;
  604. lfs_dir_open(&lfs, &dir, "burito") => LFS_ERR_NOTDIR;
  605. lfs_file_open(&lfs, &file, "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT;
  606. lfs_file_open(&lfs, &file, "potato", LFS_O_RDONLY) => LFS_ERR_ISDIR;
  607. lfs_file_open(&lfs, &file, "tomato", LFS_O_WRONLY) => LFS_ERR_NOENT;
  608. lfs_file_open(&lfs, &file, "potato", LFS_O_WRONLY) => LFS_ERR_ISDIR;
  609. lfs_file_open(&lfs, &file, "potato",
  610. LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR;
  611. lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
  612. lfs_file_open(&lfs, &file, "/",
  613. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
  614. lfs_file_open(&lfs, &file, "/", LFS_O_RDONLY) => LFS_ERR_ISDIR;
  615. lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY) => LFS_ERR_ISDIR;
  616. lfs_file_open(&lfs, &file, "/",
  617. LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR;
  618. // check that errors did not corrupt directory
  619. lfs_dir_open(&lfs, &dir, "/") => 0;
  620. lfs_dir_read(&lfs, &dir, &info) => 1;
  621. assert(info.type == LFS_TYPE_DIR);
  622. assert(strcmp(info.name, ".") == 0);
  623. lfs_dir_read(&lfs, &dir, &info) => 1;
  624. assert(info.type == LFS_TYPE_DIR);
  625. assert(strcmp(info.name, "..") == 0);
  626. lfs_dir_read(&lfs, &dir, &info) => 1;
  627. assert(info.type == LFS_TYPE_REG);
  628. assert(strcmp(info.name, "burito") == 0);
  629. lfs_dir_read(&lfs, &dir, &info) => 1;
  630. assert(info.type == LFS_TYPE_DIR);
  631. assert(strcmp(info.name, "potato") == 0);
  632. lfs_dir_read(&lfs, &dir, &info) => 0;
  633. lfs_dir_close(&lfs, &dir) => 0;
  634. lfs_unmount(&lfs) => 0;
  635. // or on disk
  636. lfs_mount(&lfs, &cfg) => 0;
  637. lfs_dir_open(&lfs, &dir, "/") => 0;
  638. lfs_dir_read(&lfs, &dir, &info) => 1;
  639. assert(info.type == LFS_TYPE_DIR);
  640. assert(strcmp(info.name, ".") == 0);
  641. lfs_dir_read(&lfs, &dir, &info) => 1;
  642. assert(info.type == LFS_TYPE_DIR);
  643. assert(strcmp(info.name, "..") == 0);
  644. lfs_dir_read(&lfs, &dir, &info) => 1;
  645. assert(info.type == LFS_TYPE_REG);
  646. assert(strcmp(info.name, "burito") == 0);
  647. lfs_dir_read(&lfs, &dir, &info) => 1;
  648. assert(info.type == LFS_TYPE_DIR);
  649. assert(strcmp(info.name, "potato") == 0);
  650. lfs_dir_read(&lfs, &dir, &info) => 0;
  651. lfs_dir_close(&lfs, &dir) => 0;
  652. lfs_unmount(&lfs) => 0;
  653. '''
  654. [[case]] # directory seek
  655. define.COUNT = [4, 128, 132]
  656. code = '''
  657. lfs_format(&lfs, &cfg) => 0;
  658. lfs_mount(&lfs, &cfg) => 0;
  659. lfs_mkdir(&lfs, "hello") => 0;
  660. for (int i = 0; i < COUNT; i++) {
  661. sprintf(path, "hello/kitty%03d", i);
  662. lfs_mkdir(&lfs, path) => 0;
  663. }
  664. lfs_unmount(&lfs) => 0;
  665. for (int j = 2; j < COUNT; j++) {
  666. lfs_mount(&lfs, &cfg) => 0;
  667. lfs_dir_open(&lfs, &dir, "hello") => 0;
  668. lfs_dir_read(&lfs, &dir, &info) => 1;
  669. assert(strcmp(info.name, ".") == 0);
  670. assert(info.type == LFS_TYPE_DIR);
  671. lfs_dir_read(&lfs, &dir, &info) => 1;
  672. assert(strcmp(info.name, "..") == 0);
  673. assert(info.type == LFS_TYPE_DIR);
  674. lfs_soff_t pos;
  675. for (int i = 0; i < j; i++) {
  676. sprintf(path, "kitty%03d", i);
  677. lfs_dir_read(&lfs, &dir, &info) => 1;
  678. assert(strcmp(info.name, path) == 0);
  679. assert(info.type == LFS_TYPE_DIR);
  680. pos = lfs_dir_tell(&lfs, &dir);
  681. assert(pos >= 0);
  682. }
  683. lfs_dir_seek(&lfs, &dir, pos) => 0;
  684. sprintf(path, "kitty%03d", j);
  685. lfs_dir_read(&lfs, &dir, &info) => 1;
  686. assert(strcmp(info.name, path) == 0);
  687. assert(info.type == LFS_TYPE_DIR);
  688. lfs_dir_rewind(&lfs, &dir) => 0;
  689. sprintf(path, "kitty%03d", 0);
  690. lfs_dir_read(&lfs, &dir, &info) => 1;
  691. assert(strcmp(info.name, ".") == 0);
  692. assert(info.type == LFS_TYPE_DIR);
  693. lfs_dir_read(&lfs, &dir, &info) => 1;
  694. assert(strcmp(info.name, "..") == 0);
  695. assert(info.type == LFS_TYPE_DIR);
  696. lfs_dir_read(&lfs, &dir, &info) => 1;
  697. assert(strcmp(info.name, path) == 0);
  698. assert(info.type == LFS_TYPE_DIR);
  699. lfs_dir_seek(&lfs, &dir, pos) => 0;
  700. sprintf(path, "kitty%03d", j);
  701. lfs_dir_read(&lfs, &dir, &info) => 1;
  702. assert(strcmp(info.name, path) == 0);
  703. assert(info.type == LFS_TYPE_DIR);
  704. lfs_dir_close(&lfs, &dir) => 0;
  705. lfs_unmount(&lfs) => 0;
  706. }
  707. '''
  708. [[case]] # root seek
  709. define.COUNT = [4, 128, 132]
  710. code = '''
  711. lfs_format(&lfs, &cfg) => 0;
  712. lfs_mount(&lfs, &cfg) => 0;
  713. for (int i = 0; i < COUNT; i++) {
  714. sprintf(path, "hi%03d", i);
  715. lfs_mkdir(&lfs, path) => 0;
  716. }
  717. lfs_unmount(&lfs) => 0;
  718. for (int j = 2; j < COUNT; j++) {
  719. lfs_mount(&lfs, &cfg) => 0;
  720. lfs_dir_open(&lfs, &dir, "/") => 0;
  721. lfs_dir_read(&lfs, &dir, &info) => 1;
  722. assert(strcmp(info.name, ".") == 0);
  723. assert(info.type == LFS_TYPE_DIR);
  724. lfs_dir_read(&lfs, &dir, &info) => 1;
  725. assert(strcmp(info.name, "..") == 0);
  726. assert(info.type == LFS_TYPE_DIR);
  727. lfs_soff_t pos;
  728. for (int i = 0; i < j; i++) {
  729. sprintf(path, "hi%03d", i);
  730. lfs_dir_read(&lfs, &dir, &info) => 1;
  731. assert(strcmp(info.name, path) == 0);
  732. assert(info.type == LFS_TYPE_DIR);
  733. pos = lfs_dir_tell(&lfs, &dir);
  734. assert(pos >= 0);
  735. }
  736. lfs_dir_seek(&lfs, &dir, pos) => 0;
  737. sprintf(path, "hi%03d", j);
  738. lfs_dir_read(&lfs, &dir, &info) => 1;
  739. assert(strcmp(info.name, path) == 0);
  740. assert(info.type == LFS_TYPE_DIR);
  741. lfs_dir_rewind(&lfs, &dir) => 0;
  742. sprintf(path, "hi%03d", 0);
  743. lfs_dir_read(&lfs, &dir, &info) => 1;
  744. assert(strcmp(info.name, ".") == 0);
  745. assert(info.type == LFS_TYPE_DIR);
  746. lfs_dir_read(&lfs, &dir, &info) => 1;
  747. assert(strcmp(info.name, "..") == 0);
  748. assert(info.type == LFS_TYPE_DIR);
  749. lfs_dir_read(&lfs, &dir, &info) => 1;
  750. assert(strcmp(info.name, path) == 0);
  751. assert(info.type == LFS_TYPE_DIR);
  752. lfs_dir_seek(&lfs, &dir, pos) => 0;
  753. sprintf(path, "hi%03d", j);
  754. lfs_dir_read(&lfs, &dir, &info) => 1;
  755. assert(strcmp(info.name, path) == 0);
  756. assert(info.type == LFS_TYPE_DIR);
  757. lfs_dir_close(&lfs, &dir) => 0;
  758. lfs_unmount(&lfs) => 0;
  759. }
  760. '''