| # simple formatting test |
| [cases.test_superblocks_format] |
| code = ''' |
| lfs_t lfs; |
| lfs_format(&lfs, cfg) => 0; |
| ''' |
| |
| # mount/unmount |
| [cases.test_superblocks_mount] |
| code = ''' |
| lfs_t lfs; |
| lfs_format(&lfs, cfg) => 0; |
| lfs_mount(&lfs, cfg) => 0; |
| lfs_unmount(&lfs) => 0; |
| ''' |
| |
| # reentrant format |
| [cases.test_superblocks_reentrant_format] |
| reentrant = true |
| code = ''' |
| lfs_t lfs; |
| int err = lfs_mount(&lfs, cfg); |
| if (err) { |
| lfs_format(&lfs, cfg) => 0; |
| lfs_mount(&lfs, cfg) => 0; |
| } |
| lfs_unmount(&lfs) => 0; |
| ''' |
| |
| # invalid mount |
| [cases.test_superblocks_invalid_mount] |
| code = ''' |
| lfs_t lfs; |
| lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT; |
| ''' |
| |
| # test we can read superblock info through lfs_fs_stat |
| [cases.test_superblocks_stat] |
| if = 'DISK_VERSION == 0' |
| code = ''' |
| lfs_t lfs; |
| lfs_format(&lfs, cfg) => 0; |
| |
| // test we can mount and read fsinfo |
| lfs_mount(&lfs, cfg) => 0; |
| |
| struct lfs_fsinfo fsinfo; |
| lfs_fs_stat(&lfs, &fsinfo) => 0; |
| assert(fsinfo.disk_version == LFS_DISK_VERSION); |
| assert(fsinfo.name_max == LFS_NAME_MAX); |
| assert(fsinfo.file_max == LFS_FILE_MAX); |
| assert(fsinfo.attr_max == LFS_ATTR_MAX); |
| |
| lfs_unmount(&lfs) => 0; |
| ''' |
| |
| [cases.test_superblocks_stat_tweaked] |
| if = 'DISK_VERSION == 0' |
| defines.TWEAKED_NAME_MAX = 63 |
| defines.TWEAKED_FILE_MAX = '(1 << 16)-1' |
| defines.TWEAKED_ATTR_MAX = 512 |
| code = ''' |
| // create filesystem with tweaked params |
| struct lfs_config tweaked_cfg = *cfg; |
| tweaked_cfg.name_max = TWEAKED_NAME_MAX; |
| tweaked_cfg.file_max = TWEAKED_FILE_MAX; |
| tweaked_cfg.attr_max = TWEAKED_ATTR_MAX; |
| |
| lfs_t lfs; |
| lfs_format(&lfs, &tweaked_cfg) => 0; |
| |
| // test we can mount and read these params with the original config |
| lfs_mount(&lfs, cfg) => 0; |
| |
| struct lfs_fsinfo fsinfo; |
| lfs_fs_stat(&lfs, &fsinfo) => 0; |
| assert(fsinfo.disk_version == LFS_DISK_VERSION); |
| assert(fsinfo.name_max == TWEAKED_NAME_MAX); |
| assert(fsinfo.file_max == TWEAKED_FILE_MAX); |
| assert(fsinfo.attr_max == TWEAKED_ATTR_MAX); |
| |
| lfs_unmount(&lfs) => 0; |
| ''' |
| |
| # expanding superblock |
| [cases.test_superblocks_expand] |
| defines.BLOCK_CYCLES = [32, 33, 1] |
| defines.N = [10, 100, 1000] |
| code = ''' |
| lfs_t lfs; |
| lfs_format(&lfs, cfg) => 0; |
| lfs_mount(&lfs, cfg) => 0; |
| for (int i = 0; i < N; i++) { |
| lfs_file_t file; |
| lfs_file_open(&lfs, &file, "dummy", |
| LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; |
| lfs_file_close(&lfs, &file) => 0; |
| struct lfs_info info; |
| lfs_stat(&lfs, "dummy", &info) => 0; |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_remove(&lfs, "dummy") => 0; |
| } |
| lfs_unmount(&lfs) => 0; |
| |
| // one last check after power-cycle |
| lfs_mount(&lfs, cfg) => 0; |
| lfs_file_t file; |
| lfs_file_open(&lfs, &file, "dummy", |
| LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; |
| lfs_file_close(&lfs, &file) => 0; |
| struct lfs_info info; |
| lfs_stat(&lfs, "dummy", &info) => 0; |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_unmount(&lfs) => 0; |
| ''' |
| |
| # expanding superblock with power cycle |
| [cases.test_superblocks_expand_power_cycle] |
| defines.BLOCK_CYCLES = [32, 33, 1] |
| defines.N = [10, 100, 1000] |
| code = ''' |
| lfs_t lfs; |
| lfs_format(&lfs, cfg) => 0; |
| for (int i = 0; i < N; i++) { |
| lfs_mount(&lfs, cfg) => 0; |
| // remove lingering dummy? |
| struct lfs_info info; |
| int err = lfs_stat(&lfs, "dummy", &info); |
| assert(err == 0 || (err == LFS_ERR_NOENT && i == 0)); |
| if (!err) { |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_remove(&lfs, "dummy") => 0; |
| } |
| |
| lfs_file_t file; |
| lfs_file_open(&lfs, &file, "dummy", |
| LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; |
| lfs_file_close(&lfs, &file) => 0; |
| lfs_stat(&lfs, "dummy", &info) => 0; |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_unmount(&lfs) => 0; |
| } |
| |
| // one last check after power-cycle |
| lfs_mount(&lfs, cfg) => 0; |
| struct lfs_info info; |
| lfs_stat(&lfs, "dummy", &info) => 0; |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_unmount(&lfs) => 0; |
| ''' |
| |
| # reentrant expanding superblock |
| [cases.test_superblocks_reentrant_expand] |
| defines.BLOCK_CYCLES = [2, 1] |
| defines.N = 24 |
| reentrant = true |
| code = ''' |
| lfs_t lfs; |
| int err = lfs_mount(&lfs, cfg); |
| if (err) { |
| lfs_format(&lfs, cfg) => 0; |
| lfs_mount(&lfs, cfg) => 0; |
| } |
| |
| for (int i = 0; i < N; i++) { |
| // remove lingering dummy? |
| struct lfs_info info; |
| err = lfs_stat(&lfs, "dummy", &info); |
| assert(err == 0 || (err == LFS_ERR_NOENT && i == 0)); |
| if (!err) { |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_remove(&lfs, "dummy") => 0; |
| } |
| |
| lfs_file_t file; |
| lfs_file_open(&lfs, &file, "dummy", |
| LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; |
| lfs_file_close(&lfs, &file) => 0; |
| lfs_stat(&lfs, "dummy", &info) => 0; |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| } |
| |
| lfs_unmount(&lfs) => 0; |
| |
| // one last check after power-cycle |
| lfs_mount(&lfs, cfg) => 0; |
| struct lfs_info info; |
| lfs_stat(&lfs, "dummy", &info) => 0; |
| assert(strcmp(info.name, "dummy") == 0); |
| assert(info.type == LFS_TYPE_REG); |
| lfs_unmount(&lfs) => 0; |
| ''' |