libmtd_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. #include <fcntl.h>
  2. #include <stdarg.h>
  3. #include <setjmp.h>
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <sys/ioctl.h>
  11. #include <unistd.h>
  12. #include <cmocka.h>
  13. #include "mtd/mtd-user.h"
  14. #include "libmtd.h"
  15. #include "libmtd_int.h"
  16. #include "test_lib.h"
  17. static libmtd_t mock_libmtd_open()
  18. {
  19. /* create a mock object for libmtd, not using sysfs */
  20. expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 4);
  21. expect_close(4,0);
  22. libmtd_t lib = libmtd_open();
  23. assert_non_null(lib);
  24. return lib;
  25. }
  26. static void test_libmtd_open(void **state)
  27. {
  28. expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 4);
  29. expect_close(4,0);
  30. struct libmtd *lib = libmtd_open();
  31. assert_non_null(lib);
  32. assert_string_equal(lib->sysfs_mtd, SYSFS_ROOT "/class/mtd");
  33. assert_string_equal(lib->mtd, SYSFS_ROOT "/class/mtd/mtd%d");
  34. assert_string_equal(lib->mtd_name, SYSFS_ROOT "/class/mtd/mtd%d/name");
  35. assert_string_equal(lib->mtd_dev, SYSFS_ROOT "/class/mtd/mtd%d/dev");
  36. assert_string_equal(lib->mtd_type, SYSFS_ROOT "/class/mtd/mtd%d/type");
  37. assert_string_equal(lib->mtd_eb_size, SYSFS_ROOT "/class/mtd/mtd%d/erasesize");
  38. assert_string_equal(lib->mtd_size, SYSFS_ROOT "/class/mtd/mtd%d/size");
  39. assert_string_equal(lib->mtd_min_io_size, SYSFS_ROOT "/class/mtd/mtd%d/writesize");
  40. assert_string_equal(lib->mtd_subpage_size, SYSFS_ROOT "/class/mtd/mtd%d/subpagesize");
  41. assert_string_equal(lib->mtd_oob_size, SYSFS_ROOT "/class/mtd/mtd%d/oobsize");
  42. assert_string_equal(lib->mtd_oobavail, SYSFS_ROOT "/class/mtd/mtd%d/oobavail");
  43. assert_string_equal(lib->mtd_region_cnt, SYSFS_ROOT "/class/mtd/mtd%d/numeraseregions");
  44. assert_string_equal(lib->mtd_flags, SYSFS_ROOT "/class/mtd/mtd%d/flags");
  45. libmtd_close(lib);
  46. (void) state;
  47. }
  48. static void test_mtd_dev_present(void **state)
  49. {
  50. int ret;
  51. libmtd_t lib = mock_libmtd_open();
  52. ret = mtd_dev_present(lib, 0);
  53. assert_int_equal(ret, 1);
  54. libmtd_close(lib);
  55. (void) state;
  56. }
  57. static void test_mtd_mark_bad(void **state)
  58. {
  59. struct mtd_dev_info mtd;
  60. loff_t seek;
  61. int eb = 12;
  62. memset(&mtd, 0, sizeof(mtd));
  63. mtd.bb_allowed = 1;
  64. mtd.eb_cnt = 1024;
  65. mtd.eb_size = 128;
  66. seek = (loff_t)eb * mtd.eb_size;
  67. expect_ioctl(MEMSETBADBLOCK, 0, &seek);
  68. int r = mtd_mark_bad(&mtd, 4, eb);
  69. assert_int_equal(r, 0);
  70. (void) state;
  71. }
  72. static void test_mtd_is_bad(void **state)
  73. {
  74. struct mtd_dev_info mtd;
  75. loff_t seek;
  76. int eb = 0x42;
  77. memset(&mtd, 0, sizeof(mtd));
  78. mtd.bb_allowed = 1;
  79. mtd.eb_cnt = 1024;
  80. mtd.eb_size = 128;
  81. seek = (loff_t)eb * mtd.eb_size;
  82. expect_ioctl(MEMGETBADBLOCK, 0, &seek);
  83. int r = mtd_is_bad(&mtd, 4, eb);
  84. assert_int_equal(r, 0);
  85. (void) state;
  86. }
  87. static void test_mtd_lock(void **state)
  88. {
  89. int eb = 0xBA;
  90. struct mtd_dev_info mtd;
  91. memset(&mtd, 0, sizeof(mtd));
  92. mtd.bb_allowed = 1;
  93. mtd.eb_cnt = 1024;
  94. mtd.eb_size = 128;
  95. struct erase_info_user ei;
  96. memset(&ei, 0, sizeof(ei));
  97. ei.start = eb * mtd.eb_size;
  98. ei.length = mtd.eb_size;
  99. expect_ioctl(MEMLOCK, 0, &ei);
  100. int r = mtd_lock(&mtd, 4, eb);
  101. assert_int_equal(r, 0);
  102. (void) state;
  103. }
  104. static void test_mtd_unlock(void **state)
  105. {
  106. int eb = 0xBA;
  107. struct mtd_dev_info mtd;
  108. memset(&mtd, 0, sizeof(mtd));
  109. mtd.bb_allowed = 1;
  110. mtd.eb_cnt = 1024;
  111. mtd.eb_size = 128;
  112. struct erase_info_user ei;
  113. memset(&ei, 0, sizeof(ei));
  114. ei.start = eb * mtd.eb_size;
  115. ei.length = mtd.eb_size;
  116. expect_ioctl(MEMUNLOCK, 0, &ei);
  117. int r = mtd_unlock(&mtd, 4, eb);
  118. assert_int_equal(r, 0);
  119. (void) state;
  120. }
  121. static void test_mtd_is_locked(void **state)
  122. {
  123. int eb = 0xBA;
  124. struct mtd_dev_info mtd;
  125. memset(&mtd, 0, sizeof(mtd));
  126. mtd.bb_allowed = 1;
  127. mtd.eb_cnt = 1024;
  128. mtd.eb_size = 128;
  129. struct erase_info_user ei;
  130. memset(&ei, 0, sizeof(ei));
  131. ei.start = eb * mtd.eb_size;
  132. ei.length = mtd.eb_size;
  133. expect_ioctl(MEMISLOCKED, 0, &ei);
  134. int r = mtd_is_locked(&mtd, 4, eb);
  135. assert_int_equal(r, 0);
  136. (void) state;
  137. }
  138. static void test_mtd_regioninfo(void **state)
  139. {
  140. struct region_info_user req;
  141. struct region_info_user rr;
  142. memset(&req, 0, sizeof(req));
  143. memset(&rr, 0, sizeof(rr));
  144. int mock_fd = 4;
  145. int regidx = 0xAA;
  146. rr.regionindex = regidx;
  147. expect_ioctl(MEMGETREGIONINFO, 0, &rr);
  148. int r = mtd_regioninfo(mock_fd, regidx, &req);
  149. assert_int_equal(r, 0);
  150. (void) state;
  151. }
  152. static void test_mtd_erase_multi(void **state)
  153. {
  154. struct libmtd *lib = mock_libmtd_open();
  155. struct mtd_dev_info mtd;
  156. struct erase_info_user ei;
  157. struct erase_info_user64 ei64;
  158. int eb = 0x3C;
  159. int blocks = 3;
  160. memset(&ei, 0, sizeof(ei));
  161. memset(&ei64, 0, sizeof(ei64));
  162. memset(&mtd, 0, sizeof(mtd));
  163. mtd.bb_allowed = 1;
  164. mtd.eb_cnt = 1024;
  165. mtd.eb_size = 128;
  166. ei64.start = (uint64_t)eb * mtd.eb_size;
  167. ei64.length = (uint64_t)mtd.eb_size * blocks;
  168. ei.start = ei64.start;
  169. ei.length = ei64.length;
  170. /* non offs64 first */
  171. lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
  172. expect_ioctl(MEMERASE, 0, &ei);
  173. int r = mtd_erase_multi(lib, &mtd, 4, eb, blocks);
  174. assert_int_equal(r, 0);
  175. lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
  176. expect_ioctl(MEMERASE64, 0, &ei64);
  177. r = mtd_erase_multi(lib, &mtd, 4, eb, blocks);
  178. assert_int_equal(r, 0);
  179. libmtd_close(lib);
  180. (void) state;
  181. }
  182. /* this is the same as above but with blocks == 1 and a
  183. * different function call.
  184. * libmtd is mapping mtd_erase to mtd_erase_multi with 1 block
  185. */
  186. static void test_mtd_erase(void **state)
  187. {
  188. struct libmtd *lib = mock_libmtd_open();
  189. struct mtd_dev_info mtd;
  190. struct erase_info_user ei;
  191. struct erase_info_user64 ei64;
  192. int eb = 0x3C;
  193. int blocks = 1;
  194. memset(&ei, 0, sizeof(ei));
  195. memset(&ei64, 0, sizeof(ei64));
  196. memset(&mtd, 0, sizeof(mtd));
  197. mtd.bb_allowed = 1;
  198. mtd.eb_cnt = 1024;
  199. mtd.eb_size = 128;
  200. ei64.start = (uint64_t)eb * mtd.eb_size;
  201. ei64.length = (uint64_t)mtd.eb_size * blocks;
  202. ei.start = ei64.start;
  203. ei.length = ei64.length;
  204. /* non offs64 first */
  205. lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
  206. expect_ioctl(MEMERASE, 0, &ei);
  207. int r = mtd_erase(lib, &mtd, 4, eb);
  208. assert_int_equal(r, 0);
  209. lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
  210. expect_ioctl(MEMERASE64, 0, &ei64);
  211. r = mtd_erase(lib, &mtd, 4, eb);
  212. assert_int_equal(r, 0);
  213. libmtd_close(lib);
  214. (void) state;
  215. }
  216. static void test_mtd_read(void **state)
  217. {
  218. int mock_fd = 4;
  219. int eb = 0xE0;
  220. int offs = 43;
  221. int len = 28;
  222. off_t seek;
  223. char buf[28];
  224. struct mtd_dev_info mtd;
  225. memset(&mtd, 0, sizeof(mtd));
  226. mtd.bb_allowed = 1;
  227. mtd.eb_cnt = 1024;
  228. mtd.eb_size = 128;
  229. seek = (off_t)eb * mtd.eb_size + offs;
  230. expect_lseek(seek, SEEK_SET, seek);
  231. expect_read(len, len);
  232. int r = mtd_read(&mtd, mock_fd, eb, offs, &buf, len);
  233. assert_int_equal(r, 0);
  234. (void) state;
  235. }
  236. static void test_mtd_write_nooob(void **state)
  237. {
  238. struct libmtd *lib = mock_libmtd_open();
  239. int mock_fd = 4;
  240. int eb = 0xE0;
  241. int offs = 64;
  242. int len = 64;
  243. off_t seek;
  244. char buf[64];
  245. memset(buf, 0xAA, len);
  246. struct mtd_dev_info mtd;
  247. memset(&mtd, 0, sizeof(mtd));
  248. mtd.bb_allowed = 1;
  249. mtd.eb_cnt = 1024;
  250. mtd.eb_size = 128;
  251. mtd.subpage_size = 64;
  252. seek = (off_t)eb * mtd.eb_size + offs;
  253. expect_lseek(seek, SEEK_SET, seek);
  254. expect_write(buf, len, len);
  255. int r = mtd_write(lib, &mtd, mock_fd, eb, offs, buf, len, NULL, 0, 0);
  256. assert_int_equal(r, 0);
  257. libmtd_close(lib);
  258. (void)state;
  259. }
  260. static void test_mtd_write_withoob(void **state)
  261. {
  262. struct libmtd *lib = mock_libmtd_open();
  263. int mock_fd = 4;
  264. int eb = 0xE0;
  265. int offs = 64;
  266. int len = 64;
  267. int oob_len = 64;
  268. uint8_t mode = 3;
  269. off_t seek;
  270. char buf[64], oob_data[64];
  271. struct mtd_dev_info mtd;
  272. struct mtd_write_req req;
  273. memset(buf, 0xAA, len);
  274. memset(oob_data, 0xBA, oob_len);
  275. memset(&mtd, 0, sizeof(mtd));
  276. memset(&req, 0, sizeof(req));
  277. mtd.bb_allowed = 1;
  278. mtd.eb_cnt = 1024;
  279. mtd.eb_size = 128;
  280. mtd.subpage_size = 64;
  281. seek = (off_t)eb * mtd.eb_size + offs;
  282. req.start = seek;
  283. req.len = len;
  284. req.ooblen = oob_len;
  285. req.usr_data = (uint64_t)(unsigned long)buf;
  286. req.usr_oob = (uint64_t)(unsigned long)oob_data;
  287. req.mode = mode;
  288. expect_ioctl(MEMWRITE, 0, &req);
  289. int r = mtd_write(lib, &mtd, mock_fd, eb, offs, buf, len, oob_data, oob_len, mode);
  290. assert_int_equal(r, 0);
  291. libmtd_close(lib);
  292. (void) state;
  293. }
  294. static void test_mtd_read_oob(void **state)
  295. {
  296. struct libmtd *lib = mock_libmtd_open();
  297. struct mtd_dev_info mtd;
  298. struct mtd_oob_buf64 oob64;
  299. struct mtd_oob_buf oob;
  300. int mock_fd = 4;
  301. uint64_t start = 0, length = 64;
  302. char buf[64];
  303. memset(buf, 0xCD, 64);
  304. memset(&oob, 0, sizeof(oob));
  305. memset(&oob64, 0, sizeof(oob64));
  306. memset(&mtd, 0, sizeof(mtd));
  307. mtd.bb_allowed = 1;
  308. mtd.eb_cnt = 1024;
  309. mtd.eb_size = 128;
  310. mtd.subpage_size = 64;
  311. mtd.oob_size = 128;
  312. oob64.start = start;
  313. oob64.length = length;
  314. oob64.usr_ptr = (uint64_t)(unsigned long)buf;
  315. oob.start = oob64.start;
  316. oob.length = oob64.length;
  317. oob.ptr = buf;
  318. lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
  319. expect_ioctl(MEMREADOOB, 0, &oob);
  320. int r = mtd_read_oob(lib, &mtd, mock_fd, start, length, buf);
  321. assert_int_equal(r, 0);
  322. lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
  323. expect_ioctl(MEMREADOOB64, 0, &oob64);
  324. r = mtd_read_oob(lib, &mtd, mock_fd, start, length, buf);
  325. assert_int_equal(r, 0);
  326. libmtd_close(lib);
  327. (void) state;
  328. }
  329. /* basically the same as above but write calls */
  330. static void test_mtd_write_oob(void **state)
  331. {
  332. struct libmtd *lib = mock_libmtd_open();
  333. struct mtd_dev_info mtd;
  334. struct mtd_oob_buf64 oob64;
  335. struct mtd_oob_buf oob;
  336. int mock_fd = 4;
  337. uint64_t start = 0, length = 64;
  338. char buf[64];
  339. memset(buf, 0xCD, 64);
  340. memset(&oob, 0, sizeof(oob));
  341. memset(&oob64, 0, sizeof(oob64));
  342. memset(&mtd, 0, sizeof(mtd));
  343. mtd.bb_allowed = 1;
  344. mtd.eb_cnt = 1024;
  345. mtd.eb_size = 128;
  346. mtd.subpage_size = 64;
  347. mtd.oob_size = 128;
  348. oob64.start = start;
  349. oob64.length = length;
  350. oob64.usr_ptr = (uint64_t)(unsigned long)buf;
  351. oob.start = oob64.start;
  352. oob.length = oob64.length;
  353. oob.ptr = buf;
  354. lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
  355. expect_ioctl(MEMWRITEOOB, 0, &oob);
  356. int r = mtd_write_oob(lib, &mtd, mock_fd, start, length, buf);
  357. assert_int_equal(r, 0);
  358. lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
  359. expect_ioctl(MEMWRITEOOB64, 0, &oob64);
  360. r = mtd_write_oob(lib, &mtd, mock_fd, start, length, buf);
  361. assert_int_equal(r, 0);
  362. libmtd_close(lib);
  363. (void)state;
  364. }
  365. static void test_mtd_get_info(void **state)
  366. {
  367. struct libmtd *lib = mock_libmtd_open();
  368. struct mtd_info info;
  369. memset(&info, 0, sizeof(info));
  370. int r = mtd_get_info(lib, &info);
  371. assert_int_equal(info.sysfs_supported, 1);
  372. assert_int_equal(info.highest_mtd_num, 0);
  373. assert_int_equal(info.lowest_mtd_num, 0);
  374. assert_int_equal(info.mtd_dev_cnt, 1);
  375. assert_int_equal(r, 0);
  376. libmtd_close(lib);
  377. (void)state;
  378. }
  379. static void test_mtd_get_dev_info1(void **state)
  380. {
  381. struct libmtd *lib = mock_libmtd_open();
  382. struct mtd_dev_info info;
  383. int dev_num = 0;
  384. memset(&info, 0, sizeof(info));
  385. expect_open(SYSFS_ROOT "/class/mtd/mtd0/dev", O_RDONLY, 0);
  386. expect_read_real(50,0);
  387. expect_read(1,0);
  388. expect_close(3,1);
  389. expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 0);
  390. expect_read_real(128,0);
  391. expect_read(1,0);
  392. expect_close(3,1);
  393. expect_open(SYSFS_ROOT "/class/mtd/mtd0/type", O_RDONLY, 4);
  394. expect_read(65,0);
  395. expect_read(1,0);
  396. expect_close(4,0);
  397. expect_open(SYSFS_ROOT "/class/mtd/mtd0/erasesize", O_RDONLY, 0);
  398. expect_read_real(50, 0);
  399. expect_close(3,1);
  400. expect_open(SYSFS_ROOT "/class/mtd/mtd0/size", O_RDONLY, 0);
  401. expect_read_real(50,0);
  402. expect_close(3,1);
  403. expect_open(SYSFS_ROOT "/class/mtd/mtd0/writesize", O_RDONLY, 0);
  404. expect_read_real(50,0);
  405. expect_close(3,1);
  406. expect_open(SYSFS_ROOT "/class/mtd/mtd0/subpagesize", O_RDONLY, 0);
  407. expect_read_real(50,0);
  408. expect_close(3,1);
  409. expect_open(SYSFS_ROOT "/class/mtd/mtd0/oobsize", O_RDONLY, 0);
  410. expect_read_real(50,0);
  411. expect_close(3,1);
  412. expect_open(SYSFS_ROOT "/class/mtd/mtd0/oobavail", O_RDONLY, 0);
  413. expect_read_real(50,0);
  414. expect_close(3,1);
  415. expect_open(SYSFS_ROOT "/class/mtd/mtd0/numeraseregions", O_RDONLY, 0);
  416. expect_read_real(50,0);
  417. expect_close(3,1);
  418. expect_open(SYSFS_ROOT "/class/mtd/mtd0/flags", O_RDONLY, 0);
  419. expect_read_real(50,0);
  420. expect_close(3,1);
  421. int r = mtd_get_dev_info1(lib, dev_num, &info);
  422. assert_int_equal(r, 0);
  423. /* TODO check values */
  424. libmtd_close(lib);
  425. (void)state;
  426. }
  427. int main(void)
  428. {
  429. const struct CMUnitTest tests[] = {
  430. cmocka_unit_test(test_libmtd_open),
  431. cmocka_unit_test(test_mtd_is_bad),
  432. cmocka_unit_test(test_mtd_mark_bad),
  433. cmocka_unit_test(test_mtd_lock),
  434. cmocka_unit_test(test_mtd_unlock),
  435. cmocka_unit_test(test_mtd_is_locked),
  436. cmocka_unit_test(test_mtd_regioninfo),
  437. cmocka_unit_test(test_mtd_erase_multi),
  438. cmocka_unit_test(test_mtd_erase),
  439. cmocka_unit_test(test_mtd_read),
  440. cmocka_unit_test(test_mtd_write_nooob),
  441. cmocka_unit_test(test_mtd_write_withoob),
  442. cmocka_unit_test(test_mtd_read_oob),
  443. cmocka_unit_test(test_mtd_write_oob),
  444. cmocka_unit_test(test_mtd_dev_present),
  445. cmocka_unit_test(test_mtd_get_info),
  446. cmocka_unit_test(test_mtd_get_dev_info1),
  447. };
  448. return cmocka_run_group_tests(tests, NULL, NULL);
  449. }