119ea8026Sopenharmony_ci# Test for compatibility between different littlefs versions
219ea8026Sopenharmony_ci#
319ea8026Sopenharmony_ci# Note, these tests are a bit special. They expect to be linked against two
419ea8026Sopenharmony_ci# different versions of littlefs:
519ea8026Sopenharmony_ci# - lfs  => the new/current version of littlefs
619ea8026Sopenharmony_ci# - lfsp => the previous version of littlefs
719ea8026Sopenharmony_ci#
819ea8026Sopenharmony_ci# If lfsp is not linked, and LFSP is not defined, these tests will alias
919ea8026Sopenharmony_ci# the relevant lfs types/functions as necessary so at least the tests can
1019ea8026Sopenharmony_ci# themselves be tested locally.
1119ea8026Sopenharmony_ci#
1219ea8026Sopenharmony_ci# But to get value from these tests, it's expected that the previous version
1319ea8026Sopenharmony_ci# of littlefs be linked in during CI, with the help of scripts/changeprefix.py
1419ea8026Sopenharmony_ci#
1519ea8026Sopenharmony_ci
1619ea8026Sopenharmony_ci# alias littlefs symbols as needed
1719ea8026Sopenharmony_ci#
1819ea8026Sopenharmony_ci# there may be a better way to do this, but oh well, explicit aliases works
1919ea8026Sopenharmony_cicode = '''
2019ea8026Sopenharmony_ci#ifdef LFSP
2119ea8026Sopenharmony_ci#define STRINGIZE(x) STRINGIZE_(x)
2219ea8026Sopenharmony_ci#define STRINGIZE_(x) #x
2319ea8026Sopenharmony_ci#include STRINGIZE(LFSP)
2419ea8026Sopenharmony_ci#else
2519ea8026Sopenharmony_ci#define LFSP_DISK_VERSION LFS_DISK_VERSION
2619ea8026Sopenharmony_ci#define LFSP_DISK_VERSION_MAJOR LFS_DISK_VERSION_MAJOR
2719ea8026Sopenharmony_ci#define LFSP_DISK_VERSION_MINOR LFS_DISK_VERSION_MINOR
2819ea8026Sopenharmony_ci#define lfsp_t lfs_t
2919ea8026Sopenharmony_ci#define lfsp_config lfs_config
3019ea8026Sopenharmony_ci#define lfsp_format lfs_format
3119ea8026Sopenharmony_ci#define lfsp_mount lfs_mount
3219ea8026Sopenharmony_ci#define lfsp_unmount lfs_unmount
3319ea8026Sopenharmony_ci#define lfsp_fsinfo lfs_fsinfo
3419ea8026Sopenharmony_ci#define lfsp_fs_stat lfs_fs_stat
3519ea8026Sopenharmony_ci#define lfsp_dir_t lfs_dir_t
3619ea8026Sopenharmony_ci#define lfsp_info lfs_info
3719ea8026Sopenharmony_ci#define LFSP_TYPE_REG LFS_TYPE_REG
3819ea8026Sopenharmony_ci#define LFSP_TYPE_DIR LFS_TYPE_DIR
3919ea8026Sopenharmony_ci#define lfsp_mkdir lfs_mkdir
4019ea8026Sopenharmony_ci#define lfsp_dir_open lfs_dir_open
4119ea8026Sopenharmony_ci#define lfsp_dir_read lfs_dir_read
4219ea8026Sopenharmony_ci#define lfsp_dir_close lfs_dir_close
4319ea8026Sopenharmony_ci#define lfsp_file_t lfs_file_t
4419ea8026Sopenharmony_ci#define LFSP_O_RDONLY LFS_O_RDONLY
4519ea8026Sopenharmony_ci#define LFSP_O_WRONLY LFS_O_WRONLY
4619ea8026Sopenharmony_ci#define LFSP_O_CREAT LFS_O_CREAT
4719ea8026Sopenharmony_ci#define LFSP_O_EXCL LFS_O_EXCL
4819ea8026Sopenharmony_ci#define LFSP_SEEK_SET LFS_SEEK_SET
4919ea8026Sopenharmony_ci#define lfsp_file_open lfs_file_open
5019ea8026Sopenharmony_ci#define lfsp_file_write lfs_file_write
5119ea8026Sopenharmony_ci#define lfsp_file_read lfs_file_read
5219ea8026Sopenharmony_ci#define lfsp_file_seek lfs_file_seek
5319ea8026Sopenharmony_ci#define lfsp_file_close lfs_file_close
5419ea8026Sopenharmony_ci#endif
5519ea8026Sopenharmony_ci'''
5619ea8026Sopenharmony_ci
5719ea8026Sopenharmony_ci
5819ea8026Sopenharmony_ci
5919ea8026Sopenharmony_ci## forward-compatibility tests ##
6019ea8026Sopenharmony_ci
6119ea8026Sopenharmony_ci# test we can mount in a new version
6219ea8026Sopenharmony_ci[cases.test_compat_forward_mount]
6319ea8026Sopenharmony_ciif = '''
6419ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
6519ea8026Sopenharmony_ci        && DISK_VERSION == 0
6619ea8026Sopenharmony_ci'''
6719ea8026Sopenharmony_cicode = '''
6819ea8026Sopenharmony_ci    // create the previous version
6919ea8026Sopenharmony_ci    struct lfsp_config cfgp;
7019ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
7119ea8026Sopenharmony_ci    lfsp_t lfsp;
7219ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
7319ea8026Sopenharmony_ci
7419ea8026Sopenharmony_ci    // confirm the previous mount works
7519ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
7619ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
7719ea8026Sopenharmony_ci
7819ea8026Sopenharmony_ci
7919ea8026Sopenharmony_ci    // now test the new mount
8019ea8026Sopenharmony_ci    lfs_t lfs;
8119ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
8219ea8026Sopenharmony_ci
8319ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
8419ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
8519ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
8619ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
8719ea8026Sopenharmony_ci
8819ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
8919ea8026Sopenharmony_ci'''
9019ea8026Sopenharmony_ci
9119ea8026Sopenharmony_ci# test we can read dirs in a new version
9219ea8026Sopenharmony_ci[cases.test_compat_forward_read_dirs]
9319ea8026Sopenharmony_cidefines.COUNT = 5
9419ea8026Sopenharmony_ciif = '''
9519ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
9619ea8026Sopenharmony_ci        && DISK_VERSION == 0
9719ea8026Sopenharmony_ci'''
9819ea8026Sopenharmony_cicode = '''
9919ea8026Sopenharmony_ci    // create the previous version
10019ea8026Sopenharmony_ci    struct lfsp_config cfgp;
10119ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
10219ea8026Sopenharmony_ci    lfsp_t lfsp;
10319ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
10419ea8026Sopenharmony_ci
10519ea8026Sopenharmony_ci    // write COUNT dirs
10619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
10719ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
10819ea8026Sopenharmony_ci        char name[8];
10919ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
11019ea8026Sopenharmony_ci        lfsp_mkdir(&lfsp, name) => 0;
11119ea8026Sopenharmony_ci    }
11219ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
11319ea8026Sopenharmony_ci
11419ea8026Sopenharmony_ci
11519ea8026Sopenharmony_ci    // mount the new version
11619ea8026Sopenharmony_ci    lfs_t lfs;
11719ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
11819ea8026Sopenharmony_ci
11919ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
12019ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
12119ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
12219ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
12319ea8026Sopenharmony_ci
12419ea8026Sopenharmony_ci    // can we list the directories?
12519ea8026Sopenharmony_ci    lfs_dir_t dir;
12619ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "/") => 0;
12719ea8026Sopenharmony_ci    struct lfs_info info;
12819ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
12919ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
13019ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
13119ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
13219ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
13319ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
13419ea8026Sopenharmony_ci
13519ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
13619ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
13719ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
13819ea8026Sopenharmony_ci        char name[8];
13919ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
14019ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
14119ea8026Sopenharmony_ci    }
14219ea8026Sopenharmony_ci
14319ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
14419ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
14519ea8026Sopenharmony_ci
14619ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
14719ea8026Sopenharmony_ci'''
14819ea8026Sopenharmony_ci
14919ea8026Sopenharmony_ci# test we can read files in a new version
15019ea8026Sopenharmony_ci[cases.test_compat_forward_read_files]
15119ea8026Sopenharmony_cidefines.COUNT = 5
15219ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
15319ea8026Sopenharmony_cidefines.CHUNK = 4
15419ea8026Sopenharmony_ciif = '''
15519ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
15619ea8026Sopenharmony_ci        && DISK_VERSION == 0
15719ea8026Sopenharmony_ci'''
15819ea8026Sopenharmony_cicode = '''
15919ea8026Sopenharmony_ci    // create the previous version
16019ea8026Sopenharmony_ci    struct lfsp_config cfgp;
16119ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
16219ea8026Sopenharmony_ci    lfsp_t lfsp;
16319ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
16419ea8026Sopenharmony_ci
16519ea8026Sopenharmony_ci    // write COUNT files
16619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
16719ea8026Sopenharmony_ci    uint32_t prng = 42;
16819ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
16919ea8026Sopenharmony_ci        lfsp_file_t file;
17019ea8026Sopenharmony_ci        char name[8];
17119ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
17219ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name,
17319ea8026Sopenharmony_ci                LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
17419ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
17519ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
17619ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
17719ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
17819ea8026Sopenharmony_ci            }
17919ea8026Sopenharmony_ci
18019ea8026Sopenharmony_ci            lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
18119ea8026Sopenharmony_ci        }
18219ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
18319ea8026Sopenharmony_ci    }
18419ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
18519ea8026Sopenharmony_ci
18619ea8026Sopenharmony_ci
18719ea8026Sopenharmony_ci    // mount the new version
18819ea8026Sopenharmony_ci    lfs_t lfs;
18919ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
19019ea8026Sopenharmony_ci
19119ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
19219ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
19319ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
19419ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
19519ea8026Sopenharmony_ci
19619ea8026Sopenharmony_ci    // can we list the files?
19719ea8026Sopenharmony_ci    lfs_dir_t dir;
19819ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "/") => 0;
19919ea8026Sopenharmony_ci    struct lfs_info info;
20019ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
20119ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
20219ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
20319ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
20419ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
20519ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
20619ea8026Sopenharmony_ci
20719ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
20819ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
20919ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_REG);
21019ea8026Sopenharmony_ci        char name[8];
21119ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
21219ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
21319ea8026Sopenharmony_ci        assert(info.size == SIZE);
21419ea8026Sopenharmony_ci    }
21519ea8026Sopenharmony_ci
21619ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
21719ea8026Sopenharmony_ci
21819ea8026Sopenharmony_ci    // now can we read the files?
21919ea8026Sopenharmony_ci    prng = 42;
22019ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
22119ea8026Sopenharmony_ci        lfs_file_t file;
22219ea8026Sopenharmony_ci        char name[8];
22319ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
22419ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
22519ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
22619ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
22719ea8026Sopenharmony_ci            lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
22819ea8026Sopenharmony_ci
22919ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
23019ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
23119ea8026Sopenharmony_ci            }
23219ea8026Sopenharmony_ci        }
23319ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
23419ea8026Sopenharmony_ci    }
23519ea8026Sopenharmony_ci
23619ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
23719ea8026Sopenharmony_ci'''
23819ea8026Sopenharmony_ci
23919ea8026Sopenharmony_ci# test we can read files in dirs in a new version
24019ea8026Sopenharmony_ci[cases.test_compat_forward_read_files_in_dirs]
24119ea8026Sopenharmony_cidefines.COUNT = 5
24219ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
24319ea8026Sopenharmony_cidefines.CHUNK = 4
24419ea8026Sopenharmony_ciif = '''
24519ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
24619ea8026Sopenharmony_ci        && DISK_VERSION == 0
24719ea8026Sopenharmony_ci'''
24819ea8026Sopenharmony_cicode = '''
24919ea8026Sopenharmony_ci    // create the previous version
25019ea8026Sopenharmony_ci    struct lfsp_config cfgp;
25119ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
25219ea8026Sopenharmony_ci    lfsp_t lfsp;
25319ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
25419ea8026Sopenharmony_ci
25519ea8026Sopenharmony_ci    // write COUNT files+dirs
25619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
25719ea8026Sopenharmony_ci    uint32_t prng = 42;
25819ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
25919ea8026Sopenharmony_ci        char name[16];
26019ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
26119ea8026Sopenharmony_ci        lfsp_mkdir(&lfsp, name) => 0;
26219ea8026Sopenharmony_ci
26319ea8026Sopenharmony_ci        lfsp_file_t file;
26419ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
26519ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name,
26619ea8026Sopenharmony_ci                LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
26719ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
26819ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
26919ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
27019ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
27119ea8026Sopenharmony_ci            }
27219ea8026Sopenharmony_ci
27319ea8026Sopenharmony_ci            lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
27419ea8026Sopenharmony_ci        }
27519ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
27619ea8026Sopenharmony_ci    }
27719ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
27819ea8026Sopenharmony_ci
27919ea8026Sopenharmony_ci
28019ea8026Sopenharmony_ci    // mount the new version
28119ea8026Sopenharmony_ci    lfs_t lfs;
28219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
28319ea8026Sopenharmony_ci
28419ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
28519ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
28619ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
28719ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
28819ea8026Sopenharmony_ci
28919ea8026Sopenharmony_ci    // can we list the directories?
29019ea8026Sopenharmony_ci    lfs_dir_t dir;
29119ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "/") => 0;
29219ea8026Sopenharmony_ci    struct lfs_info info;
29319ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
29419ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
29519ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
29619ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
29719ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
29819ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
29919ea8026Sopenharmony_ci
30019ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
30119ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
30219ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
30319ea8026Sopenharmony_ci        char name[8];
30419ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
30519ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
30619ea8026Sopenharmony_ci    }
30719ea8026Sopenharmony_ci
30819ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
30919ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
31019ea8026Sopenharmony_ci
31119ea8026Sopenharmony_ci    // can we list the files?
31219ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
31319ea8026Sopenharmony_ci        char name[8];
31419ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
31519ea8026Sopenharmony_ci        lfs_dir_t dir;
31619ea8026Sopenharmony_ci        lfs_dir_open(&lfs, &dir, name) => 0;
31719ea8026Sopenharmony_ci        struct lfs_info info;
31819ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
31919ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
32019ea8026Sopenharmony_ci        assert(strcmp(info.name, ".") == 0);
32119ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
32219ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
32319ea8026Sopenharmony_ci        assert(strcmp(info.name, "..") == 0);
32419ea8026Sopenharmony_ci
32519ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
32619ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_REG);
32719ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
32819ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
32919ea8026Sopenharmony_ci        assert(info.size == SIZE);
33019ea8026Sopenharmony_ci
33119ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 0;
33219ea8026Sopenharmony_ci        lfs_dir_close(&lfs, &dir) => 0;
33319ea8026Sopenharmony_ci    }
33419ea8026Sopenharmony_ci
33519ea8026Sopenharmony_ci    // now can we read the files?
33619ea8026Sopenharmony_ci    prng = 42;
33719ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
33819ea8026Sopenharmony_ci        lfs_file_t file;
33919ea8026Sopenharmony_ci        char name[16];
34019ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
34119ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
34219ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
34319ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
34419ea8026Sopenharmony_ci            lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
34519ea8026Sopenharmony_ci
34619ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
34719ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
34819ea8026Sopenharmony_ci            }
34919ea8026Sopenharmony_ci        }
35019ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
35119ea8026Sopenharmony_ci    }
35219ea8026Sopenharmony_ci
35319ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
35419ea8026Sopenharmony_ci'''
35519ea8026Sopenharmony_ci
35619ea8026Sopenharmony_ci# test we can write dirs in a new version
35719ea8026Sopenharmony_ci[cases.test_compat_forward_write_dirs]
35819ea8026Sopenharmony_cidefines.COUNT = 10
35919ea8026Sopenharmony_ciif = '''
36019ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
36119ea8026Sopenharmony_ci        && DISK_VERSION == 0
36219ea8026Sopenharmony_ci'''
36319ea8026Sopenharmony_cicode = '''
36419ea8026Sopenharmony_ci    // create the previous version
36519ea8026Sopenharmony_ci    struct lfsp_config cfgp;
36619ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
36719ea8026Sopenharmony_ci    lfsp_t lfsp;
36819ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
36919ea8026Sopenharmony_ci
37019ea8026Sopenharmony_ci    // write COUNT/2 dirs
37119ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
37219ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT/2; i++) {
37319ea8026Sopenharmony_ci        char name[8];
37419ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
37519ea8026Sopenharmony_ci        lfsp_mkdir(&lfsp, name) => 0;
37619ea8026Sopenharmony_ci    }
37719ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
37819ea8026Sopenharmony_ci
37919ea8026Sopenharmony_ci
38019ea8026Sopenharmony_ci    // mount the new version
38119ea8026Sopenharmony_ci    lfs_t lfs;
38219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
38319ea8026Sopenharmony_ci
38419ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
38519ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
38619ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
38719ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
38819ea8026Sopenharmony_ci
38919ea8026Sopenharmony_ci    // write another COUNT/2 dirs
39019ea8026Sopenharmony_ci    for (lfs_size_t i = COUNT/2; i < COUNT; i++) {
39119ea8026Sopenharmony_ci        char name[8];
39219ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
39319ea8026Sopenharmony_ci        lfs_mkdir(&lfs, name) => 0;
39419ea8026Sopenharmony_ci    }
39519ea8026Sopenharmony_ci
39619ea8026Sopenharmony_ci    // can we list the directories?
39719ea8026Sopenharmony_ci    lfs_dir_t dir;
39819ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "/") => 0;
39919ea8026Sopenharmony_ci    struct lfs_info info;
40019ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
40119ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
40219ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
40319ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
40419ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
40519ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
40619ea8026Sopenharmony_ci
40719ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
40819ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
40919ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
41019ea8026Sopenharmony_ci        char name[8];
41119ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
41219ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
41319ea8026Sopenharmony_ci    }
41419ea8026Sopenharmony_ci
41519ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
41619ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
41719ea8026Sopenharmony_ci
41819ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
41919ea8026Sopenharmony_ci'''
42019ea8026Sopenharmony_ci
42119ea8026Sopenharmony_ci# test we can write files in a new version
42219ea8026Sopenharmony_ci[cases.test_compat_forward_write_files]
42319ea8026Sopenharmony_cidefines.COUNT = 5
42419ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
42519ea8026Sopenharmony_cidefines.CHUNK = 2
42619ea8026Sopenharmony_ciif = '''
42719ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
42819ea8026Sopenharmony_ci        && DISK_VERSION == 0
42919ea8026Sopenharmony_ci'''
43019ea8026Sopenharmony_cicode = '''
43119ea8026Sopenharmony_ci    // create the previous version
43219ea8026Sopenharmony_ci    struct lfsp_config cfgp;
43319ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
43419ea8026Sopenharmony_ci    lfsp_t lfsp;
43519ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
43619ea8026Sopenharmony_ci
43719ea8026Sopenharmony_ci    // write half COUNT files
43819ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
43919ea8026Sopenharmony_ci    uint32_t prng = 42;
44019ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
44119ea8026Sopenharmony_ci        // write half
44219ea8026Sopenharmony_ci        lfsp_file_t file;
44319ea8026Sopenharmony_ci        char name[8];
44419ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
44519ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name,
44619ea8026Sopenharmony_ci                LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
44719ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
44819ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
44919ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
45019ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
45119ea8026Sopenharmony_ci            }
45219ea8026Sopenharmony_ci
45319ea8026Sopenharmony_ci            lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
45419ea8026Sopenharmony_ci        }
45519ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
45619ea8026Sopenharmony_ci
45719ea8026Sopenharmony_ci        // skip the other half but keep our prng reproducible
45819ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
45919ea8026Sopenharmony_ci            TEST_PRNG(&prng);
46019ea8026Sopenharmony_ci        }
46119ea8026Sopenharmony_ci    }
46219ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
46319ea8026Sopenharmony_ci
46419ea8026Sopenharmony_ci
46519ea8026Sopenharmony_ci    // mount the new version
46619ea8026Sopenharmony_ci    lfs_t lfs;
46719ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
46819ea8026Sopenharmony_ci
46919ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
47019ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
47119ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
47219ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
47319ea8026Sopenharmony_ci
47419ea8026Sopenharmony_ci    // write half COUNT files
47519ea8026Sopenharmony_ci    prng = 42;
47619ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
47719ea8026Sopenharmony_ci        // skip half but keep our prng reproducible
47819ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j++) {
47919ea8026Sopenharmony_ci            TEST_PRNG(&prng);
48019ea8026Sopenharmony_ci        }
48119ea8026Sopenharmony_ci
48219ea8026Sopenharmony_ci        // write the other half
48319ea8026Sopenharmony_ci        lfs_file_t file;
48419ea8026Sopenharmony_ci        char name[8];
48519ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
48619ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name, LFS_O_WRONLY) => 0;
48719ea8026Sopenharmony_ci        lfs_file_seek(&lfs, &file, SIZE/2, LFS_SEEK_SET) => SIZE/2;
48819ea8026Sopenharmony_ci
48919ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
49019ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
49119ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
49219ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
49319ea8026Sopenharmony_ci            }
49419ea8026Sopenharmony_ci
49519ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
49619ea8026Sopenharmony_ci        }
49719ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
49819ea8026Sopenharmony_ci    }
49919ea8026Sopenharmony_ci
50019ea8026Sopenharmony_ci    // can we list the files?
50119ea8026Sopenharmony_ci    lfs_dir_t dir;
50219ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "/") => 0;
50319ea8026Sopenharmony_ci    struct lfs_info info;
50419ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
50519ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
50619ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
50719ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
50819ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
50919ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
51019ea8026Sopenharmony_ci
51119ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
51219ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
51319ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_REG);
51419ea8026Sopenharmony_ci        char name[8];
51519ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
51619ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
51719ea8026Sopenharmony_ci        assert(info.size == SIZE);
51819ea8026Sopenharmony_ci    }
51919ea8026Sopenharmony_ci
52019ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
52119ea8026Sopenharmony_ci
52219ea8026Sopenharmony_ci    // now can we read the files?
52319ea8026Sopenharmony_ci    prng = 42;
52419ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
52519ea8026Sopenharmony_ci        lfs_file_t file;
52619ea8026Sopenharmony_ci        char name[8];
52719ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
52819ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
52919ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
53019ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
53119ea8026Sopenharmony_ci            lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
53219ea8026Sopenharmony_ci
53319ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
53419ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
53519ea8026Sopenharmony_ci            }
53619ea8026Sopenharmony_ci        }
53719ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
53819ea8026Sopenharmony_ci    }
53919ea8026Sopenharmony_ci
54019ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
54119ea8026Sopenharmony_ci'''
54219ea8026Sopenharmony_ci
54319ea8026Sopenharmony_ci# test we can write files in dirs in a new version
54419ea8026Sopenharmony_ci[cases.test_compat_forward_write_files_in_dirs]
54519ea8026Sopenharmony_cidefines.COUNT = 5
54619ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
54719ea8026Sopenharmony_cidefines.CHUNK = 2
54819ea8026Sopenharmony_ciif = '''
54919ea8026Sopenharmony_ci    LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR
55019ea8026Sopenharmony_ci        && DISK_VERSION == 0
55119ea8026Sopenharmony_ci'''
55219ea8026Sopenharmony_cicode = '''
55319ea8026Sopenharmony_ci    // create the previous version
55419ea8026Sopenharmony_ci    struct lfsp_config cfgp;
55519ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
55619ea8026Sopenharmony_ci    lfsp_t lfsp;
55719ea8026Sopenharmony_ci    lfsp_format(&lfsp, &cfgp) => 0;
55819ea8026Sopenharmony_ci
55919ea8026Sopenharmony_ci    // write half COUNT files
56019ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
56119ea8026Sopenharmony_ci    uint32_t prng = 42;
56219ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
56319ea8026Sopenharmony_ci        char name[16];
56419ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
56519ea8026Sopenharmony_ci        lfsp_mkdir(&lfsp, name) => 0;
56619ea8026Sopenharmony_ci
56719ea8026Sopenharmony_ci        // write half
56819ea8026Sopenharmony_ci        lfsp_file_t file;
56919ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
57019ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name,
57119ea8026Sopenharmony_ci                LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
57219ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
57319ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
57419ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
57519ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
57619ea8026Sopenharmony_ci            }
57719ea8026Sopenharmony_ci
57819ea8026Sopenharmony_ci            lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
57919ea8026Sopenharmony_ci        }
58019ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
58119ea8026Sopenharmony_ci
58219ea8026Sopenharmony_ci        // skip the other half but keep our prng reproducible
58319ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
58419ea8026Sopenharmony_ci            TEST_PRNG(&prng);
58519ea8026Sopenharmony_ci        }
58619ea8026Sopenharmony_ci    }
58719ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
58819ea8026Sopenharmony_ci
58919ea8026Sopenharmony_ci
59019ea8026Sopenharmony_ci    // mount the new version
59119ea8026Sopenharmony_ci    lfs_t lfs;
59219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
59319ea8026Sopenharmony_ci
59419ea8026Sopenharmony_ci    // we should be able to read the version using lfs_fs_stat
59519ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
59619ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
59719ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFSP_DISK_VERSION);
59819ea8026Sopenharmony_ci
59919ea8026Sopenharmony_ci    // write half COUNT files
60019ea8026Sopenharmony_ci    prng = 42;
60119ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
60219ea8026Sopenharmony_ci        // skip half but keep our prng reproducible
60319ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j++) {
60419ea8026Sopenharmony_ci            TEST_PRNG(&prng);
60519ea8026Sopenharmony_ci        }
60619ea8026Sopenharmony_ci
60719ea8026Sopenharmony_ci        // write the other half
60819ea8026Sopenharmony_ci        lfs_file_t file;
60919ea8026Sopenharmony_ci        char name[16];
61019ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
61119ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name, LFS_O_WRONLY) => 0;
61219ea8026Sopenharmony_ci        lfs_file_seek(&lfs, &file, SIZE/2, LFS_SEEK_SET) => SIZE/2;
61319ea8026Sopenharmony_ci
61419ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
61519ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
61619ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
61719ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
61819ea8026Sopenharmony_ci            }
61919ea8026Sopenharmony_ci
62019ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
62119ea8026Sopenharmony_ci        }
62219ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
62319ea8026Sopenharmony_ci    }
62419ea8026Sopenharmony_ci
62519ea8026Sopenharmony_ci    // can we list the directories?
62619ea8026Sopenharmony_ci    lfs_dir_t dir;
62719ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "/") => 0;
62819ea8026Sopenharmony_ci    struct lfs_info info;
62919ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
63019ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
63119ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
63219ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
63319ea8026Sopenharmony_ci    assert(info.type == LFS_TYPE_DIR);
63419ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
63519ea8026Sopenharmony_ci
63619ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
63719ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
63819ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
63919ea8026Sopenharmony_ci        char name[8];
64019ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
64119ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
64219ea8026Sopenharmony_ci    }
64319ea8026Sopenharmony_ci
64419ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
64519ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
64619ea8026Sopenharmony_ci
64719ea8026Sopenharmony_ci    // can we list the files?
64819ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
64919ea8026Sopenharmony_ci        char name[8];
65019ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
65119ea8026Sopenharmony_ci        lfs_dir_t dir;
65219ea8026Sopenharmony_ci        lfs_dir_open(&lfs, &dir, name) => 0;
65319ea8026Sopenharmony_ci        struct lfs_info info;
65419ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
65519ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
65619ea8026Sopenharmony_ci        assert(strcmp(info.name, ".") == 0);
65719ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
65819ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_DIR);
65919ea8026Sopenharmony_ci        assert(strcmp(info.name, "..") == 0);
66019ea8026Sopenharmony_ci
66119ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
66219ea8026Sopenharmony_ci        assert(info.type == LFS_TYPE_REG);
66319ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
66419ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
66519ea8026Sopenharmony_ci        assert(info.size == SIZE);
66619ea8026Sopenharmony_ci
66719ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 0;
66819ea8026Sopenharmony_ci        lfs_dir_close(&lfs, &dir) => 0;
66919ea8026Sopenharmony_ci    }
67019ea8026Sopenharmony_ci
67119ea8026Sopenharmony_ci    // now can we read the files?
67219ea8026Sopenharmony_ci    prng = 42;
67319ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
67419ea8026Sopenharmony_ci        lfs_file_t file;
67519ea8026Sopenharmony_ci        char name[16];
67619ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
67719ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
67819ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
67919ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
68019ea8026Sopenharmony_ci            lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
68119ea8026Sopenharmony_ci
68219ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
68319ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
68419ea8026Sopenharmony_ci            }
68519ea8026Sopenharmony_ci        }
68619ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
68719ea8026Sopenharmony_ci    }
68819ea8026Sopenharmony_ci
68919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
69019ea8026Sopenharmony_ci'''
69119ea8026Sopenharmony_ci
69219ea8026Sopenharmony_ci
69319ea8026Sopenharmony_ci
69419ea8026Sopenharmony_ci## backwards-compatibility tests ##
69519ea8026Sopenharmony_ci
69619ea8026Sopenharmony_ci# test we can mount in an old version
69719ea8026Sopenharmony_ci[cases.test_compat_backward_mount]
69819ea8026Sopenharmony_ciif = '''
69919ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
70019ea8026Sopenharmony_ci        && DISK_VERSION == 0
70119ea8026Sopenharmony_ci'''
70219ea8026Sopenharmony_cicode = '''
70319ea8026Sopenharmony_ci    // create the new version
70419ea8026Sopenharmony_ci    lfs_t lfs;
70519ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
70619ea8026Sopenharmony_ci
70719ea8026Sopenharmony_ci    // confirm the new mount works
70819ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
70919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
71019ea8026Sopenharmony_ci
71119ea8026Sopenharmony_ci    // now test the previous mount
71219ea8026Sopenharmony_ci    struct lfsp_config cfgp;
71319ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
71419ea8026Sopenharmony_ci    lfsp_t lfsp;
71519ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
71619ea8026Sopenharmony_ci
71719ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
71819ea8026Sopenharmony_ci'''
71919ea8026Sopenharmony_ci
72019ea8026Sopenharmony_ci# test we can read dirs in an old version
72119ea8026Sopenharmony_ci[cases.test_compat_backward_read_dirs]
72219ea8026Sopenharmony_cidefines.COUNT = 5
72319ea8026Sopenharmony_ciif = '''
72419ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
72519ea8026Sopenharmony_ci        && DISK_VERSION == 0
72619ea8026Sopenharmony_ci'''
72719ea8026Sopenharmony_cicode = '''
72819ea8026Sopenharmony_ci    // create the new version
72919ea8026Sopenharmony_ci    lfs_t lfs;
73019ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
73119ea8026Sopenharmony_ci
73219ea8026Sopenharmony_ci    // write COUNT dirs
73319ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
73419ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
73519ea8026Sopenharmony_ci        char name[8];
73619ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
73719ea8026Sopenharmony_ci        lfs_mkdir(&lfs, name) => 0;
73819ea8026Sopenharmony_ci    }
73919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
74019ea8026Sopenharmony_ci
74119ea8026Sopenharmony_ci
74219ea8026Sopenharmony_ci    // mount the new version
74319ea8026Sopenharmony_ci    struct lfsp_config cfgp;
74419ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
74519ea8026Sopenharmony_ci    lfsp_t lfsp;
74619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
74719ea8026Sopenharmony_ci
74819ea8026Sopenharmony_ci    // can we list the directories?
74919ea8026Sopenharmony_ci    lfsp_dir_t dir;
75019ea8026Sopenharmony_ci    lfsp_dir_open(&lfsp, &dir, "/") => 0;
75119ea8026Sopenharmony_ci    struct lfsp_info info;
75219ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
75319ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
75419ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
75519ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
75619ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
75719ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
75819ea8026Sopenharmony_ci
75919ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
76019ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
76119ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
76219ea8026Sopenharmony_ci        char name[8];
76319ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
76419ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
76519ea8026Sopenharmony_ci    }
76619ea8026Sopenharmony_ci
76719ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 0;
76819ea8026Sopenharmony_ci    lfsp_dir_close(&lfsp, &dir) => 0;
76919ea8026Sopenharmony_ci
77019ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
77119ea8026Sopenharmony_ci'''
77219ea8026Sopenharmony_ci
77319ea8026Sopenharmony_ci# test we can read files in an old version
77419ea8026Sopenharmony_ci[cases.test_compat_backward_read_files]
77519ea8026Sopenharmony_cidefines.COUNT = 5
77619ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
77719ea8026Sopenharmony_cidefines.CHUNK = 4
77819ea8026Sopenharmony_ciif = '''
77919ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
78019ea8026Sopenharmony_ci        && DISK_VERSION == 0
78119ea8026Sopenharmony_ci'''
78219ea8026Sopenharmony_cicode = '''
78319ea8026Sopenharmony_ci    // create the new version
78419ea8026Sopenharmony_ci    lfs_t lfs;
78519ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
78619ea8026Sopenharmony_ci
78719ea8026Sopenharmony_ci    // write COUNT files
78819ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
78919ea8026Sopenharmony_ci    uint32_t prng = 42;
79019ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
79119ea8026Sopenharmony_ci        lfs_file_t file;
79219ea8026Sopenharmony_ci        char name[8];
79319ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
79419ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name,
79519ea8026Sopenharmony_ci                LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
79619ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
79719ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
79819ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
79919ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
80019ea8026Sopenharmony_ci            }
80119ea8026Sopenharmony_ci
80219ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
80319ea8026Sopenharmony_ci        }
80419ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
80519ea8026Sopenharmony_ci    }
80619ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
80719ea8026Sopenharmony_ci
80819ea8026Sopenharmony_ci
80919ea8026Sopenharmony_ci    // mount the previous version
81019ea8026Sopenharmony_ci    struct lfsp_config cfgp;
81119ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
81219ea8026Sopenharmony_ci    lfsp_t lfsp;
81319ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
81419ea8026Sopenharmony_ci
81519ea8026Sopenharmony_ci    // can we list the files?
81619ea8026Sopenharmony_ci    lfsp_dir_t dir;
81719ea8026Sopenharmony_ci    lfsp_dir_open(&lfsp, &dir, "/") => 0;
81819ea8026Sopenharmony_ci    struct lfsp_info info;
81919ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
82019ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
82119ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
82219ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
82319ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
82419ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
82519ea8026Sopenharmony_ci
82619ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
82719ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
82819ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_REG);
82919ea8026Sopenharmony_ci        char name[8];
83019ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
83119ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
83219ea8026Sopenharmony_ci        assert(info.size == SIZE);
83319ea8026Sopenharmony_ci    }
83419ea8026Sopenharmony_ci
83519ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 0;
83619ea8026Sopenharmony_ci
83719ea8026Sopenharmony_ci    // now can we read the files?
83819ea8026Sopenharmony_ci    prng = 42;
83919ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
84019ea8026Sopenharmony_ci        lfsp_file_t file;
84119ea8026Sopenharmony_ci        char name[8];
84219ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
84319ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
84419ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
84519ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
84619ea8026Sopenharmony_ci            lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
84719ea8026Sopenharmony_ci
84819ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
84919ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
85019ea8026Sopenharmony_ci            }
85119ea8026Sopenharmony_ci        }
85219ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
85319ea8026Sopenharmony_ci    }
85419ea8026Sopenharmony_ci
85519ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
85619ea8026Sopenharmony_ci'''
85719ea8026Sopenharmony_ci
85819ea8026Sopenharmony_ci# test we can read files in dirs in an old version
85919ea8026Sopenharmony_ci[cases.test_compat_backward_read_files_in_dirs]
86019ea8026Sopenharmony_cidefines.COUNT = 5
86119ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
86219ea8026Sopenharmony_cidefines.CHUNK = 4
86319ea8026Sopenharmony_ciif = '''
86419ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
86519ea8026Sopenharmony_ci        && DISK_VERSION == 0
86619ea8026Sopenharmony_ci'''
86719ea8026Sopenharmony_cicode = '''
86819ea8026Sopenharmony_ci    // create the new version
86919ea8026Sopenharmony_ci    lfs_t lfs;
87019ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
87119ea8026Sopenharmony_ci
87219ea8026Sopenharmony_ci    // write COUNT files+dirs
87319ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
87419ea8026Sopenharmony_ci    uint32_t prng = 42;
87519ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
87619ea8026Sopenharmony_ci        char name[16];
87719ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
87819ea8026Sopenharmony_ci        lfs_mkdir(&lfs, name) => 0;
87919ea8026Sopenharmony_ci
88019ea8026Sopenharmony_ci        lfs_file_t file;
88119ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
88219ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name,
88319ea8026Sopenharmony_ci                LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
88419ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
88519ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
88619ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
88719ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
88819ea8026Sopenharmony_ci            }
88919ea8026Sopenharmony_ci
89019ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
89119ea8026Sopenharmony_ci        }
89219ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
89319ea8026Sopenharmony_ci    }
89419ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
89519ea8026Sopenharmony_ci
89619ea8026Sopenharmony_ci
89719ea8026Sopenharmony_ci    // mount the previous version
89819ea8026Sopenharmony_ci    struct lfsp_config cfgp;
89919ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
90019ea8026Sopenharmony_ci    lfsp_t lfsp;
90119ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
90219ea8026Sopenharmony_ci
90319ea8026Sopenharmony_ci    // can we list the directories?
90419ea8026Sopenharmony_ci    lfsp_dir_t dir;
90519ea8026Sopenharmony_ci    lfsp_dir_open(&lfsp, &dir, "/") => 0;
90619ea8026Sopenharmony_ci    struct lfsp_info info;
90719ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
90819ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
90919ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
91019ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
91119ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
91219ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
91319ea8026Sopenharmony_ci
91419ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
91519ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
91619ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
91719ea8026Sopenharmony_ci        char name[8];
91819ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
91919ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
92019ea8026Sopenharmony_ci    }
92119ea8026Sopenharmony_ci
92219ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 0;
92319ea8026Sopenharmony_ci    lfsp_dir_close(&lfsp, &dir) => 0;
92419ea8026Sopenharmony_ci
92519ea8026Sopenharmony_ci    // can we list the files?
92619ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
92719ea8026Sopenharmony_ci        char name[8];
92819ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
92919ea8026Sopenharmony_ci        lfsp_dir_t dir;
93019ea8026Sopenharmony_ci        lfsp_dir_open(&lfsp, &dir, name) => 0;
93119ea8026Sopenharmony_ci        struct lfsp_info info;
93219ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
93319ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
93419ea8026Sopenharmony_ci        assert(strcmp(info.name, ".") == 0);
93519ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
93619ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
93719ea8026Sopenharmony_ci        assert(strcmp(info.name, "..") == 0);
93819ea8026Sopenharmony_ci
93919ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
94019ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_REG);
94119ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
94219ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
94319ea8026Sopenharmony_ci        assert(info.size == SIZE);
94419ea8026Sopenharmony_ci
94519ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 0;
94619ea8026Sopenharmony_ci        lfsp_dir_close(&lfsp, &dir) => 0;
94719ea8026Sopenharmony_ci    }
94819ea8026Sopenharmony_ci
94919ea8026Sopenharmony_ci    // now can we read the files?
95019ea8026Sopenharmony_ci    prng = 42;
95119ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
95219ea8026Sopenharmony_ci        lfsp_file_t file;
95319ea8026Sopenharmony_ci        char name[16];
95419ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
95519ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
95619ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
95719ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
95819ea8026Sopenharmony_ci            lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
95919ea8026Sopenharmony_ci
96019ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
96119ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
96219ea8026Sopenharmony_ci            }
96319ea8026Sopenharmony_ci        }
96419ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
96519ea8026Sopenharmony_ci    }
96619ea8026Sopenharmony_ci
96719ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
96819ea8026Sopenharmony_ci'''
96919ea8026Sopenharmony_ci
97019ea8026Sopenharmony_ci# test we can write dirs in an old version
97119ea8026Sopenharmony_ci[cases.test_compat_backward_write_dirs]
97219ea8026Sopenharmony_cidefines.COUNT = 10
97319ea8026Sopenharmony_ciif = '''
97419ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
97519ea8026Sopenharmony_ci        && DISK_VERSION == 0
97619ea8026Sopenharmony_ci'''
97719ea8026Sopenharmony_cicode = '''
97819ea8026Sopenharmony_ci    // create the new version
97919ea8026Sopenharmony_ci    lfs_t lfs;
98019ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
98119ea8026Sopenharmony_ci
98219ea8026Sopenharmony_ci    // write COUNT/2 dirs
98319ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
98419ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT/2; i++) {
98519ea8026Sopenharmony_ci        char name[8];
98619ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
98719ea8026Sopenharmony_ci        lfs_mkdir(&lfs, name) => 0;
98819ea8026Sopenharmony_ci    }
98919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
99019ea8026Sopenharmony_ci
99119ea8026Sopenharmony_ci
99219ea8026Sopenharmony_ci    // mount the previous version
99319ea8026Sopenharmony_ci    struct lfsp_config cfgp;
99419ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
99519ea8026Sopenharmony_ci    lfsp_t lfsp;
99619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
99719ea8026Sopenharmony_ci
99819ea8026Sopenharmony_ci    // write another COUNT/2 dirs
99919ea8026Sopenharmony_ci    for (lfs_size_t i = COUNT/2; i < COUNT; i++) {
100019ea8026Sopenharmony_ci        char name[8];
100119ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
100219ea8026Sopenharmony_ci        lfsp_mkdir(&lfsp, name) => 0;
100319ea8026Sopenharmony_ci    }
100419ea8026Sopenharmony_ci
100519ea8026Sopenharmony_ci    // can we list the directories?
100619ea8026Sopenharmony_ci    lfsp_dir_t dir;
100719ea8026Sopenharmony_ci    lfsp_dir_open(&lfsp, &dir, "/") => 0;
100819ea8026Sopenharmony_ci    struct lfsp_info info;
100919ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
101019ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
101119ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
101219ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
101319ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
101419ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
101519ea8026Sopenharmony_ci
101619ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
101719ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
101819ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
101919ea8026Sopenharmony_ci        char name[8];
102019ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
102119ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
102219ea8026Sopenharmony_ci    }
102319ea8026Sopenharmony_ci
102419ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 0;
102519ea8026Sopenharmony_ci    lfsp_dir_close(&lfsp, &dir) => 0;
102619ea8026Sopenharmony_ci
102719ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
102819ea8026Sopenharmony_ci'''
102919ea8026Sopenharmony_ci
103019ea8026Sopenharmony_ci# test we can write files in an old version
103119ea8026Sopenharmony_ci[cases.test_compat_backward_write_files]
103219ea8026Sopenharmony_cidefines.COUNT = 5
103319ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
103419ea8026Sopenharmony_cidefines.CHUNK = 2
103519ea8026Sopenharmony_ciif = '''
103619ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
103719ea8026Sopenharmony_ci        && DISK_VERSION == 0
103819ea8026Sopenharmony_ci'''
103919ea8026Sopenharmony_cicode = '''
104019ea8026Sopenharmony_ci    // create the previous version
104119ea8026Sopenharmony_ci    lfs_t lfs;
104219ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
104319ea8026Sopenharmony_ci
104419ea8026Sopenharmony_ci    // write half COUNT files
104519ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
104619ea8026Sopenharmony_ci    uint32_t prng = 42;
104719ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
104819ea8026Sopenharmony_ci        // write half
104919ea8026Sopenharmony_ci        lfs_file_t file;
105019ea8026Sopenharmony_ci        char name[8];
105119ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
105219ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name,
105319ea8026Sopenharmony_ci                LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
105419ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
105519ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
105619ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
105719ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
105819ea8026Sopenharmony_ci            }
105919ea8026Sopenharmony_ci
106019ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
106119ea8026Sopenharmony_ci        }
106219ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
106319ea8026Sopenharmony_ci
106419ea8026Sopenharmony_ci        // skip the other half but keep our prng reproducible
106519ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
106619ea8026Sopenharmony_ci            TEST_PRNG(&prng);
106719ea8026Sopenharmony_ci        }
106819ea8026Sopenharmony_ci    }
106919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
107019ea8026Sopenharmony_ci
107119ea8026Sopenharmony_ci
107219ea8026Sopenharmony_ci    // mount the new version
107319ea8026Sopenharmony_ci    struct lfsp_config cfgp;
107419ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
107519ea8026Sopenharmony_ci    lfsp_t lfsp;
107619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
107719ea8026Sopenharmony_ci
107819ea8026Sopenharmony_ci    // write half COUNT files
107919ea8026Sopenharmony_ci    prng = 42;
108019ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
108119ea8026Sopenharmony_ci        // skip half but keep our prng reproducible
108219ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j++) {
108319ea8026Sopenharmony_ci            TEST_PRNG(&prng);
108419ea8026Sopenharmony_ci        }
108519ea8026Sopenharmony_ci
108619ea8026Sopenharmony_ci        // write the other half
108719ea8026Sopenharmony_ci        lfsp_file_t file;
108819ea8026Sopenharmony_ci        char name[8];
108919ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
109019ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name, LFSP_O_WRONLY) => 0;
109119ea8026Sopenharmony_ci        lfsp_file_seek(&lfsp, &file, SIZE/2, LFSP_SEEK_SET) => SIZE/2;
109219ea8026Sopenharmony_ci
109319ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
109419ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
109519ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
109619ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
109719ea8026Sopenharmony_ci            }
109819ea8026Sopenharmony_ci
109919ea8026Sopenharmony_ci            lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
110019ea8026Sopenharmony_ci        }
110119ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
110219ea8026Sopenharmony_ci    }
110319ea8026Sopenharmony_ci
110419ea8026Sopenharmony_ci    // can we list the files?
110519ea8026Sopenharmony_ci    lfsp_dir_t dir;
110619ea8026Sopenharmony_ci    lfsp_dir_open(&lfsp, &dir, "/") => 0;
110719ea8026Sopenharmony_ci    struct lfsp_info info;
110819ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
110919ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
111019ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
111119ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
111219ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
111319ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
111419ea8026Sopenharmony_ci
111519ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
111619ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
111719ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_REG);
111819ea8026Sopenharmony_ci        char name[8];
111919ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
112019ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
112119ea8026Sopenharmony_ci        assert(info.size == SIZE);
112219ea8026Sopenharmony_ci    }
112319ea8026Sopenharmony_ci
112419ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 0;
112519ea8026Sopenharmony_ci
112619ea8026Sopenharmony_ci    // now can we read the files?
112719ea8026Sopenharmony_ci    prng = 42;
112819ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
112919ea8026Sopenharmony_ci        lfsp_file_t file;
113019ea8026Sopenharmony_ci        char name[8];
113119ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
113219ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
113319ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
113419ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
113519ea8026Sopenharmony_ci            lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
113619ea8026Sopenharmony_ci
113719ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
113819ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
113919ea8026Sopenharmony_ci            }
114019ea8026Sopenharmony_ci        }
114119ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
114219ea8026Sopenharmony_ci    }
114319ea8026Sopenharmony_ci
114419ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
114519ea8026Sopenharmony_ci'''
114619ea8026Sopenharmony_ci
114719ea8026Sopenharmony_ci# test we can write files in dirs in an old version
114819ea8026Sopenharmony_ci[cases.test_compat_backward_write_files_in_dirs]
114919ea8026Sopenharmony_cidefines.COUNT = 5
115019ea8026Sopenharmony_cidefines.SIZE = [4, 32, 512, 8192]
115119ea8026Sopenharmony_cidefines.CHUNK = 2
115219ea8026Sopenharmony_ciif = '''
115319ea8026Sopenharmony_ci    LFS_DISK_VERSION == LFSP_DISK_VERSION
115419ea8026Sopenharmony_ci        && DISK_VERSION == 0
115519ea8026Sopenharmony_ci'''
115619ea8026Sopenharmony_cicode = '''
115719ea8026Sopenharmony_ci    // create the previous version
115819ea8026Sopenharmony_ci    lfs_t lfs;
115919ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
116019ea8026Sopenharmony_ci
116119ea8026Sopenharmony_ci    // write half COUNT files
116219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
116319ea8026Sopenharmony_ci    uint32_t prng = 42;
116419ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
116519ea8026Sopenharmony_ci        char name[16];
116619ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
116719ea8026Sopenharmony_ci        lfs_mkdir(&lfs, name) => 0;
116819ea8026Sopenharmony_ci
116919ea8026Sopenharmony_ci        // write half
117019ea8026Sopenharmony_ci        lfs_file_t file;
117119ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
117219ea8026Sopenharmony_ci        lfs_file_open(&lfs, &file, name,
117319ea8026Sopenharmony_ci                LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
117419ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
117519ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
117619ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
117719ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
117819ea8026Sopenharmony_ci            }
117919ea8026Sopenharmony_ci
118019ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
118119ea8026Sopenharmony_ci        }
118219ea8026Sopenharmony_ci        lfs_file_close(&lfs, &file) => 0;
118319ea8026Sopenharmony_ci
118419ea8026Sopenharmony_ci        // skip the other half but keep our prng reproducible
118519ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
118619ea8026Sopenharmony_ci            TEST_PRNG(&prng);
118719ea8026Sopenharmony_ci        }
118819ea8026Sopenharmony_ci    }
118919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
119019ea8026Sopenharmony_ci
119119ea8026Sopenharmony_ci
119219ea8026Sopenharmony_ci    // mount the new version
119319ea8026Sopenharmony_ci    struct lfsp_config cfgp;
119419ea8026Sopenharmony_ci    memcpy(&cfgp, cfg, sizeof(cfgp));
119519ea8026Sopenharmony_ci    lfsp_t lfsp;
119619ea8026Sopenharmony_ci    lfsp_mount(&lfsp, &cfgp) => 0;
119719ea8026Sopenharmony_ci
119819ea8026Sopenharmony_ci    // write half COUNT files
119919ea8026Sopenharmony_ci    prng = 42;
120019ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
120119ea8026Sopenharmony_ci        // skip half but keep our prng reproducible
120219ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE/2; j++) {
120319ea8026Sopenharmony_ci            TEST_PRNG(&prng);
120419ea8026Sopenharmony_ci        }
120519ea8026Sopenharmony_ci
120619ea8026Sopenharmony_ci        // write the other half
120719ea8026Sopenharmony_ci        lfsp_file_t file;
120819ea8026Sopenharmony_ci        char name[16];
120919ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
121019ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name, LFSP_O_WRONLY) => 0;
121119ea8026Sopenharmony_ci        lfsp_file_seek(&lfsp, &file, SIZE/2, LFSP_SEEK_SET) => SIZE/2;
121219ea8026Sopenharmony_ci
121319ea8026Sopenharmony_ci        for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
121419ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
121519ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
121619ea8026Sopenharmony_ci                chunk[k] = TEST_PRNG(&prng) & 0xff;
121719ea8026Sopenharmony_ci            }
121819ea8026Sopenharmony_ci
121919ea8026Sopenharmony_ci            lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
122019ea8026Sopenharmony_ci        }
122119ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
122219ea8026Sopenharmony_ci    }
122319ea8026Sopenharmony_ci
122419ea8026Sopenharmony_ci    // can we list the directories?
122519ea8026Sopenharmony_ci    lfsp_dir_t dir;
122619ea8026Sopenharmony_ci    lfsp_dir_open(&lfsp, &dir, "/") => 0;
122719ea8026Sopenharmony_ci    struct lfsp_info info;
122819ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
122919ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
123019ea8026Sopenharmony_ci    assert(strcmp(info.name, ".") == 0);
123119ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 1;
123219ea8026Sopenharmony_ci    assert(info.type == LFSP_TYPE_DIR);
123319ea8026Sopenharmony_ci    assert(strcmp(info.name, "..") == 0);
123419ea8026Sopenharmony_ci
123519ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
123619ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
123719ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
123819ea8026Sopenharmony_ci        char name[8];
123919ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
124019ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
124119ea8026Sopenharmony_ci    }
124219ea8026Sopenharmony_ci
124319ea8026Sopenharmony_ci    lfsp_dir_read(&lfsp, &dir, &info) => 0;
124419ea8026Sopenharmony_ci    lfsp_dir_close(&lfsp, &dir) => 0;
124519ea8026Sopenharmony_ci
124619ea8026Sopenharmony_ci    // can we list the files?
124719ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
124819ea8026Sopenharmony_ci        char name[8];
124919ea8026Sopenharmony_ci        sprintf(name, "dir%03d", i);
125019ea8026Sopenharmony_ci        lfsp_dir_t dir;
125119ea8026Sopenharmony_ci        lfsp_dir_open(&lfsp, &dir, name) => 0;
125219ea8026Sopenharmony_ci        struct lfsp_info info;
125319ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
125419ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
125519ea8026Sopenharmony_ci        assert(strcmp(info.name, ".") == 0);
125619ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
125719ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_DIR);
125819ea8026Sopenharmony_ci        assert(strcmp(info.name, "..") == 0);
125919ea8026Sopenharmony_ci
126019ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 1;
126119ea8026Sopenharmony_ci        assert(info.type == LFSP_TYPE_REG);
126219ea8026Sopenharmony_ci        sprintf(name, "file%03d", i);
126319ea8026Sopenharmony_ci        assert(strcmp(info.name, name) == 0);
126419ea8026Sopenharmony_ci        assert(info.size == SIZE);
126519ea8026Sopenharmony_ci
126619ea8026Sopenharmony_ci        lfsp_dir_read(&lfsp, &dir, &info) => 0;
126719ea8026Sopenharmony_ci        lfsp_dir_close(&lfsp, &dir) => 0;
126819ea8026Sopenharmony_ci    }
126919ea8026Sopenharmony_ci
127019ea8026Sopenharmony_ci    // now can we read the files?
127119ea8026Sopenharmony_ci    prng = 42;
127219ea8026Sopenharmony_ci    for (lfs_size_t i = 0; i < COUNT; i++) {
127319ea8026Sopenharmony_ci        lfsp_file_t file;
127419ea8026Sopenharmony_ci        char name[16];
127519ea8026Sopenharmony_ci        sprintf(name, "dir%03d/file%03d", i, i);
127619ea8026Sopenharmony_ci        lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
127719ea8026Sopenharmony_ci        for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
127819ea8026Sopenharmony_ci            uint8_t chunk[CHUNK];
127919ea8026Sopenharmony_ci            lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
128019ea8026Sopenharmony_ci
128119ea8026Sopenharmony_ci            for (lfs_size_t k = 0; k < CHUNK; k++) {
128219ea8026Sopenharmony_ci                assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
128319ea8026Sopenharmony_ci            }
128419ea8026Sopenharmony_ci        }
128519ea8026Sopenharmony_ci        lfsp_file_close(&lfsp, &file) => 0;
128619ea8026Sopenharmony_ci    }
128719ea8026Sopenharmony_ci
128819ea8026Sopenharmony_ci    lfsp_unmount(&lfsp) => 0;
128919ea8026Sopenharmony_ci'''
129019ea8026Sopenharmony_ci
129119ea8026Sopenharmony_ci
129219ea8026Sopenharmony_ci
129319ea8026Sopenharmony_ci## incompatiblity tests ##
129419ea8026Sopenharmony_ci
129519ea8026Sopenharmony_ci# test that we fail to mount after a major version bump
129619ea8026Sopenharmony_ci[cases.test_compat_major_incompat]
129719ea8026Sopenharmony_ciin = 'lfs.c'
129819ea8026Sopenharmony_cicode = '''
129919ea8026Sopenharmony_ci    // create a superblock
130019ea8026Sopenharmony_ci    lfs_t lfs;
130119ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
130219ea8026Sopenharmony_ci
130319ea8026Sopenharmony_ci    // bump the major version
130419ea8026Sopenharmony_ci    //
130519ea8026Sopenharmony_ci    // note we're messing around with internals to do this! this
130619ea8026Sopenharmony_ci    // is not a user API
130719ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
130819ea8026Sopenharmony_ci    lfs_mdir_t mdir;
130919ea8026Sopenharmony_ci    lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
131019ea8026Sopenharmony_ci    lfs_superblock_t superblock = {
131119ea8026Sopenharmony_ci        .version     = LFS_DISK_VERSION + 0x00010000,
131219ea8026Sopenharmony_ci        .block_size  = lfs.cfg->block_size,
131319ea8026Sopenharmony_ci        .block_count = lfs.cfg->block_count,
131419ea8026Sopenharmony_ci        .name_max    = lfs.name_max,
131519ea8026Sopenharmony_ci        .file_max    = lfs.file_max,
131619ea8026Sopenharmony_ci        .attr_max    = lfs.attr_max,
131719ea8026Sopenharmony_ci    };
131819ea8026Sopenharmony_ci    lfs_superblock_tole32(&superblock);
131919ea8026Sopenharmony_ci    lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
132019ea8026Sopenharmony_ci            {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
132119ea8026Sopenharmony_ci                &superblock})) => 0;
132219ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
132319ea8026Sopenharmony_ci
132419ea8026Sopenharmony_ci    // mount should now fail
132519ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
132619ea8026Sopenharmony_ci'''
132719ea8026Sopenharmony_ci
132819ea8026Sopenharmony_ci# test that we fail to mount after a minor version bump
132919ea8026Sopenharmony_ci[cases.test_compat_minor_incompat]
133019ea8026Sopenharmony_ciin = 'lfs.c'
133119ea8026Sopenharmony_cicode = '''
133219ea8026Sopenharmony_ci    // create a superblock
133319ea8026Sopenharmony_ci    lfs_t lfs;
133419ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
133519ea8026Sopenharmony_ci
133619ea8026Sopenharmony_ci    // bump the minor version
133719ea8026Sopenharmony_ci    //
133819ea8026Sopenharmony_ci    // note we're messing around with internals to do this! this
133919ea8026Sopenharmony_ci    // is not a user API
134019ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
134119ea8026Sopenharmony_ci    lfs_mdir_t mdir;
134219ea8026Sopenharmony_ci    lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
134319ea8026Sopenharmony_ci    lfs_superblock_t superblock = {
134419ea8026Sopenharmony_ci        .version     = LFS_DISK_VERSION + 0x00000001,
134519ea8026Sopenharmony_ci        .block_size  = lfs.cfg->block_size,
134619ea8026Sopenharmony_ci        .block_count = lfs.cfg->block_count,
134719ea8026Sopenharmony_ci        .name_max    = lfs.name_max,
134819ea8026Sopenharmony_ci        .file_max    = lfs.file_max,
134919ea8026Sopenharmony_ci        .attr_max    = lfs.attr_max,
135019ea8026Sopenharmony_ci    };
135119ea8026Sopenharmony_ci    lfs_superblock_tole32(&superblock);
135219ea8026Sopenharmony_ci    lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
135319ea8026Sopenharmony_ci            {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
135419ea8026Sopenharmony_ci                &superblock})) => 0;
135519ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
135619ea8026Sopenharmony_ci
135719ea8026Sopenharmony_ci    // mount should now fail
135819ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
135919ea8026Sopenharmony_ci'''
136019ea8026Sopenharmony_ci
136119ea8026Sopenharmony_ci# test that we correctly bump the minor version
136219ea8026Sopenharmony_ci[cases.test_compat_minor_bump]
136319ea8026Sopenharmony_ciin = 'lfs.c'
136419ea8026Sopenharmony_ciif = '''
136519ea8026Sopenharmony_ci    LFS_DISK_VERSION_MINOR > 0
136619ea8026Sopenharmony_ci        && DISK_VERSION == 0
136719ea8026Sopenharmony_ci'''
136819ea8026Sopenharmony_cicode = '''
136919ea8026Sopenharmony_ci    // create a superblock
137019ea8026Sopenharmony_ci    lfs_t lfs;
137119ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
137219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
137319ea8026Sopenharmony_ci    lfs_file_t file;
137419ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "test",
137519ea8026Sopenharmony_ci            LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
137619ea8026Sopenharmony_ci    lfs_file_write(&lfs, &file, "testtest", 8) => 8;
137719ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
137819ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
137919ea8026Sopenharmony_ci
138019ea8026Sopenharmony_ci    // write an old minor version
138119ea8026Sopenharmony_ci    //
138219ea8026Sopenharmony_ci    // note we're messing around with internals to do this! this
138319ea8026Sopenharmony_ci    // is not a user API
138419ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
138519ea8026Sopenharmony_ci    lfs_mdir_t mdir;
138619ea8026Sopenharmony_ci    lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
138719ea8026Sopenharmony_ci    lfs_superblock_t superblock = {
138819ea8026Sopenharmony_ci        .version     = LFS_DISK_VERSION - 0x00000001,
138919ea8026Sopenharmony_ci        .block_size  = lfs.cfg->block_size,
139019ea8026Sopenharmony_ci        .block_count = lfs.cfg->block_count,
139119ea8026Sopenharmony_ci        .name_max    = lfs.name_max,
139219ea8026Sopenharmony_ci        .file_max    = lfs.file_max,
139319ea8026Sopenharmony_ci        .attr_max    = lfs.attr_max,
139419ea8026Sopenharmony_ci    };
139519ea8026Sopenharmony_ci    lfs_superblock_tole32(&superblock);
139619ea8026Sopenharmony_ci    lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
139719ea8026Sopenharmony_ci            {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
139819ea8026Sopenharmony_ci                &superblock})) => 0;
139919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
140019ea8026Sopenharmony_ci
140119ea8026Sopenharmony_ci    // mount should still work
140219ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
140319ea8026Sopenharmony_ci
140419ea8026Sopenharmony_ci    struct lfs_fsinfo fsinfo;
140519ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
140619ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFS_DISK_VERSION-1);
140719ea8026Sopenharmony_ci
140819ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
140919ea8026Sopenharmony_ci    uint8_t buffer[8];
141019ea8026Sopenharmony_ci    lfs_file_read(&lfs, &file, buffer, 8) => 8;
141119ea8026Sopenharmony_ci    assert(memcmp(buffer, "testtest", 8) == 0);
141219ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
141319ea8026Sopenharmony_ci
141419ea8026Sopenharmony_ci    // minor version should be unchanged
141519ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
141619ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFS_DISK_VERSION-1);
141719ea8026Sopenharmony_ci
141819ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
141919ea8026Sopenharmony_ci
142019ea8026Sopenharmony_ci    // if we write, we need to bump the minor version
142119ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
142219ea8026Sopenharmony_ci
142319ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
142419ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFS_DISK_VERSION-1);
142519ea8026Sopenharmony_ci
142619ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "test", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
142719ea8026Sopenharmony_ci    lfs_file_write(&lfs, &file, "teeeeest", 8) => 8;
142819ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
142919ea8026Sopenharmony_ci
143019ea8026Sopenharmony_ci    // minor version should be changed
143119ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
143219ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFS_DISK_VERSION);
143319ea8026Sopenharmony_ci
143419ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
143519ea8026Sopenharmony_ci
143619ea8026Sopenharmony_ci    // and of course mount should still work
143719ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
143819ea8026Sopenharmony_ci
143919ea8026Sopenharmony_ci    // minor version should have changed
144019ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
144119ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFS_DISK_VERSION);
144219ea8026Sopenharmony_ci
144319ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
144419ea8026Sopenharmony_ci    lfs_file_read(&lfs, &file, buffer, 8) => 8;
144519ea8026Sopenharmony_ci    assert(memcmp(buffer, "teeeeest", 8) == 0);
144619ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
144719ea8026Sopenharmony_ci
144819ea8026Sopenharmony_ci    // yep, still changed
144919ea8026Sopenharmony_ci    lfs_fs_stat(&lfs, &fsinfo) => 0;
145019ea8026Sopenharmony_ci    assert(fsinfo.disk_version == LFS_DISK_VERSION);
145119ea8026Sopenharmony_ci
145219ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
145319ea8026Sopenharmony_ci'''
1454