test_seek.toml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. # simple file seek
  2. [cases.seek]
  3. defines = [
  4. {COUNT=132, SKIP=4},
  5. {COUNT=132, SKIP=128},
  6. {COUNT=200, SKIP=10},
  7. {COUNT=200, SKIP=100},
  8. {COUNT=4, SKIP=1},
  9. {COUNT=4, SKIP=2},
  10. ]
  11. code = '''
  12. lfs_t lfs;
  13. lfs_format(&lfs, cfg) => 0;
  14. lfs_mount(&lfs, cfg) => 0;
  15. lfs_file_t file;
  16. lfs_file_open(&lfs, &file, "kitty",
  17. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
  18. size_t size = strlen("kittycatcat");
  19. uint8_t buffer[1024];
  20. memcpy(buffer, "kittycatcat", size);
  21. for (int j = 0; j < COUNT; j++) {
  22. lfs_file_write(&lfs, &file, buffer, size);
  23. }
  24. lfs_file_close(&lfs, &file) => 0;
  25. lfs_unmount(&lfs) => 0;
  26. lfs_mount(&lfs, cfg) => 0;
  27. lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY) => 0;
  28. lfs_soff_t pos = -1;
  29. size = strlen("kittycatcat");
  30. for (int i = 0; i < SKIP; i++) {
  31. lfs_file_read(&lfs, &file, buffer, size) => size;
  32. memcmp(buffer, "kittycatcat", size) => 0;
  33. pos = lfs_file_tell(&lfs, &file);
  34. }
  35. assert(pos >= 0);
  36. lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos;
  37. lfs_file_read(&lfs, &file, buffer, size) => size;
  38. memcmp(buffer, "kittycatcat", size) => 0;
  39. lfs_file_rewind(&lfs, &file) => 0;
  40. lfs_file_read(&lfs, &file, buffer, size) => size;
  41. memcmp(buffer, "kittycatcat", size) => 0;
  42. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => size;
  43. lfs_file_read(&lfs, &file, buffer, size) => size;
  44. memcmp(buffer, "kittycatcat", size) => 0;
  45. lfs_file_seek(&lfs, &file, size, LFS_SEEK_CUR) => 3*size;
  46. lfs_file_read(&lfs, &file, buffer, size) => size;
  47. memcmp(buffer, "kittycatcat", size) => 0;
  48. lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos;
  49. lfs_file_read(&lfs, &file, buffer, size) => size;
  50. memcmp(buffer, "kittycatcat", size) => 0;
  51. lfs_file_seek(&lfs, &file, -size, LFS_SEEK_CUR) => pos;
  52. lfs_file_read(&lfs, &file, buffer, size) => size;
  53. memcmp(buffer, "kittycatcat", size) => 0;
  54. lfs_file_seek(&lfs, &file, -size, LFS_SEEK_END) >= 0 => 1;
  55. lfs_file_read(&lfs, &file, buffer, size) => size;
  56. memcmp(buffer, "kittycatcat", size) => 0;
  57. size = lfs_file_size(&lfs, &file);
  58. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => size;
  59. lfs_file_close(&lfs, &file) => 0;
  60. lfs_unmount(&lfs) => 0;
  61. '''
  62. # simple file seek and write
  63. [cases.seek_write]
  64. defines = [
  65. {COUNT=132, SKIP=4},
  66. {COUNT=132, SKIP=128},
  67. {COUNT=200, SKIP=10},
  68. {COUNT=200, SKIP=100},
  69. {COUNT=4, SKIP=1},
  70. {COUNT=4, SKIP=2},
  71. ]
  72. code = '''
  73. lfs_t lfs;
  74. lfs_format(&lfs, cfg) => 0;
  75. lfs_mount(&lfs, cfg) => 0;
  76. lfs_file_t file;
  77. lfs_file_open(&lfs, &file, "kitty",
  78. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
  79. size_t size = strlen("kittycatcat");
  80. uint8_t buffer[1024];
  81. memcpy(buffer, "kittycatcat", size);
  82. for (int j = 0; j < COUNT; j++) {
  83. lfs_file_write(&lfs, &file, buffer, size);
  84. }
  85. lfs_file_close(&lfs, &file) => 0;
  86. lfs_unmount(&lfs) => 0;
  87. lfs_mount(&lfs, cfg) => 0;
  88. lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
  89. lfs_soff_t pos = -1;
  90. size = strlen("kittycatcat");
  91. for (int i = 0; i < SKIP; i++) {
  92. lfs_file_read(&lfs, &file, buffer, size) => size;
  93. memcmp(buffer, "kittycatcat", size) => 0;
  94. pos = lfs_file_tell(&lfs, &file);
  95. }
  96. assert(pos >= 0);
  97. memcpy(buffer, "doggodogdog", size);
  98. lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos;
  99. lfs_file_write(&lfs, &file, buffer, size) => size;
  100. lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos;
  101. lfs_file_read(&lfs, &file, buffer, size) => size;
  102. memcmp(buffer, "doggodogdog", size) => 0;
  103. lfs_file_rewind(&lfs, &file) => 0;
  104. lfs_file_read(&lfs, &file, buffer, size) => size;
  105. memcmp(buffer, "kittycatcat", size) => 0;
  106. lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos;
  107. lfs_file_read(&lfs, &file, buffer, size) => size;
  108. memcmp(buffer, "doggodogdog", size) => 0;
  109. lfs_file_seek(&lfs, &file, -size, LFS_SEEK_END) >= 0 => 1;
  110. lfs_file_read(&lfs, &file, buffer, size) => size;
  111. memcmp(buffer, "kittycatcat", size) => 0;
  112. size = lfs_file_size(&lfs, &file);
  113. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => size;
  114. lfs_file_close(&lfs, &file) => 0;
  115. lfs_unmount(&lfs) => 0;
  116. '''
  117. # boundary seek and writes
  118. [cases.boundary_seek_write]
  119. defines.COUNT = 132
  120. code = '''
  121. lfs_t lfs;
  122. lfs_format(&lfs, cfg) => 0;
  123. lfs_mount(&lfs, cfg) => 0;
  124. lfs_file_t file;
  125. lfs_file_open(&lfs, &file, "kitty",
  126. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
  127. size_t size = strlen("kittycatcat");
  128. uint8_t buffer[1024];
  129. memcpy(buffer, "kittycatcat", size);
  130. for (int j = 0; j < COUNT; j++) {
  131. lfs_file_write(&lfs, &file, buffer, size);
  132. }
  133. lfs_file_close(&lfs, &file) => 0;
  134. lfs_unmount(&lfs) => 0;
  135. lfs_mount(&lfs, cfg) => 0;
  136. lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
  137. size = strlen("hedgehoghog");
  138. const lfs_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019, 1441};
  139. for (unsigned i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) {
  140. lfs_soff_t off = offsets[i];
  141. memcpy(buffer, "hedgehoghog", size);
  142. lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off;
  143. lfs_file_write(&lfs, &file, buffer, size) => size;
  144. lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off;
  145. lfs_file_read(&lfs, &file, buffer, size) => size;
  146. memcmp(buffer, "hedgehoghog", size) => 0;
  147. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
  148. lfs_file_read(&lfs, &file, buffer, size) => size;
  149. memcmp(buffer, "kittycatcat", size) => 0;
  150. lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off;
  151. lfs_file_read(&lfs, &file, buffer, size) => size;
  152. memcmp(buffer, "hedgehoghog", size) => 0;
  153. lfs_file_sync(&lfs, &file) => 0;
  154. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
  155. lfs_file_read(&lfs, &file, buffer, size) => size;
  156. memcmp(buffer, "kittycatcat", size) => 0;
  157. lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off;
  158. lfs_file_read(&lfs, &file, buffer, size) => size;
  159. memcmp(buffer, "hedgehoghog", size) => 0;
  160. }
  161. lfs_file_close(&lfs, &file) => 0;
  162. lfs_unmount(&lfs) => 0;
  163. '''
  164. # out of bounds seek
  165. [cases.out_of_bounds_seek]
  166. defines = [
  167. {COUNT=132, SKIP=4},
  168. {COUNT=132, SKIP=128},
  169. {COUNT=200, SKIP=10},
  170. {COUNT=200, SKIP=100},
  171. {COUNT=4, SKIP=2},
  172. {COUNT=4, SKIP=3},
  173. ]
  174. code = '''
  175. lfs_t lfs;
  176. lfs_format(&lfs, cfg) => 0;
  177. lfs_mount(&lfs, cfg) => 0;
  178. lfs_file_t file;
  179. lfs_file_open(&lfs, &file, "kitty",
  180. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
  181. size_t size = strlen("kittycatcat");
  182. uint8_t buffer[1024];
  183. memcpy(buffer, "kittycatcat", size);
  184. for (int j = 0; j < COUNT; j++) {
  185. lfs_file_write(&lfs, &file, buffer, size);
  186. }
  187. lfs_file_close(&lfs, &file) => 0;
  188. lfs_unmount(&lfs) => 0;
  189. lfs_mount(&lfs, cfg) => 0;
  190. lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
  191. size = strlen("kittycatcat");
  192. lfs_file_size(&lfs, &file) => COUNT*size;
  193. lfs_file_seek(&lfs, &file, (COUNT+SKIP)*size,
  194. LFS_SEEK_SET) => (COUNT+SKIP)*size;
  195. lfs_file_read(&lfs, &file, buffer, size) => 0;
  196. memcpy(buffer, "porcupineee", size);
  197. lfs_file_write(&lfs, &file, buffer, size) => size;
  198. lfs_file_seek(&lfs, &file, (COUNT+SKIP)*size,
  199. LFS_SEEK_SET) => (COUNT+SKIP)*size;
  200. lfs_file_read(&lfs, &file, buffer, size) => size;
  201. memcmp(buffer, "porcupineee", size) => 0;
  202. lfs_file_seek(&lfs, &file, COUNT*size,
  203. LFS_SEEK_SET) => COUNT*size;
  204. lfs_file_read(&lfs, &file, buffer, size) => size;
  205. memcmp(buffer, "\0\0\0\0\0\0\0\0\0\0\0", size) => 0;
  206. lfs_file_seek(&lfs, &file, -((COUNT+SKIP)*size),
  207. LFS_SEEK_CUR) => LFS_ERR_INVAL;
  208. lfs_file_tell(&lfs, &file) => (COUNT+1)*size;
  209. lfs_file_seek(&lfs, &file, -((COUNT+2*SKIP)*size),
  210. LFS_SEEK_END) => LFS_ERR_INVAL;
  211. lfs_file_tell(&lfs, &file) => (COUNT+1)*size;
  212. lfs_file_close(&lfs, &file) => 0;
  213. lfs_unmount(&lfs) => 0;
  214. '''
  215. # inline write and seek
  216. [cases.inline_write_seek]
  217. defines.SIZE = [2, 4, 128, 132]
  218. code = '''
  219. lfs_t lfs;
  220. lfs_format(&lfs, cfg) => 0;
  221. lfs_mount(&lfs, cfg) => 0;
  222. lfs_file_t file;
  223. lfs_file_open(&lfs, &file, "tinykitty",
  224. LFS_O_RDWR | LFS_O_CREAT) => 0;
  225. int j = 0;
  226. int k = 0;
  227. uint8_t buffer[1024];
  228. memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26);
  229. for (unsigned i = 0; i < SIZE; i++) {
  230. lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1;
  231. lfs_file_tell(&lfs, &file) => i+1;
  232. lfs_file_size(&lfs, &file) => i+1;
  233. }
  234. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
  235. lfs_file_tell(&lfs, &file) => 0;
  236. lfs_file_size(&lfs, &file) => SIZE;
  237. for (unsigned i = 0; i < SIZE; i++) {
  238. uint8_t c;
  239. lfs_file_read(&lfs, &file, &c, 1) => 1;
  240. c => buffer[k++ % 26];
  241. }
  242. lfs_file_sync(&lfs, &file) => 0;
  243. lfs_file_tell(&lfs, &file) => SIZE;
  244. lfs_file_size(&lfs, &file) => SIZE;
  245. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
  246. for (unsigned i = 0; i < SIZE; i++) {
  247. lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1;
  248. lfs_file_tell(&lfs, &file) => i+1;
  249. lfs_file_size(&lfs, &file) => SIZE;
  250. lfs_file_sync(&lfs, &file) => 0;
  251. lfs_file_tell(&lfs, &file) => i+1;
  252. lfs_file_size(&lfs, &file) => SIZE;
  253. if (i < SIZE-2) {
  254. uint8_t c[3];
  255. lfs_file_seek(&lfs, &file, -1, LFS_SEEK_CUR) => i;
  256. lfs_file_read(&lfs, &file, &c, 3) => 3;
  257. lfs_file_tell(&lfs, &file) => i+3;
  258. lfs_file_size(&lfs, &file) => SIZE;
  259. lfs_file_seek(&lfs, &file, i+1, LFS_SEEK_SET) => i+1;
  260. lfs_file_tell(&lfs, &file) => i+1;
  261. lfs_file_size(&lfs, &file) => SIZE;
  262. }
  263. }
  264. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
  265. lfs_file_tell(&lfs, &file) => 0;
  266. lfs_file_size(&lfs, &file) => SIZE;
  267. for (unsigned i = 0; i < SIZE; i++) {
  268. uint8_t c;
  269. lfs_file_read(&lfs, &file, &c, 1) => 1;
  270. c => buffer[k++ % 26];
  271. }
  272. lfs_file_sync(&lfs, &file) => 0;
  273. lfs_file_tell(&lfs, &file) => SIZE;
  274. lfs_file_size(&lfs, &file) => SIZE;
  275. lfs_file_close(&lfs, &file) => 0;
  276. lfs_unmount(&lfs) => 0;
  277. '''
  278. # file seek and write with power-loss
  279. [cases.reentrant_seek_write]
  280. # must be power-of-2 for quadratic probing to be exhaustive
  281. defines.COUNT = [4, 64, 128]
  282. reentrant = true
  283. code = '''
  284. lfs_t lfs;
  285. int err = lfs_mount(&lfs, cfg);
  286. if (err) {
  287. lfs_format(&lfs, cfg) => 0;
  288. lfs_mount(&lfs, cfg) => 0;
  289. }
  290. lfs_file_t file;
  291. uint8_t buffer[1024];
  292. err = lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY);
  293. assert(!err || err == LFS_ERR_NOENT);
  294. if (!err) {
  295. if (lfs_file_size(&lfs, &file) != 0) {
  296. lfs_file_size(&lfs, &file) => 11*COUNT;
  297. for (int j = 0; j < COUNT; j++) {
  298. memset(buffer, 0, 11+1);
  299. lfs_file_read(&lfs, &file, buffer, 11) => 11;
  300. assert(memcmp(buffer, "kittycatcat", 11) == 0 ||
  301. memcmp(buffer, "doggodogdog", 11) == 0);
  302. }
  303. }
  304. lfs_file_close(&lfs, &file) => 0;
  305. }
  306. lfs_file_open(&lfs, &file, "kitty", LFS_O_WRONLY | LFS_O_CREAT) => 0;
  307. if (lfs_file_size(&lfs, &file) == 0) {
  308. for (int j = 0; j < COUNT; j++) {
  309. strcpy((char*)buffer, "kittycatcat");
  310. size_t size = strlen((char*)buffer);
  311. lfs_file_write(&lfs, &file, buffer, size) => size;
  312. }
  313. }
  314. lfs_file_close(&lfs, &file) => 0;
  315. strcpy((char*)buffer, "doggodogdog");
  316. size_t size = strlen((char*)buffer);
  317. lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
  318. lfs_file_size(&lfs, &file) => COUNT*size;
  319. // seek and write using quadratic probing to touch all
  320. // 11-byte words in the file
  321. lfs_off_t off = 0;
  322. for (int j = 0; j < COUNT; j++) {
  323. off = (5*off + 1) % COUNT;
  324. lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size;
  325. lfs_file_read(&lfs, &file, buffer, size) => size;
  326. assert(memcmp(buffer, "kittycatcat", size) == 0 ||
  327. memcmp(buffer, "doggodogdog", size) == 0);
  328. if (memcmp(buffer, "doggodogdog", size) != 0) {
  329. lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size;
  330. strcpy((char*)buffer, "doggodogdog");
  331. lfs_file_write(&lfs, &file, buffer, size) => size;
  332. lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size;
  333. lfs_file_read(&lfs, &file, buffer, size) => size;
  334. assert(memcmp(buffer, "doggodogdog", size) == 0);
  335. lfs_file_sync(&lfs, &file) => 0;
  336. lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size;
  337. lfs_file_read(&lfs, &file, buffer, size) => size;
  338. assert(memcmp(buffer, "doggodogdog", size) == 0);
  339. }
  340. }
  341. lfs_file_close(&lfs, &file) => 0;
  342. lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
  343. lfs_file_size(&lfs, &file) => COUNT*size;
  344. for (int j = 0; j < COUNT; j++) {
  345. lfs_file_read(&lfs, &file, buffer, size) => size;
  346. assert(memcmp(buffer, "doggodogdog", size) == 0);
  347. }
  348. lfs_file_close(&lfs, &file) => 0;
  349. lfs_unmount(&lfs) => 0;
  350. '''