# There are already a number of tests that test general operations under # power-loss (see the reentrant attribute). These tests are for explicitly # testing specific corner cases. [[case]] # only a revision count code = ''' lfs_format(&lfs, &cfg) => 0; lfs_mount(&lfs, &cfg) => 0; lfs_mkdir(&lfs, "notebook") => 0; lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; strcpy((char*)buffer, "hello"); size = strlen("hello"); for (int i = 0; i < 5; i++) { lfs_file_write(&lfs, &file, buffer, size) => size; lfs_file_sync(&lfs, &file) => 0; } lfs_file_close(&lfs, &file) => 0; char rbuffer[256]; lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0; for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } lfs_file_close(&lfs, &file) => 0; lfs_unmount(&lfs) => 0; // get pair/rev count lfs_mount(&lfs, &cfg) => 0; lfs_dir_open(&lfs, &dir, "notebook") => 0; lfs_block_t pair[2] = {dir.m.pair[0], dir.m.pair[1]}; uint32_t rev = dir.m.rev; lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; // write just the revision count uint8_t bbuffer[LFS_BLOCK_SIZE]; cfg.read(&cfg, pair[1], 0, bbuffer, LFS_BLOCK_SIZE) => 0; memcpy(bbuffer, &(uint32_t){lfs_tole32(rev+1)}, sizeof(uint32_t)); cfg.erase(&cfg, pair[1]) => 0; cfg.prog(&cfg, pair[1], 0, bbuffer, LFS_BLOCK_SIZE) => 0; lfs_mount(&lfs, &cfg) => 0; // can read? lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0; for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } lfs_file_close(&lfs, &file) => 0; // can write? lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_WRONLY | LFS_O_APPEND) => 0; strcpy((char*)buffer, "goodbye"); size = strlen("goodbye"); for (int i = 0; i < 5; i++) { lfs_file_write(&lfs, &file, buffer, size) => size; lfs_file_sync(&lfs, &file) => 0; } lfs_file_close(&lfs, &file) => 0; lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0; strcpy((char*)buffer, "hello"); size = strlen("hello"); for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } strcpy((char*)buffer, "goodbye"); size = strlen("goodbye"); for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } lfs_file_close(&lfs, &file) => 0; lfs_unmount(&lfs) => 0; ''' [[case]] # partial prog, may not be byte in order! define.BYTE_OFF = ["0", "LFS_PROG_SIZE-1", "LFS_PROG_SIZE/2"] define.BYTE_VALUE = [0x33, 0xcc] in = "lfs.c" code = ''' lfs_format(&lfs, &cfg) => 0; lfs_mount(&lfs, &cfg) => 0; lfs_mkdir(&lfs, "notebook") => 0; lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; strcpy((char*)buffer, "hello"); size = strlen("hello"); for (int i = 0; i < 5; i++) { lfs_file_write(&lfs, &file, buffer, size) => size; lfs_file_sync(&lfs, &file) => 0; } lfs_file_close(&lfs, &file) => 0; char rbuffer[256]; lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0; for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } lfs_file_close(&lfs, &file) => 0; lfs_unmount(&lfs) => 0; // imitate a partial prog, value should not matter, if littlefs // doesn't notice the partial prog testbd will assert // get offset to next prog lfs_mount(&lfs, &cfg) => 0; lfs_dir_open(&lfs, &dir, "notebook") => 0; lfs_block_t block = dir.m.pair[0]; lfs_off_t off = dir.m.off; lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; // tweak byte uint8_t bbuffer[LFS_BLOCK_SIZE]; cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; bbuffer[off + BYTE_OFF] = BYTE_VALUE; cfg.erase(&cfg, block) => 0; cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; lfs_mount(&lfs, &cfg) => 0; // can read? lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0; for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } lfs_file_close(&lfs, &file) => 0; // can write? lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_WRONLY | LFS_O_APPEND) => 0; strcpy((char*)buffer, "goodbye"); size = strlen("goodbye"); for (int i = 0; i < 5; i++) { lfs_file_write(&lfs, &file, buffer, size) => size; lfs_file_sync(&lfs, &file) => 0; } lfs_file_close(&lfs, &file) => 0; lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0; strcpy((char*)buffer, "hello"); size = strlen("hello"); for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } strcpy((char*)buffer, "goodbye"); size = strlen("goodbye"); for (int i = 0; i < 5; i++) { lfs_file_read(&lfs, &file, rbuffer, size) => size; assert(memcmp(rbuffer, buffer, size) == 0); } lfs_file_close(&lfs, &file) => 0; lfs_unmount(&lfs) => 0; '''