| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- # 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.
- # only a revision count
- [cases.test_powerloss_only_rev]
- code = '''
- lfs_t lfs;
- lfs_format(&lfs, cfg) => 0;
- lfs_mount(&lfs, cfg) => 0;
- lfs_mkdir(&lfs, "notebook") => 0;
- lfs_file_t file;
- lfs_file_open(&lfs, &file, "notebook/paper",
- LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- char buffer[256];
- strcpy(buffer, "hello");
- lfs_size_t 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_t dir;
- 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[BLOCK_SIZE];
- cfg->read(cfg, pair[1], 0, bbuffer, 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, 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(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(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(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;
- '''
- # partial prog, may not be byte in order!
- [cases.test_powerloss_partial_prog]
- if = '''
- PROG_SIZE < BLOCK_SIZE
- && (DISK_VERSION == 0 || DISK_VERSION >= 0x00020001)
- '''
- defines.BYTE_OFF = ["0", "PROG_SIZE-1", "PROG_SIZE/2"]
- defines.BYTE_VALUE = [0x33, 0xcc]
- in = "lfs.c"
- code = '''
- lfs_t lfs;
- lfs_format(&lfs, cfg) => 0;
- lfs_mount(&lfs, cfg) => 0;
- lfs_mkdir(&lfs, "notebook") => 0;
- lfs_file_t file;
- lfs_file_open(&lfs, &file, "notebook/paper",
- LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- char buffer[256];
- strcpy(buffer, "hello");
- lfs_size_t 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_t dir;
- 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[BLOCK_SIZE];
- cfg->read(cfg, block, 0, bbuffer, BLOCK_SIZE) => 0;
- bbuffer[off + BYTE_OFF] = BYTE_VALUE;
- cfg->erase(cfg, block) => 0;
- cfg->prog(cfg, block, 0, bbuffer, 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(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(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(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;
- '''
|