119ea8026Sopenharmony_ci# There are already a number of tests that test general operations under
219ea8026Sopenharmony_ci# power-loss (see the reentrant attribute). These tests are for explicitly
319ea8026Sopenharmony_ci# testing specific corner cases.
419ea8026Sopenharmony_ci
519ea8026Sopenharmony_ci# only a revision count
619ea8026Sopenharmony_ci[cases.test_powerloss_only_rev]
719ea8026Sopenharmony_cicode = '''
819ea8026Sopenharmony_ci    lfs_t lfs;
919ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
1019ea8026Sopenharmony_ci
1119ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
1219ea8026Sopenharmony_ci    lfs_mkdir(&lfs, "notebook") => 0;
1319ea8026Sopenharmony_ci    lfs_file_t file;
1419ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper",
1519ea8026Sopenharmony_ci            LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
1619ea8026Sopenharmony_ci    char buffer[256];
1719ea8026Sopenharmony_ci    strcpy(buffer, "hello");
1819ea8026Sopenharmony_ci    lfs_size_t size = strlen("hello");
1919ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
2019ea8026Sopenharmony_ci        lfs_file_write(&lfs, &file, buffer, size) => size;
2119ea8026Sopenharmony_ci        lfs_file_sync(&lfs, &file) => 0;
2219ea8026Sopenharmony_ci    }
2319ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
2419ea8026Sopenharmony_ci
2519ea8026Sopenharmony_ci    char rbuffer[256];
2619ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
2719ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
2819ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
2919ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
3019ea8026Sopenharmony_ci    }
3119ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
3219ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
3319ea8026Sopenharmony_ci
3419ea8026Sopenharmony_ci    // get pair/rev count
3519ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
3619ea8026Sopenharmony_ci    lfs_dir_t dir;
3719ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "notebook") => 0;
3819ea8026Sopenharmony_ci    lfs_block_t pair[2] = {dir.m.pair[0], dir.m.pair[1]};
3919ea8026Sopenharmony_ci    uint32_t rev = dir.m.rev;
4019ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
4119ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
4219ea8026Sopenharmony_ci
4319ea8026Sopenharmony_ci    // write just the revision count
4419ea8026Sopenharmony_ci    uint8_t bbuffer[BLOCK_SIZE];
4519ea8026Sopenharmony_ci    cfg->read(cfg, pair[1], 0, bbuffer, BLOCK_SIZE) => 0;
4619ea8026Sopenharmony_ci
4719ea8026Sopenharmony_ci    memcpy(bbuffer, &(uint32_t){lfs_tole32(rev+1)}, sizeof(uint32_t));
4819ea8026Sopenharmony_ci
4919ea8026Sopenharmony_ci    cfg->erase(cfg, pair[1]) => 0;
5019ea8026Sopenharmony_ci    cfg->prog(cfg, pair[1], 0, bbuffer, BLOCK_SIZE) => 0;
5119ea8026Sopenharmony_ci
5219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
5319ea8026Sopenharmony_ci
5419ea8026Sopenharmony_ci    // can read?
5519ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
5619ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
5719ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
5819ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
5919ea8026Sopenharmony_ci    }
6019ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
6119ea8026Sopenharmony_ci
6219ea8026Sopenharmony_ci    // can write?
6319ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper",
6419ea8026Sopenharmony_ci            LFS_O_WRONLY | LFS_O_APPEND) => 0;
6519ea8026Sopenharmony_ci    strcpy(buffer, "goodbye");
6619ea8026Sopenharmony_ci    size = strlen("goodbye");
6719ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
6819ea8026Sopenharmony_ci        lfs_file_write(&lfs, &file, buffer, size) => size;
6919ea8026Sopenharmony_ci        lfs_file_sync(&lfs, &file) => 0;
7019ea8026Sopenharmony_ci    }
7119ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
7219ea8026Sopenharmony_ci
7319ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
7419ea8026Sopenharmony_ci    strcpy(buffer, "hello");
7519ea8026Sopenharmony_ci    size = strlen("hello");
7619ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
7719ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
7819ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
7919ea8026Sopenharmony_ci    }
8019ea8026Sopenharmony_ci    strcpy(buffer, "goodbye");
8119ea8026Sopenharmony_ci    size = strlen("goodbye");
8219ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
8319ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
8419ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
8519ea8026Sopenharmony_ci    }
8619ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
8719ea8026Sopenharmony_ci
8819ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
8919ea8026Sopenharmony_ci'''
9019ea8026Sopenharmony_ci
9119ea8026Sopenharmony_ci# partial prog, may not be byte in order!
9219ea8026Sopenharmony_ci[cases.test_powerloss_partial_prog]
9319ea8026Sopenharmony_ciif = '''
9419ea8026Sopenharmony_ci    PROG_SIZE < BLOCK_SIZE
9519ea8026Sopenharmony_ci        && (DISK_VERSION == 0 || DISK_VERSION >= 0x00020001)
9619ea8026Sopenharmony_ci'''
9719ea8026Sopenharmony_cidefines.BYTE_OFF = ["0", "PROG_SIZE-1", "PROG_SIZE/2"]
9819ea8026Sopenharmony_cidefines.BYTE_VALUE = [0x33, 0xcc]
9919ea8026Sopenharmony_ciin = "lfs.c"
10019ea8026Sopenharmony_cicode = '''
10119ea8026Sopenharmony_ci    lfs_t lfs;
10219ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
10319ea8026Sopenharmony_ci
10419ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
10519ea8026Sopenharmony_ci    lfs_mkdir(&lfs, "notebook") => 0;
10619ea8026Sopenharmony_ci    lfs_file_t file;
10719ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper",
10819ea8026Sopenharmony_ci            LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
10919ea8026Sopenharmony_ci    char buffer[256];
11019ea8026Sopenharmony_ci    strcpy(buffer, "hello");
11119ea8026Sopenharmony_ci    lfs_size_t size = strlen("hello");
11219ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
11319ea8026Sopenharmony_ci        lfs_file_write(&lfs, &file, buffer, size) => size;
11419ea8026Sopenharmony_ci        lfs_file_sync(&lfs, &file) => 0;
11519ea8026Sopenharmony_ci    }
11619ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
11719ea8026Sopenharmony_ci
11819ea8026Sopenharmony_ci    char rbuffer[256];
11919ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
12019ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
12119ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
12219ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
12319ea8026Sopenharmony_ci    }
12419ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
12519ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
12619ea8026Sopenharmony_ci
12719ea8026Sopenharmony_ci    // imitate a partial prog, value should not matter, if littlefs
12819ea8026Sopenharmony_ci    // doesn't notice the partial prog testbd will assert
12919ea8026Sopenharmony_ci
13019ea8026Sopenharmony_ci    // get offset to next prog
13119ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
13219ea8026Sopenharmony_ci    lfs_dir_t dir;
13319ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "notebook") => 0;
13419ea8026Sopenharmony_ci    lfs_block_t block = dir.m.pair[0];
13519ea8026Sopenharmony_ci    lfs_off_t off = dir.m.off;
13619ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
13719ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
13819ea8026Sopenharmony_ci
13919ea8026Sopenharmony_ci    // tweak byte
14019ea8026Sopenharmony_ci    uint8_t bbuffer[BLOCK_SIZE];
14119ea8026Sopenharmony_ci    cfg->read(cfg, block, 0, bbuffer, BLOCK_SIZE) => 0;
14219ea8026Sopenharmony_ci
14319ea8026Sopenharmony_ci    bbuffer[off + BYTE_OFF] = BYTE_VALUE;
14419ea8026Sopenharmony_ci
14519ea8026Sopenharmony_ci    cfg->erase(cfg, block) => 0;
14619ea8026Sopenharmony_ci    cfg->prog(cfg, block, 0, bbuffer, BLOCK_SIZE) => 0;
14719ea8026Sopenharmony_ci
14819ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
14919ea8026Sopenharmony_ci
15019ea8026Sopenharmony_ci    // can read?
15119ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
15219ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
15319ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
15419ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
15519ea8026Sopenharmony_ci    }
15619ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
15719ea8026Sopenharmony_ci
15819ea8026Sopenharmony_ci    // can write?
15919ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper",
16019ea8026Sopenharmony_ci            LFS_O_WRONLY | LFS_O_APPEND) => 0;
16119ea8026Sopenharmony_ci    strcpy(buffer, "goodbye");
16219ea8026Sopenharmony_ci    size = strlen("goodbye");
16319ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
16419ea8026Sopenharmony_ci        lfs_file_write(&lfs, &file, buffer, size) => size;
16519ea8026Sopenharmony_ci        lfs_file_sync(&lfs, &file) => 0;
16619ea8026Sopenharmony_ci    }
16719ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
16819ea8026Sopenharmony_ci
16919ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
17019ea8026Sopenharmony_ci    strcpy(buffer, "hello");
17119ea8026Sopenharmony_ci    size = strlen("hello");
17219ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
17319ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
17419ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
17519ea8026Sopenharmony_ci    }
17619ea8026Sopenharmony_ci    strcpy(buffer, "goodbye");
17719ea8026Sopenharmony_ci    size = strlen("goodbye");
17819ea8026Sopenharmony_ci    for (int i = 0; i < 5; i++) {
17919ea8026Sopenharmony_ci        lfs_file_read(&lfs, &file, rbuffer, size) => size;
18019ea8026Sopenharmony_ci        assert(memcmp(rbuffer, buffer, size) == 0);
18119ea8026Sopenharmony_ci    }
18219ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
18319ea8026Sopenharmony_ci
18419ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
18519ea8026Sopenharmony_ci'''
186