53a4da13f5
In theory this is pretty much the same as lfsr_mkdir, but backwards. The main work was making the interactions between removing mids/rids and the grm correct. This ends up meaning we just need to update the grm on any mid/rid update the same way we update the list of opened mdirs. On the plus side, it turned out to be possible to deduplicate the mdir uninlining route a bit, by adding range argument to lfsr_mdir_commit_ and changing the write of the newly uninlined mtree/mdir to marking mtree as dirty and then joining the common path. This lets us move the pre-commit round of grm updates into a single location in lfsr_mdir_commit, removing and extra function definition and the related state marshalling while also simplifying the control-flow. This also raises the question, can more lfsr_mdir_commit be deduplicated more? Uninlining is a infrequent operation we don't really need to optimize for. --- Testing lfsr_remove also found a bug related to incorrect propagation of when the mroot becomes "unerased" (when rbyd overflows). This raises the concern that we're not propagating unerased-states very rigorously, and unexpected errors may not allow the filesystem to resume. This has never been in a very good place for littlefs, but would be worth improving in the future.
3114 lines
100 KiB
TOML
3114 lines
100 KiB
TOML
# Directory tests
|
|
|
|
|
|
## mkdir tests
|
|
|
|
[cases.t5_dirs_mkdir]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked with stat
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// and with dir_read
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that noent errors work
|
|
[cases.t5_dirs_noent]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to read a nonsense path
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "no", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "no") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that creating the same directory twice errors
|
|
[cases.t5_dirs_mkdir_exists]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// make the same directory, should error
|
|
lfsr_mkdir(&lfs, "ardvark") => LFS_ERR_EXIST;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test what happens if we try to make root
|
|
[cases.t5_dirs_mkdir_root]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// try to make root, which doesn't make sense
|
|
lfsr_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to make root, which doesn't make sense
|
|
lfsr_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that creating a directory with an invalid path errors
|
|
[cases.t5_dirs_mkdir_noent]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// make a nonsense directory, should error
|
|
lfsr_mkdir(&lfs, "no/hmm") => LFS_ERR_NOENT;
|
|
|
|
// make a nonsense child directory, should error
|
|
lfsr_mkdir(&lfs, "ardvark/no/hmm") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_siblings]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_children]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman/cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark/batman") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_backwards]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_2layers]
|
|
defines.N = [1, 2, 4, 8, 16]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// containing this many directories
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "child%04d", j);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", j);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_3layers]
|
|
defines.N = [1, 2, 4]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// containing this many directories
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// containing this many directories
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "child%04d", j);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "grandchild%04d", k);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
}
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", j);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char name[256];
|
|
sprintf(name, "grandchild%04d", k);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_linkedlist]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// create this many directory in a sort of linked-list by nesting
|
|
char name[4096];
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", i);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
if (i < N-1) {
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", i+1);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_fuzz]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
defines.SEED = 'range(10)'
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
if (PARENT) {
|
|
err = lfsr_mkdir(&lfs, "pricklypear");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
}
|
|
|
|
// set up a simulation to compare against
|
|
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
|
lfs_size_t sim_size = 0;
|
|
|
|
uint32_t prng = SEED;
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
// choose a pseudo-random number, truncate to 4 decimals
|
|
lfs_size_t x = TEST_PRNG(&prng) % 1000;
|
|
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen? skip
|
|
if (j < sim_size && sim[j] == x) {
|
|
goto next;
|
|
}
|
|
|
|
// insert
|
|
memmove(&sim[j+1], &sim[j],
|
|
(sim_size-j)*sizeof(lfs_size_t));
|
|
sim_size += 1;
|
|
sim[j] = x;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// create a directory here
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
next:;
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// test that our directories match our simulation
|
|
for (lfs_size_t j = 0; j < sim_size; j++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), sim[j]);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", sim[j]);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < sim_size; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", sim[j]);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// clean up sim/lfs
|
|
free(sim);
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
# test that did collisions don't cause issues
|
|
[cases.t5_dirs_did_collisions]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_SNmwMTHH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "b_skvjpWJH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "c_OnOQhVPH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "d_puMpPjRH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "e_LptKHkHH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "f_lUoVuhJH", 10) == 0x12345678);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_SNmwMTHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_skvjpWJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_OnOQhVPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_puMpPjRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_LptKHkHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_lUoVuhJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_SNmwMTHH", &info) => 0;
|
|
assert(strcmp(info.name, "a_SNmwMTHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_skvjpWJH", &info) => 0;
|
|
assert(strcmp(info.name, "b_skvjpWJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_OnOQhVPH", &info) => 0;
|
|
assert(strcmp(info.name, "c_OnOQhVPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_puMpPjRH", &info) => 0;
|
|
assert(strcmp(info.name, "d_puMpPjRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_LptKHkHH", &info) => 0;
|
|
assert(strcmp(info.name, "e_LptKHkHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_lUoVuhJH", &info) => 0;
|
|
assert(strcmp(info.name, "f_lUoVuhJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_SNmwMTHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_skvjpWJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_OnOQhVPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_puMpPjRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_LptKHkHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_lUoVuhJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# these will also collide with the root
|
|
[cases.t5_dirs_did_zero]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "b_iUwOsqRH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "c_UPNtkpHH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "d_jKLUSLJH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "e_VNunKMPH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "f_vknsvNRH", 10) == 0x00000000);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_IplRNrPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_iUwOsqRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_UPNtkpHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_jKLUSLJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_VNunKMPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_vknsvNRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_IplRNrPH", &info) => 0;
|
|
assert(strcmp(info.name, "a_IplRNrPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_iUwOsqRH", &info) => 0;
|
|
assert(strcmp(info.name, "b_iUwOsqRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_UPNtkpHH", &info) => 0;
|
|
assert(strcmp(info.name, "c_UPNtkpHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_jKLUSLJH", &info) => 0;
|
|
assert(strcmp(info.name, "d_jKLUSLJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_VNunKMPH", &info) => 0;
|
|
assert(strcmp(info.name, "e_VNunKMPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_vknsvNRH", &info) => 0;
|
|
assert(strcmp(info.name, "f_vknsvNRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_IplRNrPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_iUwOsqRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_UPNtkpHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_jKLUSLJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_VNunKMPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_vknsvNRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# these will need to rollover from 0xffffffff -> 0x00000000 correctly
|
|
#
|
|
# note this is true even if you truncate
|
|
[cases.t5_dirs_did_ones]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_iomlVKPH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "b_IJvqkHRH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "c_uOOJsIHH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "d_JTMkKuJH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "e_vQtPStPH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_iomlVKPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_IJvqkHRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_uOOJsIHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_JTMkKuJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_vQtPStPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_VtoMnwRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_iomlVKPH", &info) => 0;
|
|
assert(strcmp(info.name, "a_iomlVKPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_IJvqkHRH", &info) => 0;
|
|
assert(strcmp(info.name, "b_IJvqkHRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_uOOJsIHH", &info) => 0;
|
|
assert(strcmp(info.name, "c_uOOJsIHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_JTMkKuJH", &info) => 0;
|
|
assert(strcmp(info.name, "d_JTMkKuJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_vQtPStPH", &info) => 0;
|
|
assert(strcmp(info.name, "e_vQtPStPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_VtoMnwRH", &info) => 0;
|
|
assert(strcmp(info.name, "f_VtoMnwRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_iomlVKPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_IJvqkHRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_uOOJsIHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_JTMkKuJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_vQtPStPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_VtoMnwRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# these test some boundary conditions on the underlying leb128 encoding,
|
|
# if the leb128 disk-size is not calculated correctly these can cause
|
|
# issues
|
|
[cases.t5_dirs_did_leb128_boundaries]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_IOtUptRH", 10) == 0x0000007f);
|
|
assert(lfs_crc32c(0, "b_nquQsKHH", 10) == 0x00000080);
|
|
assert(lfs_crc32c(0, "c_vwQtKjHH", 10) == 0x00000081);
|
|
assert(lfs_crc32c(0, "d_sVrvrWHH", 10) == 0x00003fff);
|
|
assert(lfs_crc32c(0, "e_thrRIsRH", 10) == 0x00004000);
|
|
assert(lfs_crc32c(0, "f_pNtQTPJH", 10) == 0x00004001);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_IOtUptRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_nquQsKHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_vwQtKjHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_sVrvrWHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_thrRIsRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_pNtQTPJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_IOtUptRH", &info) => 0;
|
|
assert(strcmp(info.name, "a_IOtUptRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_nquQsKHH", &info) => 0;
|
|
assert(strcmp(info.name, "b_nquQsKHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_vwQtKjHH", &info) => 0;
|
|
assert(strcmp(info.name, "c_vwQtKjHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_sVrvrWHH", &info) => 0;
|
|
assert(strcmp(info.name, "d_sVrvrWHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_thrRIsRH", &info) => 0;
|
|
assert(strcmp(info.name, "e_thrRIsRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_pNtQTPJH", &info) => 0;
|
|
assert(strcmp(info.name, "f_pNtQTPJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_IOtUptRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_nquQsKHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_vwQtKjHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_sVrvrWHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_thrRIsRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_pNtQTPJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
## dir remove tests
|
|
|
|
[cases.t5_dirs_rm]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked with stat
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// and with dir_read
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// and remove the directory
|
|
lfsr_remove(&lfs, "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that remove worked with stat
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
|
|
// and with dir_read
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that noent errors work
|
|
[cases.t5_dirs_rm_noent]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to remove a nonsense directory
|
|
lfsr_remove(&lfs, "no") => LFS_ERR_NOENT;
|
|
|
|
// try to remove a directory in a nonsense directory
|
|
lfsr_remove(&lfs, "no/ardvark") => LFS_ERR_NOENT;
|
|
|
|
// try to remove a nonsense child directory
|
|
lfsr_remove(&lfs, "ardvark/no") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that we catch removing of a non-empty directory
|
|
[cases.t5_dirs_rm_notempty]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// fill it with stuff
|
|
err = lfsr_mkdir(&lfs, "ardvark/banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to remove the parent directory
|
|
lfsr_remove(&lfs, "ardvark") => LFS_ERR_NOTEMPTY;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
## TODO make this work eventually
|
|
#
|
|
## test what happens if we try to remove root
|
|
#[cases.t5_dirs_rm_root]
|
|
#defines.REMOUNT = [false, true]
|
|
#reentrant = true
|
|
#code = '''
|
|
# // format once per test
|
|
# lfs_t lfs;
|
|
# int err = lfsr_mount(&lfs, cfg);
|
|
# if (err) {
|
|
# lfsr_format(&lfs, cfg) => 0;
|
|
# lfsr_mount(&lfs, cfg) => 0;
|
|
# }
|
|
#
|
|
# // try to remove root, which doesn't really make sense
|
|
# lfsr_remove(&lfs, "/") => LFS_ERR_INVAL;
|
|
#
|
|
# // make a directory
|
|
# err = lfsr_mkdir(&lfs, "ardvark");
|
|
# assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
#
|
|
# // try to remove root, which doesn't really make sense
|
|
# //
|
|
# // it doesn't really matter which error returns first, so accept both
|
|
# err = lfsr_remove(&lfs, "/");
|
|
# assert(err == LFS_ERR_NOTEMPTY || err == LFS_ERR_INVAL);
|
|
#
|
|
# // remount?
|
|
# if (REMOUNT) {
|
|
# lfsr_unmount(&lfs) => 0;
|
|
# lfsr_mount(&lfs, cfg) => 0;
|
|
# // grm should be zero here
|
|
# assert(lfs.grm[0] == 0);
|
|
# }
|
|
#
|
|
# // and check that this didn't interfere with our original directory
|
|
# struct lfs_info info;
|
|
# lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
# assert(strcmp(info.name, "ardvark") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfsr_dir_t dir;
|
|
# lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
# assert(strcmp(info.name, "ardvark") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
# lfsr_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# lfsr_unmount(&lfs) => 0;
|
|
#'''
|
|
|
|
[cases.t5_dirs_rm_siblings]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove each directory
|
|
lfsr_remove(&lfs, "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "batman") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "cantaloupe") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_children]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman/cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark/batman") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove each directory
|
|
lfsr_remove(&lfs, "ardvark/batman/cantaloupe") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark/batman") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "ardvark/batman") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_many]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMAINING = [64, 2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 32',
|
|
]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
}
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-REMAINING + i));
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-REMAINING + i));
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_many_backwards]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMAINING = [64, 2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 32',
|
|
]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
}
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
#[cases.test_dirs_root]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_many_creation]
|
|
#defines.N = 'range(3, 100, 3)'
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "dir%03d", i);
|
|
# lfs_mkdir(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "dir%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_many_removal]
|
|
#defines.N = 'range(3, 100, 11)'
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "removeme%03d", i);
|
|
# lfs_mkdir(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "removeme%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "removeme%03d", i);
|
|
# lfs_remove(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_many_rename]
|
|
#defines.N = 'range(3, 100, 11)'
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "test%03d", i);
|
|
# lfs_mkdir(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "test%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char oldpath[128];
|
|
# char newpath[128];
|
|
# sprintf(oldpath, "test%03d", i);
|
|
# sprintf(newpath, "tedd%03d", i);
|
|
# lfs_rename(&lfs, oldpath, newpath) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "tedd%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_many_reentrant]
|
|
#defines.N = [5, 11]
|
|
#if = 'BLOCK_COUNT >= 4*N'
|
|
#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++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", i);
|
|
# err = lfs_mkdir(&lfs, path);
|
|
# assert(err == 0 || err == LFS_ERR_EXIST);
|
|
# }
|
|
#
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello%03d", i);
|
|
# err = lfs_remove(&lfs, path);
|
|
# assert(err == 0 || err == LFS_ERR_NOENT);
|
|
# }
|
|
#
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# for (int i = 0; i < N; i++) {
|
|
# char oldpath[128];
|
|
# char newpath[128];
|
|
# sprintf(oldpath, "hi%03d", i);
|
|
# sprintf(newpath, "hello%03d", i);
|
|
# // YES this can overwrite an existing newpath
|
|
# lfs_rename(&lfs, oldpath, newpath) => 0;
|
|
# }
|
|
#
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello%03d", i);
|
|
# lfs_remove(&lfs, path) => 0;
|
|
# }
|
|
#
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_file_creation]
|
|
#defines.N = 'range(3, 100, 11)'
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "file%03d", i);
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, path,
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "file%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_file_removal]
|
|
#defines.N = 'range(3, 100, 11)'
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "removeme%03d", i);
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, path,
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "removeme%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "removeme%03d", i);
|
|
# lfs_remove(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_file_rename]
|
|
#defines.N = 'range(3, 100, 11)'
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "test%03d", i);
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, path,
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "test%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char oldpath[128];
|
|
# char newpath[128];
|
|
# sprintf(oldpath, "test%03d", i);
|
|
# sprintf(newpath, "tedd%03d", i);
|
|
# lfs_rename(&lfs, oldpath, newpath) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "tedd%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_file_reentrant]
|
|
#defines.N = [5, 25]
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#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++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", i);
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# }
|
|
#
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello%03d", i);
|
|
# err = lfs_remove(&lfs, path);
|
|
# assert(err == 0 || err == LFS_ERR_NOENT);
|
|
# }
|
|
#
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# for (int i = 0; i < N; i++) {
|
|
# char oldpath[128];
|
|
# char newpath[128];
|
|
# sprintf(oldpath, "hi%03d", i);
|
|
# sprintf(newpath, "hello%03d", i);
|
|
# // YES this can overwrite an existing newpath
|
|
# lfs_rename(&lfs, oldpath, newpath) => 0;
|
|
# }
|
|
#
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello%03d", i);
|
|
# lfs_remove(&lfs, path) => 0;
|
|
# }
|
|
#
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_nested]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "potato") => 0;
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, "burito",
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "potato/baked") => 0;
|
|
# lfs_mkdir(&lfs, "potato/sweet") => 0;
|
|
# lfs_mkdir(&lfs, "potato/fried") => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "potato") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "baked") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "fried") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "sweet") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# // try removing?
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# // try renaming?
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_rename(&lfs, "potato", "coldpotato") => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_rename(&lfs, "coldpotato", "warmpotato") => 0;
|
|
# lfs_rename(&lfs, "warmpotato", "hotpotato") => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_remove(&lfs, "potato") => LFS_ERR_NOENT;
|
|
# lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT;
|
|
# lfs_remove(&lfs, "warmpotato") => LFS_ERR_NOENT;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# // try cross-directory renaming
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "coldpotato") => 0;
|
|
# lfs_rename(&lfs, "hotpotato/baked", "coldpotato/baked") => 0;
|
|
# lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_rename(&lfs, "hotpotato/fried", "coldpotato/fried") => 0;
|
|
# lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_rename(&lfs, "hotpotato/sweet", "coldpotato/sweet") => 0;
|
|
# lfs_rename(&lfs, "coldpotato", "hotpotato") => 0;
|
|
# lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "hotpotato") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "baked") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "fried") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "sweet") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# // final remove
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "hotpotato/baked") => 0;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "hotpotato/fried") => 0;
|
|
# lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
|
# lfs_remove(&lfs, "hotpotato/sweet") => 0;
|
|
# lfs_remove(&lfs, "hotpotato") => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# info.type => LFS_TYPE_DIR;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "burito") == 0);
|
|
# info.type => LFS_TYPE_REG;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_recursive_remove]
|
|
#defines.N = [10, 100]
|
|
#if = 'N < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "prickly-pear") => 0;
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "prickly-pear/cactus%03d", i);
|
|
# lfs_mkdir(&lfs, path) => 0;
|
|
# }
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "cactus%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs);
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY;
|
|
#
|
|
# lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# for (int i = 0; i < N; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "cactus%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# sprintf(path, "prickly-pear/%s", info.name);
|
|
# lfs_remove(&lfs, path) => 0;
|
|
# }
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# lfs_remove(&lfs, "prickly-pear") => 0;
|
|
# lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_other_errors]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "potato") => 0;
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, "burito",
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
#
|
|
# lfs_mkdir(&lfs, "potato") => LFS_ERR_EXIST;
|
|
# lfs_mkdir(&lfs, "burito") => LFS_ERR_EXIST;
|
|
# lfs_file_open(&lfs, &file, "burito",
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
|
|
# lfs_file_open(&lfs, &file, "potato",
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "tomato") => LFS_ERR_NOENT;
|
|
# lfs_dir_open(&lfs, &dir, "burito") => LFS_ERR_NOTDIR;
|
|
# lfs_file_open(&lfs, &file, "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
|
# lfs_file_open(&lfs, &file, "potato", LFS_O_RDONLY) => LFS_ERR_ISDIR;
|
|
# lfs_file_open(&lfs, &file, "tomato", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
|
# lfs_file_open(&lfs, &file, "potato", LFS_O_WRONLY) => LFS_ERR_ISDIR;
|
|
# lfs_file_open(&lfs, &file, "potato",
|
|
# LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR;
|
|
#
|
|
# lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
|
# lfs_file_open(&lfs, &file, "/",
|
|
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
|
|
# lfs_file_open(&lfs, &file, "/", LFS_O_RDONLY) => LFS_ERR_ISDIR;
|
|
# lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY) => LFS_ERR_ISDIR;
|
|
# lfs_file_open(&lfs, &file, "/",
|
|
# LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR;
|
|
#
|
|
# // check that errors did not corrupt directory
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, "burito") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "potato") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# // or on disk
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_REG);
|
|
# assert(strcmp(info.name, "burito") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# assert(strcmp(info.name, "potato") == 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 0;
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_seek]
|
|
#defines.COUNT = [4, 128, 132]
|
|
#if = 'COUNT < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "hello") => 0;
|
|
# for (int i = 0; i < COUNT; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hello/kitty%03d", i);
|
|
# lfs_mkdir(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# for (int j = 2; j < COUNT; j++) {
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "hello") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_soff_t pos;
|
|
# for (int i = 0; i < j; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "kitty%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# pos = lfs_dir_tell(&lfs, &dir);
|
|
# assert(pos >= 0);
|
|
# }
|
|
#
|
|
# lfs_dir_seek(&lfs, &dir, pos) => 0;
|
|
# char path[1024];
|
|
# sprintf(path, "kitty%03d", j);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_dir_rewind(&lfs, &dir) => 0;
|
|
# sprintf(path, "kitty%03u", 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_dir_seek(&lfs, &dir, pos) => 0;
|
|
# sprintf(path, "kitty%03d", j);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
# }
|
|
#'''
|
|
#
|
|
#[cases.test_dirs_toot_seek]
|
|
#defines.COUNT = [4, 128, 132]
|
|
#if = 'COUNT < BLOCK_COUNT/2'
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# for (int i = 0; i < COUNT; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", i);
|
|
# lfs_mkdir(&lfs, path) => 0;
|
|
# }
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# for (int j = 2; j < COUNT; j++) {
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_dir_t dir;
|
|
# lfs_dir_open(&lfs, &dir, "/") => 0;
|
|
# struct lfs_info info;
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_soff_t pos;
|
|
# for (int i = 0; i < j; i++) {
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", i);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# pos = lfs_dir_tell(&lfs, &dir);
|
|
# assert(pos >= 0);
|
|
# }
|
|
#
|
|
# lfs_dir_seek(&lfs, &dir, pos) => 0;
|
|
# char path[1024];
|
|
# sprintf(path, "hi%03d", j);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_dir_rewind(&lfs, &dir) => 0;
|
|
# sprintf(path, "hi%03u", 0);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_dir_seek(&lfs, &dir, pos) => 0;
|
|
# sprintf(path, "hi%03d", j);
|
|
# lfs_dir_read(&lfs, &dir, &info) => 1;
|
|
# assert(strcmp(info.name, path) == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfs_dir_close(&lfs, &dir) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
# }
|
|
#'''
|
|
#
|