123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- #include <fcntl.h>
- #include <stdarg.h>
- #include <setjmp.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <cmocka.h>
- #include "mtd/mtd-user.h"
- #include "libmtd.h"
- #include "libmtd_int.h"
- #include "test_lib.h"
- static libmtd_t mock_libmtd_open()
- {
- /* create a mock object for libmtd, not using sysfs */
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 4);
- expect_close(4,0);
- libmtd_t lib = libmtd_open();
- assert_non_null(lib);
- return lib;
- }
- static void test_libmtd_open(void **state)
- {
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 4);
- expect_close(4,0);
- struct libmtd *lib = libmtd_open();
- assert_non_null(lib);
- assert_string_equal(lib->sysfs_mtd, SYSFS_ROOT "/class/mtd");
- assert_string_equal(lib->mtd, SYSFS_ROOT "/class/mtd/mtd%d");
- assert_string_equal(lib->mtd_name, SYSFS_ROOT "/class/mtd/mtd%d/name");
- assert_string_equal(lib->mtd_dev, SYSFS_ROOT "/class/mtd/mtd%d/dev");
- assert_string_equal(lib->mtd_type, SYSFS_ROOT "/class/mtd/mtd%d/type");
- assert_string_equal(lib->mtd_eb_size, SYSFS_ROOT "/class/mtd/mtd%d/erasesize");
- assert_string_equal(lib->mtd_size, SYSFS_ROOT "/class/mtd/mtd%d/size");
- assert_string_equal(lib->mtd_min_io_size, SYSFS_ROOT "/class/mtd/mtd%d/writesize");
- assert_string_equal(lib->mtd_subpage_size, SYSFS_ROOT "/class/mtd/mtd%d/subpagesize");
- assert_string_equal(lib->mtd_oob_size, SYSFS_ROOT "/class/mtd/mtd%d/oobsize");
- assert_string_equal(lib->mtd_oobavail, SYSFS_ROOT "/class/mtd/mtd%d/oobavail");
- assert_string_equal(lib->mtd_region_cnt, SYSFS_ROOT "/class/mtd/mtd%d/numeraseregions");
- assert_string_equal(lib->mtd_flags, SYSFS_ROOT "/class/mtd/mtd%d/flags");
- libmtd_close(lib);
- (void) state;
- }
- static void test_mtd_dev_present(void **state)
- {
- int ret;
- libmtd_t lib = mock_libmtd_open();
- ret = mtd_dev_present(lib, 0);
- assert_int_equal(ret, 1);
- libmtd_close(lib);
- (void) state;
- }
- static void test_mtd_mark_bad(void **state)
- {
- struct mtd_dev_info mtd;
- loff_t seek;
- int eb = 12;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- seek = (loff_t)eb * mtd.eb_size;
- expect_ioctl(MEMSETBADBLOCK, 0, &seek);
- int r = mtd_mark_bad(&mtd, 4, eb);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_is_bad(void **state)
- {
- struct mtd_dev_info mtd;
- loff_t seek;
- int eb = 0x42;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- seek = (loff_t)eb * mtd.eb_size;
- expect_ioctl(MEMGETBADBLOCK, 0, &seek);
- int r = mtd_is_bad(&mtd, 4, eb);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_lock(void **state)
- {
- int eb = 0xBA;
- struct mtd_dev_info mtd;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- struct erase_info_user ei;
- memset(&ei, 0, sizeof(ei));
- ei.start = eb * mtd.eb_size;
- ei.length = mtd.eb_size;
- expect_ioctl(MEMLOCK, 0, &ei);
- int r = mtd_lock(&mtd, 4, eb);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_unlock(void **state)
- {
- int eb = 0xBA;
- struct mtd_dev_info mtd;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- struct erase_info_user ei;
- memset(&ei, 0, sizeof(ei));
- ei.start = eb * mtd.eb_size;
- ei.length = mtd.eb_size;
- expect_ioctl(MEMUNLOCK, 0, &ei);
- int r = mtd_unlock(&mtd, 4, eb);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_is_locked(void **state)
- {
- int eb = 0xBA;
- struct mtd_dev_info mtd;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- struct erase_info_user ei;
- memset(&ei, 0, sizeof(ei));
- ei.start = eb * mtd.eb_size;
- ei.length = mtd.eb_size;
- expect_ioctl(MEMISLOCKED, 0, &ei);
- int r = mtd_is_locked(&mtd, 4, eb);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_regioninfo(void **state)
- {
- struct region_info_user req;
- struct region_info_user rr;
- memset(&req, 0, sizeof(req));
- memset(&rr, 0, sizeof(rr));
- int mock_fd = 4;
- int regidx = 0xAA;
- rr.regionindex = regidx;
- expect_ioctl(MEMGETREGIONINFO, 0, &rr);
- int r = mtd_regioninfo(mock_fd, regidx, &req);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_erase_multi(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- struct mtd_dev_info mtd;
- struct erase_info_user ei;
- struct erase_info_user64 ei64;
- int eb = 0x3C;
- int blocks = 3;
- memset(&ei, 0, sizeof(ei));
- memset(&ei64, 0, sizeof(ei64));
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- ei64.start = (uint64_t)eb * mtd.eb_size;
- ei64.length = (uint64_t)mtd.eb_size * blocks;
- ei.start = ei64.start;
- ei.length = ei64.length;
- /* non offs64 first */
- lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
- expect_ioctl(MEMERASE, 0, &ei);
- int r = mtd_erase_multi(lib, &mtd, 4, eb, blocks);
- assert_int_equal(r, 0);
- lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
- expect_ioctl(MEMERASE64, 0, &ei64);
- r = mtd_erase_multi(lib, &mtd, 4, eb, blocks);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void) state;
- }
- /* this is the same as above but with blocks == 1 and a
- * different function call.
- * libmtd is mapping mtd_erase to mtd_erase_multi with 1 block
- */
- static void test_mtd_erase(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- struct mtd_dev_info mtd;
- struct erase_info_user ei;
- struct erase_info_user64 ei64;
- int eb = 0x3C;
- int blocks = 1;
- memset(&ei, 0, sizeof(ei));
- memset(&ei64, 0, sizeof(ei64));
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- ei64.start = (uint64_t)eb * mtd.eb_size;
- ei64.length = (uint64_t)mtd.eb_size * blocks;
- ei.start = ei64.start;
- ei.length = ei64.length;
- /* non offs64 first */
- lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
- expect_ioctl(MEMERASE, 0, &ei);
- int r = mtd_erase(lib, &mtd, 4, eb);
- assert_int_equal(r, 0);
- lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
- expect_ioctl(MEMERASE64, 0, &ei64);
- r = mtd_erase(lib, &mtd, 4, eb);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void) state;
- }
- static void test_mtd_read(void **state)
- {
- int mock_fd = 4;
- int eb = 0xE0;
- int offs = 43;
- int len = 28;
- off_t seek;
- char buf[28];
- struct mtd_dev_info mtd;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- seek = (off_t)eb * mtd.eb_size + offs;
- expect_lseek(seek, SEEK_SET, seek);
- expect_read(len, len);
- int r = mtd_read(&mtd, mock_fd, eb, offs, &buf, len);
- assert_int_equal(r, 0);
- (void) state;
- }
- static void test_mtd_write_nooob(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- int mock_fd = 4;
- int eb = 0xE0;
- int offs = 64;
- int len = 64;
- off_t seek;
- char buf[64];
- memset(buf, 0xAA, len);
- struct mtd_dev_info mtd;
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- mtd.subpage_size = 64;
- seek = (off_t)eb * mtd.eb_size + offs;
- expect_lseek(seek, SEEK_SET, seek);
- expect_write(buf, len, len);
- int r = mtd_write(lib, &mtd, mock_fd, eb, offs, buf, len, NULL, 0, 0);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void)state;
- }
- static void test_mtd_write_withoob(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- int mock_fd = 4;
- int eb = 0xE0;
- int offs = 64;
- int len = 64;
- int oob_len = 64;
- uint8_t mode = 3;
- off_t seek;
- char buf[64], oob_data[64];
- struct mtd_dev_info mtd;
- struct mtd_write_req req;
- memset(buf, 0xAA, len);
- memset(oob_data, 0xBA, oob_len);
- memset(&mtd, 0, sizeof(mtd));
- memset(&req, 0, sizeof(req));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- mtd.subpage_size = 64;
- seek = (off_t)eb * mtd.eb_size + offs;
- req.start = seek;
- req.len = len;
- req.ooblen = oob_len;
- req.usr_data = (uint64_t)(unsigned long)buf;
- req.usr_oob = (uint64_t)(unsigned long)oob_data;
- req.mode = mode;
- expect_ioctl(MEMWRITE, 0, &req);
- int r = mtd_write(lib, &mtd, mock_fd, eb, offs, buf, len, oob_data, oob_len, mode);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void) state;
- }
- static void test_mtd_read_oob(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- struct mtd_dev_info mtd;
- struct mtd_oob_buf64 oob64;
- struct mtd_oob_buf oob;
- int mock_fd = 4;
- uint64_t start = 0, length = 64;
- char buf[64];
- memset(buf, 0xCD, 64);
- memset(&oob, 0, sizeof(oob));
- memset(&oob64, 0, sizeof(oob64));
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- mtd.subpage_size = 64;
- mtd.oob_size = 128;
- oob64.start = start;
- oob64.length = length;
- oob64.usr_ptr = (uint64_t)(unsigned long)buf;
- oob.start = oob64.start;
- oob.length = oob64.length;
- oob.ptr = buf;
- lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
- expect_ioctl(MEMREADOOB, 0, &oob);
- int r = mtd_read_oob(lib, &mtd, mock_fd, start, length, buf);
- assert_int_equal(r, 0);
- lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
- expect_ioctl(MEMREADOOB64, 0, &oob64);
- r = mtd_read_oob(lib, &mtd, mock_fd, start, length, buf);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void) state;
- }
- /* basically the same as above but write calls */
- static void test_mtd_write_oob(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- struct mtd_dev_info mtd;
- struct mtd_oob_buf64 oob64;
- struct mtd_oob_buf oob;
- int mock_fd = 4;
- uint64_t start = 0, length = 64;
- char buf[64];
- memset(buf, 0xCD, 64);
- memset(&oob, 0, sizeof(oob));
- memset(&oob64, 0, sizeof(oob64));
- memset(&mtd, 0, sizeof(mtd));
- mtd.bb_allowed = 1;
- mtd.eb_cnt = 1024;
- mtd.eb_size = 128;
- mtd.subpage_size = 64;
- mtd.oob_size = 128;
- oob64.start = start;
- oob64.length = length;
- oob64.usr_ptr = (uint64_t)(unsigned long)buf;
- oob.start = oob64.start;
- oob.length = oob64.length;
- oob.ptr = buf;
- lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED;
- expect_ioctl(MEMWRITEOOB, 0, &oob);
- int r = mtd_write_oob(lib, &mtd, mock_fd, start, length, buf);
- assert_int_equal(r, 0);
- lib->offs64_ioctls = OFFS64_IOCTLS_SUPPORTED;
- expect_ioctl(MEMWRITEOOB64, 0, &oob64);
- r = mtd_write_oob(lib, &mtd, mock_fd, start, length, buf);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void)state;
- }
- static void test_mtd_get_info(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- struct mtd_info info;
- memset(&info, 0, sizeof(info));
- int r = mtd_get_info(lib, &info);
- assert_int_equal(info.sysfs_supported, 1);
- assert_int_equal(info.highest_mtd_num, 0);
- assert_int_equal(info.lowest_mtd_num, 0);
- assert_int_equal(info.mtd_dev_cnt, 1);
- assert_int_equal(r, 0);
- libmtd_close(lib);
- (void)state;
- }
- static void test_mtd_get_dev_info1(void **state)
- {
- struct libmtd *lib = mock_libmtd_open();
- struct mtd_dev_info info;
- int dev_num = 0;
- memset(&info, 0, sizeof(info));
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/dev", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_read(1,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 0);
- expect_read_real(128,0);
- expect_read(1,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/type", O_RDONLY, 4);
- expect_read(65,0);
- expect_read(1,0);
- expect_close(4,0);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/erasesize", O_RDONLY, 0);
- expect_read_real(50, 0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/size", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/writesize", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/subpagesize", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/oobsize", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/oobavail", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/numeraseregions", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- expect_open(SYSFS_ROOT "/class/mtd/mtd0/flags", O_RDONLY, 0);
- expect_read_real(50,0);
- expect_close(3,1);
- int r = mtd_get_dev_info1(lib, dev_num, &info);
- assert_int_equal(r, 0);
- /* TODO check values */
- libmtd_close(lib);
- (void)state;
- }
- int main(void)
- {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_libmtd_open),
- cmocka_unit_test(test_mtd_is_bad),
- cmocka_unit_test(test_mtd_mark_bad),
- cmocka_unit_test(test_mtd_lock),
- cmocka_unit_test(test_mtd_unlock),
- cmocka_unit_test(test_mtd_is_locked),
- cmocka_unit_test(test_mtd_regioninfo),
- cmocka_unit_test(test_mtd_erase_multi),
- cmocka_unit_test(test_mtd_erase),
- cmocka_unit_test(test_mtd_read),
- cmocka_unit_test(test_mtd_write_nooob),
- cmocka_unit_test(test_mtd_write_withoob),
- cmocka_unit_test(test_mtd_read_oob),
- cmocka_unit_test(test_mtd_write_oob),
- cmocka_unit_test(test_mtd_dev_present),
- cmocka_unit_test(test_mtd_get_info),
- cmocka_unit_test(test_mtd_get_dev_info1),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
- }
|