test_check.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * test_dev.c
  3. *
  4. * Created on: Jul 14, 2013
  5. * Author: petera
  6. */
  7. #include "testrunner.h"
  8. #include "test_spiffs.h"
  9. #include "spiffs_nucleus.h"
  10. #include "spiffs.h"
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14. #include <dirent.h>
  15. #include <unistd.h>
  16. SUITE(check_tests)
  17. void setup() {
  18. _setup();
  19. }
  20. void teardown() {
  21. _teardown();
  22. }
  23. TEST(evil_write) {
  24. fs_set_validate_flashing(0);
  25. printf("writing corruption to block 1 data range (leaving lu intact)\n");
  26. u32_t data_range = SPIFFS_CFG_LOG_BLOCK_SZ(FS) -
  27. SPIFFS_CFG_LOG_PAGE_SZ(FS) * (SPIFFS_OBJ_LOOKUP_PAGES(FS));
  28. u8_t *corruption = malloc(data_range);
  29. memrand(corruption, data_range);
  30. u32_t addr = 0 * SPIFFS_CFG_LOG_PAGE_SZ(FS) * SPIFFS_OBJ_LOOKUP_PAGES(FS);
  31. area_write(addr, corruption, data_range);
  32. free(corruption);
  33. int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
  34. int res = test_create_and_write_file("file", size, size);
  35. printf("CHECK1-----------------\n");
  36. SPIFFS_check(FS);
  37. printf("CHECK2-----------------\n");
  38. SPIFFS_check(FS);
  39. printf("CHECK3-----------------\n");
  40. SPIFFS_check(FS);
  41. res = test_create_and_write_file("file2", size, size);
  42. TEST_CHECK(res >= 0);
  43. return TEST_RES_OK;
  44. } TEST_END(evil_write)
  45. TEST(lu_check1) {
  46. int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
  47. int res = test_create_and_write_file("file", size, size);
  48. TEST_CHECK(res >= 0);
  49. res = read_and_verify("file");
  50. TEST_CHECK(res >= 0);
  51. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  52. TEST_CHECK(fd > 0);
  53. spiffs_stat s;
  54. res = SPIFFS_fstat(FS, fd, &s);
  55. TEST_CHECK(res >= 0);
  56. SPIFFS_close(FS, fd);
  57. // modify lu entry data page index 1
  58. spiffs_page_ix pix;
  59. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix);
  60. TEST_CHECK(res >= 0);
  61. // reset lu entry to being erased, but keep page data
  62. spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED;
  63. spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
  64. int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
  65. u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry*sizeof(spiffs_obj_id);
  66. area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
  67. #if SPIFFS_CACHE
  68. spiffs_cache *cache = spiffs_get_cache(FS);
  69. cache->cpage_use_map = 0;
  70. #endif
  71. SPIFFS_check(FS);
  72. return TEST_RES_OK;
  73. } TEST_END(lu_check1)
  74. TEST(page_cons1) {
  75. int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
  76. int res = test_create_and_write_file("file", size, size);
  77. TEST_CHECK(res >= 0);
  78. res = read_and_verify("file");
  79. TEST_CHECK(res >= 0);
  80. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  81. TEST_CHECK(fd > 0);
  82. spiffs_stat s;
  83. res = SPIFFS_fstat(FS, fd, &s);
  84. TEST_CHECK(res >= 0);
  85. SPIFFS_close(FS, fd);
  86. // modify object index, find object index header
  87. spiffs_page_ix pix;
  88. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  89. TEST_CHECK(res >= 0);
  90. // set object index entry 2 to a bad page
  91. u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 0 * sizeof(spiffs_page_ix);
  92. spiffs_page_ix bad_pix_ref = 0x55;
  93. area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
  94. area_write(addr+2, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
  95. // delete all cache
  96. #if SPIFFS_CACHE
  97. spiffs_cache *cache = spiffs_get_cache(FS);
  98. cache->cpage_use_map = 0;
  99. #endif
  100. SPIFFS_check(FS);
  101. res = read_and_verify("file");
  102. TEST_CHECK(res >= 0);
  103. return TEST_RES_OK;
  104. } TEST_END(page_cons1)
  105. TEST(page_cons2) {
  106. int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
  107. int res = test_create_and_write_file("file", size, size);
  108. TEST_CHECK(res >= 0);
  109. res = read_and_verify("file");
  110. TEST_CHECK(res >= 0);
  111. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  112. TEST_CHECK(fd > 0);
  113. spiffs_stat s;
  114. res = SPIFFS_fstat(FS, fd, &s);
  115. TEST_CHECK(res >= 0);
  116. SPIFFS_close(FS, fd);
  117. // modify object index, find object index header
  118. spiffs_page_ix pix;
  119. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  120. TEST_CHECK(res >= 0);
  121. // find data page span index 0
  122. spiffs_page_ix dpix;
  123. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &dpix);
  124. TEST_CHECK(res >= 0);
  125. // set object index entry 1+2 to a data page 0
  126. u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix);
  127. spiffs_page_ix bad_pix_ref = dpix;
  128. area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
  129. area_write(addr+sizeof(spiffs_page_ix), (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
  130. // delete all cache
  131. #if SPIFFS_CACHE
  132. spiffs_cache *cache = spiffs_get_cache(FS);
  133. cache->cpage_use_map = 0;
  134. #endif
  135. SPIFFS_check(FS);
  136. res = read_and_verify("file");
  137. TEST_CHECK(res >= 0);
  138. return TEST_RES_OK;
  139. } TEST_END(page_cons2)
  140. TEST(page_cons3) {
  141. int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
  142. int res = test_create_and_write_file("file", size, size);
  143. TEST_CHECK(res >= 0);
  144. res = read_and_verify("file");
  145. TEST_CHECK(res >= 0);
  146. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  147. TEST_CHECK(fd > 0);
  148. spiffs_stat s;
  149. res = SPIFFS_fstat(FS, fd, &s);
  150. TEST_CHECK(res >= 0);
  151. SPIFFS_close(FS, fd);
  152. // modify object index, find object index header
  153. spiffs_page_ix pix;
  154. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  155. TEST_CHECK(res >= 0);
  156. // set object index entry 1+2 lookup page
  157. u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix);
  158. spiffs_page_ix bad_pix_ref = SPIFFS_PAGES_PER_BLOCK(FS) * (*FS.block_count - 2);
  159. area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
  160. area_write(addr+sizeof(spiffs_page_ix), (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
  161. // delete all cache
  162. #if SPIFFS_CACHE
  163. spiffs_cache *cache = spiffs_get_cache(FS);
  164. cache->cpage_use_map = 0;
  165. #endif
  166. SPIFFS_check(FS);
  167. res = read_and_verify("file");
  168. TEST_CHECK(res >= 0);
  169. return TEST_RES_OK;
  170. } TEST_END(page_cons3)
  171. TEST(page_cons_final) {
  172. int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
  173. int res = test_create_and_write_file("file", size, size);
  174. TEST_CHECK(res >= 0);
  175. res = read_and_verify("file");
  176. TEST_CHECK(res >= 0);
  177. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  178. TEST_CHECK(fd > 0);
  179. spiffs_stat s;
  180. res = SPIFFS_fstat(FS, fd, &s);
  181. TEST_CHECK(res >= 0);
  182. SPIFFS_close(FS, fd);
  183. // modify page header, make unfinalized
  184. spiffs_page_ix pix;
  185. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix);
  186. TEST_CHECK(res >= 0);
  187. // set page span ix 1 as unfinalized
  188. u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags);
  189. u8_t flags;
  190. area_read(addr, (u8_t*)&flags, 1);
  191. flags |= SPIFFS_PH_FLAG_FINAL;
  192. area_write(addr, (u8_t*)&flags, 1);
  193. // delete all cache
  194. #if SPIFFS_CACHE
  195. spiffs_cache *cache = spiffs_get_cache(FS);
  196. cache->cpage_use_map = 0;
  197. #endif
  198. SPIFFS_check(FS);
  199. res = read_and_verify("file");
  200. TEST_CHECK(res >= 0);
  201. return TEST_RES_OK;
  202. } TEST_END(page_cons_final)
  203. TEST(index_cons1) {
  204. int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
  205. int res = test_create_and_write_file("file", size, size);
  206. TEST_CHECK(res >= 0);
  207. res = read_and_verify("file");
  208. TEST_CHECK(res >= 0);
  209. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  210. TEST_CHECK(fd > 0);
  211. spiffs_stat s;
  212. res = SPIFFS_fstat(FS, fd, &s);
  213. TEST_CHECK(res >= 0);
  214. SPIFFS_close(FS, fd);
  215. // modify lu entry data page index header
  216. spiffs_page_ix pix;
  217. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  218. TEST_CHECK(res >= 0);
  219. printf(" deleting lu entry pix %04x\n", pix);
  220. // reset lu entry to being erased, but keep page data
  221. spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED;
  222. spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
  223. int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
  224. u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id);
  225. area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
  226. #if SPIFFS_CACHE
  227. spiffs_cache *cache = spiffs_get_cache(FS);
  228. cache->cpage_use_map = 0;
  229. #endif
  230. SPIFFS_check(FS);
  231. res = read_and_verify("file");
  232. TEST_CHECK(res >= 0);
  233. return TEST_RES_OK;
  234. } TEST_END(index_cons1)
  235. TEST(index_cons2) {
  236. int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
  237. int res = test_create_and_write_file("file", size, size);
  238. TEST_CHECK(res >= 0);
  239. res = read_and_verify("file");
  240. TEST_CHECK(res >= 0);
  241. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  242. TEST_CHECK(fd > 0);
  243. spiffs_stat s;
  244. res = SPIFFS_fstat(FS, fd, &s);
  245. TEST_CHECK(res >= 0);
  246. SPIFFS_close(FS, fd);
  247. // modify lu entry data page index header
  248. spiffs_page_ix pix;
  249. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  250. TEST_CHECK(res >= 0);
  251. printf(" writing lu entry for index page, ix %04x, as data page\n", pix);
  252. spiffs_obj_id obj_id = 0x1234;
  253. spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
  254. int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
  255. u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id);
  256. area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
  257. #if SPIFFS_CACHE
  258. spiffs_cache *cache = spiffs_get_cache(FS);
  259. cache->cpage_use_map = 0;
  260. #endif
  261. SPIFFS_check(FS);
  262. res = read_and_verify("file");
  263. TEST_CHECK(res >= 0);
  264. return TEST_RES_OK;
  265. } TEST_END(index_cons2)
  266. TEST(index_cons3) {
  267. int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
  268. int res = test_create_and_write_file("file", size, size);
  269. TEST_CHECK(res >= 0);
  270. res = read_and_verify("file");
  271. TEST_CHECK(res >= 0);
  272. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  273. TEST_CHECK(fd > 0);
  274. spiffs_stat s;
  275. res = SPIFFS_fstat(FS, fd, &s);
  276. TEST_CHECK(res >= 0);
  277. SPIFFS_close(FS, fd);
  278. // modify lu entry data page index header
  279. spiffs_page_ix pix;
  280. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  281. TEST_CHECK(res >= 0);
  282. printf(" setting lu entry pix %04x to another index page\n", pix);
  283. // reset lu entry to being erased, but keep page data
  284. spiffs_obj_id obj_id = 1234 | SPIFFS_OBJ_ID_IX_FLAG;
  285. spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
  286. int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
  287. u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id);
  288. area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
  289. #if SPIFFS_CACHE
  290. spiffs_cache *cache = spiffs_get_cache(FS);
  291. cache->cpage_use_map = 0;
  292. #endif
  293. SPIFFS_check(FS);
  294. res = read_and_verify("file");
  295. TEST_CHECK(res >= 0);
  296. return TEST_RES_OK;
  297. } TEST_END(index_cons3)
  298. TEST(index_cons4) {
  299. int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
  300. int res = test_create_and_write_file("file", size, size);
  301. TEST_CHECK(res >= 0);
  302. res = read_and_verify("file");
  303. TEST_CHECK(res >= 0);
  304. spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
  305. TEST_CHECK(fd > 0);
  306. spiffs_stat s;
  307. res = SPIFFS_fstat(FS, fd, &s);
  308. TEST_CHECK(res >= 0);
  309. SPIFFS_close(FS, fd);
  310. // modify lu entry data page index header, flags
  311. spiffs_page_ix pix;
  312. res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
  313. TEST_CHECK(res >= 0);
  314. printf(" cue objix hdr deletion in page %04x\n", pix);
  315. // set flags as deleting ix header
  316. u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags);
  317. u8_t flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE);
  318. area_write(addr, (u8_t*)&flags, 1);
  319. #if SPIFFS_CACHE
  320. spiffs_cache *cache = spiffs_get_cache(FS);
  321. cache->cpage_use_map = 0;
  322. #endif
  323. SPIFFS_check(FS);
  324. return TEST_RES_OK;
  325. } TEST_END(index_cons4)
  326. SUITE_END(check_tests)