2ce6567683
It turned out our dir-read-idempotent test never created non-dstart neighbors. This was a bit of a problem since we relied on dstart entries to know when our dir read terminates. If we seek to an invalid position (in theory undefined behavior, but easily possible with concurrent modifications to the directory), we can end up reading an unrealted, non-dstart entry, and incorrectly reporting that entry as in our current dir. This fix reintroduces the did into the lfsr_dir_t struct and uses the did to determine end-of-dir. This adds some RAM cost, but is more resilient to any seeks that overshoot the end of the directory. Using did is also a stronger guarantee we will never accidentally report unrelated entries as a part of the current directory.
7324 lines
236 KiB
TOML
7324 lines
236 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.pgrm[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]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
// make a directory
|
|
lfsr_mkdir(&lfs, "ardvark") => 0;
|
|
|
|
// 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.pgrm[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 stat on root works
|
|
[cases.t5_dirs_stat_root]
|
|
defines.REMOUNT = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
// make a directory
|
|
lfsr_mkdir(&lfs, "ardvark") => 0;
|
|
|
|
// stat the root
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "/", &info) => 0;
|
|
assert(strcmp(info.name, "/") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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_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 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.pgrm[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
|
|
err = lfsr_mkdir(&lfs, "/");
|
|
assert(err == LFS_ERR_EXIST || err == LFS_ERR_INVAL);
|
|
|
|
// 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
|
|
err = lfsr_mkdir(&lfs, "/");
|
|
assert(err == LFS_ERR_EXIST || err == LFS_ERR_INVAL);
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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.pgrm[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, "banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cat");
|
|
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.pgrm[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, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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/banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/banana/cat");
|
|
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.pgrm[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/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/banana/cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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_dir_open(&lfs, &dir, "/ardvark/banana") => 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, "cat") == 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]
|
|
# limit powerloss testing due to time
|
|
if = '!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.pgrm[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]
|
|
# limit powerloss testing due to time
|
|
if = '!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.pgrm[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]
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 4'
|
|
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.pgrm[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]
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 2'
|
|
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.pgrm[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]
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 16'
|
|
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.pgrm[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)'
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 64'
|
|
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) % 10000;
|
|
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen?
|
|
if (j < sim_size && sim[j] == x) {
|
|
// do nothing
|
|
} else {
|
|
// 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);
|
|
int err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || err == LFS_ERR_EXIST);
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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.pgrm[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.pgrm[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.pgrm[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.pgrm[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.pgrm[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.pgrm[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.pgrm[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.pgrm[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;
|
|
'''
|
|
|
|
# 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.pgrm[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, "banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cat");
|
|
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.pgrm[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, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "banana") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "banana", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "cat") == 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, "cat") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "banana", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "cat", &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/banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/banana/cat");
|
|
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.pgrm[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/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/banana/cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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_dir_open(&lfs, &dir, "/ardvark/banana") => 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, "cat") == 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/banana/cat") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/banana/cat", &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, "banana") == 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/banana") => 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/banana") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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/banana", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/banana/cat", &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.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/banana", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/banana/cat", &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',
|
|
# limit powerloss testing due to time
|
|
'!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.pgrm[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.pgrm[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',
|
|
# limit powerloss testing due to time
|
|
'!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.pgrm[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.pgrm[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.t5_dirs_rm_many_2layers]
|
|
defines.N = [1, 2, 4, 8, 16]
|
|
defines.REMAINING = [2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# limit powerloss testing due to time
|
|
'!TEST_PL || N <= 4',
|
|
]
|
|
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.pgrm[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;
|
|
}
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
if (i < N-REMAINING || j < N-REMAINING) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
if (i < N-REMAINING) {
|
|
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.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
if (i < N-REMAINING) {
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
} else {
|
|
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;
|
|
if (j < N-REMAINING) {
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
} else {
|
|
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_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;
|
|
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-REMAINING + 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 < REMAINING; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", (int)(N-REMAINING + 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_rm_many_3layers]
|
|
defines.N = [1, 2, 4]
|
|
defines.REMAINING = [2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# limit powerloss testing due to time
|
|
'!TEST_PL || N <= 2',
|
|
]
|
|
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.pgrm[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;
|
|
}
|
|
}
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
if (i < N-REMAINING || j < N-REMAINING || k < N-REMAINING) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
if (i < N-REMAINING || j < N-REMAINING) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
if (i < N-REMAINING) {
|
|
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.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
if (i < N-REMAINING) {
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
} else {
|
|
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;
|
|
if (j < N-REMAINING) {
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
} else {
|
|
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;
|
|
if (k < N-REMAINING) {
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
} else {
|
|
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_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;
|
|
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-REMAINING + 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 < REMAINING; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", (int)(N-REMAINING + 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 i = 0; i < REMAINING; i++) {
|
|
for (lfs_size_t j = 0; j < REMAINING; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d",
|
|
(int)(N-REMAINING + i),
|
|
(int)(N-REMAINING + 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 < REMAINING; k++) {
|
|
char name[256];
|
|
sprintf(name, "grandchild%04d", (int)(N-REMAINING + 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_rm_many_linkedlist]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
|
defines.REMAINING = [16, 2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# limit powerloss testing due to time
|
|
'!TEST_PL || N <= 16',
|
|
]
|
|
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.pgrm[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;
|
|
}
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
lfsr_remove(&lfs, name) => 0;
|
|
name[strlen(name) - strlen("/dir....")] = '\0';
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our remove worked
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < REMAINING; 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 < REMAINING; 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 < REMAINING-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_rm_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)'
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 64'
|
|
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 op, either mkdir or rmdir
|
|
uint8_t op = TEST_PRNG(&prng) % 2;
|
|
|
|
if (op == 0 || sim_size == 0) {
|
|
// choose a pseudo-random number, truncate to 4 decimals
|
|
lfs_size_t x = TEST_PRNG(&prng) % 10000;
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen?
|
|
if (j < sim_size && sim[j] == x) {
|
|
// do nothing
|
|
} else {
|
|
// 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);
|
|
int err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || err == LFS_ERR_EXIST);
|
|
|
|
} else {
|
|
// choose a pseudo-random entry to delete
|
|
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
|
lfs_size_t x = sim[j];
|
|
// delete from our sim
|
|
memmove(&sim[j], &sim[j+1],
|
|
(sim_size-(j+1))*sizeof(lfs_size_t));
|
|
sim_size -= 1;
|
|
|
|
// remove this directory
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
}
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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;
|
|
'''
|
|
|
|
|
|
## dir rename tests
|
|
|
|
[cases.t5_dirs_mv]
|
|
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));
|
|
|
|
// clean up interrupted renames
|
|
if (TEST_PL) {
|
|
err = lfsr_remove(&lfs, "banana");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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;
|
|
|
|
// now rename the directory
|
|
lfsr_rename(&lfs, "ardvark", "banana") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that rename worked with stat
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// 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) => 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;
|
|
'''
|
|
|
|
# test that we can rename, and replace, other directories
|
|
[cases.t5_dirs_mv_replace]
|
|
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 directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "banana");
|
|
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.pgrm[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) => 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;
|
|
|
|
// now rename the directory
|
|
lfsr_rename(&lfs, "ardvark", "banana") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that rename worked with stat
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// 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) => 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;
|
|
'''
|
|
|
|
# test that we can rename to ourselves
|
|
[cases.t5_dirs_mv_noop]
|
|
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 directories
|
|
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.pgrm[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;
|
|
|
|
// now rename the directory to itself
|
|
lfsr_rename(&lfs, "ardvark", "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that rename worked with stat
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// 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) => 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 replacing an invalid path
|
|
[cases.t5_dirs_mv_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 directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to rename a nonsense directory
|
|
lfsr_rename(&lfs, "no", "ardvark") => LFS_ERR_NOENT;
|
|
|
|
// try to rename a directory in a nonsense directory
|
|
lfsr_rename(&lfs, "no/ardvark", "ardvark") => LFS_ERR_NOENT;
|
|
|
|
// try to rename a nonsense child directory
|
|
lfsr_rename(&lfs, "ardvark/no", "banana") => LFS_ERR_NOENT;
|
|
|
|
// try to rename to a nonense directory
|
|
lfsr_rename(&lfs, "ardvark", "no/ardvark") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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 replacing a non-empty directory
|
|
[cases.t5_dirs_mv_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 directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
// fill dest with stuff
|
|
err = lfsr_mkdir(&lfs, "banana/cat");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to rename
|
|
lfsr_rename(&lfs, "ardvark", "banana") => LFS_ERR_NOTEMPTY;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "banana/cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "banana") == 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, "banana") => 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, "cat") == 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 rename root
|
|
[cases.t5_dirs_mv_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 rename root, which doesn't really make sense
|
|
lfsr_rename(&lfs, "/", "notroot") => LFS_ERR_INVAL;
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to rename root, which doesn't really make sense
|
|
lfsr_rename(&lfs, "/", "notroot") => LFS_ERR_INVAL;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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_mv_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, "banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cat");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// clean up interrupted renames
|
|
if (TEST_PL) {
|
|
err = lfsr_remove(&lfs, "disco");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "eggplant");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "fish");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now rename each directory
|
|
lfsr_rename(&lfs, "ardvark", "disco") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our rename worked
|
|
lfsr_stat(&lfs, "banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco", &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 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, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// rename another
|
|
lfsr_rename(&lfs, "banana", "eggplant") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our rename worked
|
|
lfsr_stat(&lfs, "cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco", &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "eggplant", &info) => 0;
|
|
assert(strcmp(info.name, "eggplant") == 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, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "eggplant") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// rename another
|
|
lfsr_rename(&lfs, "cat", "fish") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our rename worked
|
|
lfsr_stat(&lfs, "disco", &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "eggplant", &info) => 0;
|
|
assert(strcmp(info.name, "eggplant") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "fish", &info) => 0;
|
|
assert(strcmp(info.name, "fish") == 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, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "eggplant") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "fish") == 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_mv_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/banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/banana/cat");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// clean up interrupted renames
|
|
if (TEST_PL) {
|
|
err = lfsr_remove(&lfs, "disco/eggplant/fish");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "disco/eggplant/cat");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "disco/eggplant");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "disco/banana/cat");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "disco/banana");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
err = lfsr_remove(&lfs, "disco");
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/banana/cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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_dir_open(&lfs, &dir, "/ardvark/banana") => 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, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now rename each directory
|
|
lfsr_rename(&lfs, "ardvark", "disco") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our rename worked
|
|
lfsr_stat(&lfs, "disco", &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco/banana/cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "disco") == 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, "/disco") => 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_dir_open(&lfs, &dir, "/disco/banana") => 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, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// rename another
|
|
lfsr_rename(&lfs, "disco/banana", "disco/eggplant") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our rename worked
|
|
lfsr_stat(&lfs, "disco", &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco/eggplant", &info) => 0;
|
|
assert(strcmp(info.name, "eggplant") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco/eggplant/cat", &info) => 0;
|
|
assert(strcmp(info.name, "cat") == 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, "disco") == 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, "/disco") => 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, "eggplant") == 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, "/disco/eggplant") => 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, "cat") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// rename another
|
|
lfsr_rename(&lfs, "disco/eggplant/cat", "disco/eggplant/fish") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// check that our rename worked
|
|
lfsr_stat(&lfs, "disco", &info) => 0;
|
|
assert(strcmp(info.name, "disco") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco/eggplant", &info) => 0;
|
|
assert(strcmp(info.name, "eggplant") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "disco/eggplant/fish", &info) => 0;
|
|
assert(strcmp(info.name, "fish") == 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, "disco") == 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, "/disco") => 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, "eggplant") == 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, "/disco/eggplant") => 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, "fish") == 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_mv_many]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.BEFORE = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
# limit powerloss testing due to time
|
|
if = '!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;
|
|
}
|
|
|
|
// check if we have already started renaming, in case of powerloss
|
|
struct lfs_info info;
|
|
err = lfsr_stat(&lfs, (BEFORE ? "/0mved0000" : "/mved0000"), &info);
|
|
if (err == LFS_ERR_NOENT) {
|
|
// 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.pgrm[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 rename the directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "dir%04d", i);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d", (BEFORE ? "0" : ""), i);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our renames worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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;
|
|
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, "%smved%04d", (BEFORE ? "0" : ""), 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_mv_many_backwards]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.BEFORE = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
# limit powerloss testing due to time
|
|
if = '!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;
|
|
}
|
|
|
|
// check if we have already started renaming, in case of powerloss
|
|
struct lfs_info info;
|
|
err = lfsr_stat(&lfs, (BEFORE ? "/0mved0000" : "/mved0000"), &info);
|
|
if (err == LFS_ERR_NOENT) {
|
|
// 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.pgrm[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 rename the directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "dir%04d", i);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d", (BEFORE ? "0" : ""), i);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our renames worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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;
|
|
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, "%smved%04d", (BEFORE ? "0" : ""), 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_mv_many_2layers]
|
|
defines.N = [1, 2, 4, 8, 16]
|
|
defines.BEFORE = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 4'
|
|
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;
|
|
}
|
|
|
|
// check if we have already started renaming, in case of powerloss
|
|
struct lfs_info info;
|
|
err = lfsr_stat(&lfs, (BEFORE ? "/0mved0000" : "/mved0000"), &info);
|
|
if (err == LFS_ERR_NOENT) {
|
|
// 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.pgrm[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;
|
|
}
|
|
}
|
|
|
|
// now rename our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "dir%04d", i);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d", (BEFORE ? "0" : ""), i);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "%smved%04d/child%04d",
|
|
(BEFORE ? "0" : ""), i, j);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d/%schmved%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), j);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our renames worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d/%schmved%04d",
|
|
(BEFORE ? "0" : ""), i, (BEFORE ? "0" : ""), j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "%schmved%04d", (BEFORE ? "0" : ""), j);
|
|
assert(strcmp(info.name, name) == 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);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d", (BEFORE ? "0" : ""), 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, "%schmved%04d", (BEFORE ? "0" : ""), 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_mv_many_3layers]
|
|
defines.N = [1, 2, 4]
|
|
defines.BEFORE = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 2'
|
|
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;
|
|
}
|
|
|
|
// check if we have already started renaming, in case of powerloss
|
|
struct lfs_info info;
|
|
err = lfsr_stat(&lfs, (BEFORE ? "/0mved0000" : "/mved0000"), &info);
|
|
if (err == LFS_ERR_NOENT) {
|
|
// 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.pgrm[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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// now rename our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "dir%04d", i);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d", (BEFORE ? "0" : ""), i);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "%smved%04d/child%04d",
|
|
(BEFORE ? "0" : ""), i, j);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d/%schmved%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), j);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char old_name[256];
|
|
sprintf(old_name, "%smved%04d/%schmved%04d/grandchild%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), j, k);
|
|
char new_name[256];
|
|
sprintf(new_name, "%smved%04d/%schmved%04d/%sgrmved%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), j,
|
|
(BEFORE ? "0" : ""), k);
|
|
int err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d/%schmved%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "%schmved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d/%schmved%04d/%sgrmved%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), j,
|
|
(BEFORE ? "0" : ""), k);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "%sgrmved%04d", (BEFORE ? "0" : ""), k);
|
|
assert(strcmp(info.name, name) == 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);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d", (BEFORE ? "0" : ""), 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, "%schmved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d/%schmved%04d",
|
|
(BEFORE ? "0" : ""), i,
|
|
(BEFORE ? "0" : ""), 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, "%sgrmved%04d", (BEFORE ? "0" : ""), 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_mv_many_linkedlist]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
|
defines.BEFORE = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 16'
|
|
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;
|
|
}
|
|
|
|
// check if we have already started renaming, in case of powerloss
|
|
struct lfs_info info;
|
|
err = lfsr_stat(&lfs, (BEFORE ? "/0mved0000" : "/mved0000"), &info);
|
|
if (err == LFS_ERR_NOENT) {
|
|
// 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.pgrm[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;
|
|
}
|
|
}
|
|
|
|
// now rename our directories
|
|
char old_name[4096];
|
|
memset(old_name, 0, sizeof(old_name));
|
|
char new_name[4096];
|
|
memset(new_name, 0, sizeof(new_name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&old_name[strlen(old_name)], "/dir%04d", i);
|
|
sprintf(&new_name[strlen(new_name)], "/%smved%04d",
|
|
(BEFORE ? "0" : ""), i);
|
|
err = lfsr_rename(&lfs, old_name, new_name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[0] == 0);
|
|
}
|
|
|
|
// update old_name's path
|
|
memcpy(old_name, new_name, sizeof(old_name));
|
|
}
|
|
|
|
// check that our renames worked
|
|
char name[4096];
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/%smved%04d", (BEFORE ? "0" : ""), i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "%smved%04d", (BEFORE ? "0" : ""), 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)], "/%smved%04d", (BEFORE ? "0" : ""), 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, "%smved%04d", (BEFORE ? "0" : ""), 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_mv_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)'
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 64'
|
|
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 op, either mkdir or rename
|
|
uint8_t op = TEST_PRNG(&prng) % 2;
|
|
|
|
if (op == 0 || sim_size == 0) {
|
|
// choose a pseudo-random number, truncate to 4 decimals
|
|
lfs_size_t x = TEST_PRNG(&prng) % 10000;
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen?
|
|
if (j < sim_size && sim[j] == x) {
|
|
// do nothing
|
|
} else {
|
|
// 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);
|
|
int err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || err == LFS_ERR_EXIST);
|
|
|
|
} else {
|
|
// choose a pseudo-random entry to rename, and a pseudo-random
|
|
// number to rename to
|
|
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
|
lfs_size_t x = sim[j];
|
|
lfs_size_t y = TEST_PRNG(&prng) % 10000;
|
|
for (lfs_size_t k = 0;; k++) {
|
|
if (k >= sim_size || sim[k] >= y) {
|
|
// already seen and not a noop?
|
|
if (k < sim_size && sim[k] == y && x != y) {
|
|
// just delete the original entry
|
|
memmove(&sim[j], &sim[j+1],
|
|
(sim_size-(j+1))*sizeof(lfs_size_t));
|
|
sim_size -= 1;
|
|
} else {
|
|
// first delete
|
|
memmove(&sim[j], &sim[j+1],
|
|
(sim_size-(j+1))*sizeof(lfs_size_t));
|
|
if (k > j) {
|
|
k -= 1;
|
|
}
|
|
// then insert
|
|
memmove(&sim[k+1], &sim[k],
|
|
(sim_size-k)*sizeof(lfs_size_t));
|
|
sim[k] = y;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// rename this directory
|
|
char old_name[256];
|
|
sprintf(old_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
char new_name[256];
|
|
sprintf(new_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), y);
|
|
lfsr_rename(&lfs, old_name, new_name) => 0;
|
|
}
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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 all of the operations together
|
|
[cases.t5_dirs_general_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)'
|
|
# limit powerloss testing due to time
|
|
if = '!TEST_PL || N <= 64'
|
|
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 op, either mkdir, remove, or rename
|
|
uint8_t op = TEST_PRNG(&prng) % 3;
|
|
|
|
if (op == 0 || sim_size == 0) {
|
|
// choose a pseudo-random number, truncate to 4 decimals
|
|
lfs_size_t x = TEST_PRNG(&prng) % 10000;
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen?
|
|
if (j < sim_size && sim[j] == x) {
|
|
// do nothing
|
|
} else {
|
|
// 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);
|
|
int err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || err == LFS_ERR_EXIST);
|
|
|
|
} else if (op == 1) {
|
|
// choose a pseudo-random entry to delete
|
|
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
|
lfs_size_t x = sim[j];
|
|
// delete from our sim
|
|
memmove(&sim[j], &sim[j+1],
|
|
(sim_size-(j+1))*sizeof(lfs_size_t));
|
|
sim_size -= 1;
|
|
|
|
// remove this directory
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
} else {
|
|
// choose a pseudo-random entry to rename, and a pseudo-random
|
|
// number to rename to
|
|
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
|
lfs_size_t x = sim[j];
|
|
lfs_size_t y = TEST_PRNG(&prng) % 10000;
|
|
for (lfs_size_t k = 0;; k++) {
|
|
if (k >= sim_size || sim[k] >= y) {
|
|
// already seen and not a noop?
|
|
if (k < sim_size && sim[k] == y && x != y) {
|
|
// just delete the original entry
|
|
memmove(&sim[j], &sim[j+1],
|
|
(sim_size-(j+1))*sizeof(lfs_size_t));
|
|
sim_size -= 1;
|
|
} else {
|
|
// first delete
|
|
memmove(&sim[j], &sim[j+1],
|
|
(sim_size-(j+1))*sizeof(lfs_size_t));
|
|
if (k > j) {
|
|
k -= 1;
|
|
}
|
|
// then insert
|
|
memmove(&sim[k+1], &sim[k],
|
|
(sim_size-k)*sizeof(lfs_size_t));
|
|
sim[k] = y;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// rename this directory
|
|
char old_name[256];
|
|
sprintf(old_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
char new_name[256];
|
|
sprintf(new_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), y);
|
|
lfsr_rename(&lfs, old_name, new_name) => 0;
|
|
}
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.pgrm[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 seeking and stuff
|
|
|
|
[cases.t5_dirs_tell]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// read our directory
|
|
//
|
|
// Note tell's value is not guaranteed! We can test the exact value only
|
|
// because these tests are tightly bound to the current littlefs version.
|
|
//
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 0;
|
|
lfsr_dir_tell(&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_tell(&lfs, &dir) => 1;
|
|
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++) {
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + 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_tell(&lfs, &dir) => 2 + N;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + N;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rewind]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 0;
|
|
|
|
// read our directory once
|
|
lfsr_dir_tell(&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_tell(&lfs, &dir) => 1;
|
|
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++) {
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + 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_tell(&lfs, &dir) => 2 + N;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + N;
|
|
|
|
// now read it again
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
lfsr_dir_tell(&lfs, &dir) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_tell(&lfs, &dir) => 1;
|
|
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++) {
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + 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_tell(&lfs, &dir) => 2 + N;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + N;
|
|
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_seek]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 0;
|
|
|
|
// read our directory once
|
|
lfsr_dir_tell(&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_tell(&lfs, &dir) => 1;
|
|
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++) {
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + 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_tell(&lfs, &dir) => 2 + N;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_tell(&lfs, &dir) => 2 + N;
|
|
|
|
// now try to seek to each entry explicitly
|
|
lfsr_dir_seek(&lfs, &dir, 0) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_seek(&lfs, &dir, 1) => 0;
|
|
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++) {
|
|
lfsr_dir_seek(&lfs, &dir, 2 + i) => 0;
|
|
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_seek(&lfs, &dir, 2 + N) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_seek(&lfs, &dir, 2 + N) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_read_idempotent]
|
|
defines.PARENT = [false, true]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# neighbors only make sense if we have a parent
|
|
if = 'PARENT || NEIGHBORS == 0'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
}
|
|
|
|
char name[256];
|
|
sprintf(name, "%s/ardvark", (PARENT ? "pricklypear" : ""));
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
|
|
// read to the end
|
|
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);
|
|
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_tell(&lfs, &dir) => 3;
|
|
|
|
// reading again should still return noent
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
|
|
// seeking past the end of the directory should still return noent
|
|
lfsr_dir_seek(&lfs, &dir, 3) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_seek(&lfs, &dir, 4) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_seek(&lfs, &dir, 1000) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
|
|
// but we should be able to read again
|
|
lfsr_dir_rewind(&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_read_with_mkdirs]
|
|
defines.N = 5
|
|
# where in the dir read do we mkdir?
|
|
defines.I = 'range(6)'
|
|
# where do we mkdir?
|
|
defines.J = 'range(6)'
|
|
defines.PARENT = [false, true]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
# neighbors only make sense if we have a parent
|
|
if = 'PARENT || NEIGHBORS == 0'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i+1);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i+1);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
// make a dir at J
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d_", (PARENT ? "pricklypear" : ""), (int)J);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
|
|
// seek after mkdir? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// we should be able to keep reading, though we may pick up J
|
|
for (lfs_size_t i = I + (I >= J ? 1 : 0); i < N+1; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d%s", i+1 - (i >= J ? 1 : 0), (i == 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_read_with_rms]
|
|
defines.N = 5
|
|
# where in the dir read do we rm?
|
|
defines.I = 'range(5)'
|
|
# where do we rm?
|
|
defines.J = 'range(5)'
|
|
defines.PARENT = [false, true]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
# neighbors only make sense if we have a parent
|
|
if = 'PARENT || NEIGHBORS == 0'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; 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);
|
|
}
|
|
|
|
// remove the dir at J
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), (int)J);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// seek after remove? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// we should be able to keep reading
|
|
for (lfs_size_t i = I; i < N; i++) {
|
|
if (i == J) {
|
|
continue;
|
|
}
|
|
|
|
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_read_with_mvs]
|
|
defines.N = 5
|
|
# where in the dir read do we rm?
|
|
defines.I = 'range(5)'
|
|
# where do we rm?
|
|
defines.J = 'range(5)'
|
|
defines.K = 'range(5)'
|
|
defines.BEFORE = [false, true]
|
|
# 0 => no
|
|
# 1 => yes
|
|
# 2 => yes, and rename to new parent
|
|
defines.PARENT = [0, 1, 2]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
# neighbors only make sense if we have a parent
|
|
if = 'PARENT || NEIGHBORS == 0'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
if (PARENT >= 2) {
|
|
lfsr_mkdir(&lfs, "quiabentia") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; 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);
|
|
}
|
|
|
|
// rename the dir at J
|
|
char old_name[256];
|
|
sprintf(old_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), (int)J);
|
|
char new_name[256];
|
|
sprintf(new_name, "%s/%smved%04d",
|
|
(PARENT == 1 ? "pricklypear"
|
|
: PARENT >= 2 ? "quiabentia"
|
|
: ""),
|
|
(BEFORE ? "0" : ""),
|
|
(int)J);
|
|
lfsr_rename(&lfs, old_name, new_name) => 0;
|
|
|
|
// seek after remove? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// we should be able to keep reading
|
|
for (lfs_size_t i = I; i < N; i++) {
|
|
if (i == J) {
|
|
continue;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
int err = lfsr_dir_read(&lfs, &dir, &info);
|
|
assert(err == LFS_ERR_NOENT || (!BEFORE && PARENT < 2));
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# dir reads with 2x ops have better chances of catching bugs that depend on
|
|
# invalid dir states
|
|
|
|
[cases.t5_dirs_read_with_2_mkdirs]
|
|
defines.N = 5
|
|
# where in the dir read do we mkdir?
|
|
defines.I = 'range(6)'
|
|
# where do we mkdir?
|
|
defines.J = 'range(6)'
|
|
defines.K = 'range(6)'
|
|
defines.PARENT = [false, true]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
if = [
|
|
'J != K',
|
|
# neighbors only make sense if we have a parent
|
|
'PARENT || NEIGHBORS == 0',
|
|
]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
}
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i+1);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i+1);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
// make a dir at J
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d_", (PARENT ? "pricklypear" : ""), (int)J);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
|
|
// make a dir at K
|
|
sprintf(name, "%s/dir%04d_", (PARENT ? "pricklypear" : ""), (int)K);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
|
|
// seek after mkdir? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// we should be able to keep reading, though we may pick up J
|
|
for (lfs_size_t i = I + (I >= J ? 1 : 0) + (I >= K ? 1 : 0); i < N+2; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d%s",
|
|
i+1 - (i >= J + (J >= K ? 1 : 0) ? 1 : 0)
|
|
- (i >= K + (K >= J ? 1 : 0) ? 1 : 0),
|
|
(i == J + (J > K ? 1 : 0) || i == K + (K > J ? 1 : 0)
|
|
? "_" : ""));
|
|
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_read_with_2_rms]
|
|
defines.N = 5
|
|
# where in the dir read do we rm?
|
|
defines.I = 'range(5)'
|
|
# where do we rm?
|
|
defines.J = 'range(5)'
|
|
defines.K = 'range(5)'
|
|
defines.PARENT = [false, true]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
if = [
|
|
'J != K',
|
|
# neighbors only make sense if we have a parent
|
|
'PARENT || NEIGHBORS == 0',
|
|
]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; 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);
|
|
}
|
|
|
|
// remove the dir at J
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), (int)J);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// remove the dir at K
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), (int)K);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// seek after remove? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// we should be able to keep reading
|
|
for (lfs_size_t i = I; i < N; i++) {
|
|
if (i == J || i == K) {
|
|
continue;
|
|
}
|
|
|
|
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_read_with_2_mvs]
|
|
defines.N = 5
|
|
# where in the dir read do we rm?
|
|
defines.I = 'range(5)'
|
|
# where do we rm?
|
|
defines.J = 'range(5)'
|
|
defines.K = 'range(5)'
|
|
defines.BEFORE = [false, true]
|
|
# 0 => no
|
|
# 1 => yes
|
|
# 2 => yes, and rename to new parent
|
|
defines.PARENT = [0, 1, 2]
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
# neighbors only make sense if we have a parent
|
|
if = [
|
|
'J != K',
|
|
# neighbors only make sense if we have a parent
|
|
'PARENT || NEIGHBORS == 0',
|
|
]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
if (PARENT) {
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
if (PARENT >= 2) {
|
|
lfsr_mkdir(&lfs, "quiabentia") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; 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);
|
|
}
|
|
|
|
// rename the dir at J
|
|
char old_name[256];
|
|
sprintf(old_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), (int)J);
|
|
char new_name[256];
|
|
sprintf(new_name, "%s/%smved%04d",
|
|
(PARENT == 1 ? "pricklypear"
|
|
: PARENT >= 2 ? "quiabentia"
|
|
: ""),
|
|
(BEFORE ? "0" : ""),
|
|
(int)J);
|
|
lfsr_rename(&lfs, old_name, new_name) => 0;
|
|
|
|
// rename the dir at K
|
|
sprintf(old_name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), (int)K);
|
|
sprintf(new_name, "%s/%smved%04d",
|
|
(PARENT == 1 ? "pricklypear"
|
|
: PARENT >= 2 ? "quiabentia"
|
|
: ""),
|
|
(BEFORE ? "0" : ""),
|
|
(int)K);
|
|
lfsr_rename(&lfs, old_name, new_name) => 0;
|
|
|
|
// seek after remove? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// we should be able to keep reading
|
|
for (lfs_size_t i = I; i < N; i++) {
|
|
if (i == J || i == K) {
|
|
continue;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
int err = lfsr_dir_read(&lfs, &dir, &info);
|
|
assert(err == LFS_ERR_NOENT || (!BEFORE && PARENT < 2));
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test removing the directory we are iterating over
|
|
[cases.t5_dirs_read_rm]
|
|
defines.N = 5
|
|
# where in the dir read do we remove?
|
|
defines.I = 'range(6)'
|
|
# bit 0x2 = left neighbor
|
|
# bit 0x1 = right neighbor
|
|
defines.NEIGHBORS = [0x0, 0x1, 0x2, 0x3]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
|
|
lfsr_mkdir(&lfs, "pricklypear") => 0;
|
|
|
|
if (NEIGHBORS & 0x2) {
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH") => 0;
|
|
lfsr_mkdir(&lfs, "a_IplRNrPH/a_child") => 0;
|
|
}
|
|
|
|
if (NEIGHBORS & 0x1) {
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH") => 0;
|
|
lfsr_mkdir(&lfs, "f_VtoMnwRH/f_child") => 0;
|
|
}
|
|
|
|
// create our directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "pricklypear/dir%04d", i+1);
|
|
lfsr_mkdir(&lfs, name) => 0;
|
|
}
|
|
|
|
// start reading
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "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);
|
|
|
|
// read until I
|
|
for (lfs_size_t i = 0; i < I; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i+1);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
// remove the directory
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "pricklypear/dir%04d", i+1);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
}
|
|
lfsr_remove(&lfs, "pricklypear") => 0;
|
|
|
|
// seek after mkdir?
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
|
|
// try to read, but this should return an error
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
|
|
## Recursive tests
|
|
|
|
# Recursive here just refers to removing entries in a directory while
|
|
# iterating over the directory
|
|
#
|
|
# This is a useful feature, but it's unintuitive if this should have
|
|
# well-defined behavior, so make sure to test for it
|
|
[cases.t5_dirs_rm_recursive]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
# limit powerloss testing due to time
|
|
if = '!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;
|
|
}
|
|
|
|
if (PARENT) {
|
|
err = lfsr_mkdir(&lfs, "pricklypear");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), 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);
|
|
}
|
|
|
|
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 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 directories recursively
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 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 < 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);
|
|
|
|
char path[1024];
|
|
sprintf(path, "%s/%s", (PARENT ? "pricklypear" : ""), info.name);
|
|
lfsr_remove(&lfs, path) => 0;
|
|
|
|
// seek between removes? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
}
|
|
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 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;
|
|
'''
|
|
|
|
# Recursive here just refers to renaming entries in a directory while
|
|
# iterating over the directory
|
|
#
|
|
# This is a useful feature, but it's unintuitive if this should have
|
|
# well-defined behavior, so make sure to test for it
|
|
[cases.t5_dirs_mv_recursive]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.BEFORE = [false, true]
|
|
# 0 => no
|
|
# 1 => yes
|
|
# 2 => yes, and rename to new parent
|
|
defines.PARENT = [0, 1, 2]
|
|
# 0 => don't seek
|
|
# 1 => seek
|
|
# 2 => rewind then seek
|
|
defines.SEEK = [0, 1, 2]
|
|
# limit powerloss testing due to time
|
|
if = '!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;
|
|
}
|
|
|
|
if (PARENT) {
|
|
err = lfsr_mkdir(&lfs, "pricklypear");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
if (PARENT >= 2) {
|
|
err = lfsr_mkdir(&lfs, "quiabentia");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
}
|
|
}
|
|
|
|
// check if we have already started renaming, in case of powerloss
|
|
struct lfs_info info;
|
|
err = lfsr_stat(&lfs,
|
|
(PARENT == 1 ? (BEFORE
|
|
? "pricklypear/0mved0000"
|
|
: "pricklypear/mved0000")
|
|
: PARENT >= 2 ? (BEFORE
|
|
? "quiabentia/0mved0000"
|
|
: "quiabentia/mved0000")
|
|
: (BEFORE
|
|
? "/0mved0000"
|
|
: "/mved0000")), &info);
|
|
if (err == LFS_ERR_NOENT) {
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), 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);
|
|
}
|
|
|
|
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 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 rename directories recursively
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 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++) {
|
|
int err = lfsr_dir_read(&lfs, &dir, &info);
|
|
assert(!err || err == LFS_ERR_NOENT);
|
|
// reached the end?
|
|
if (err == LFS_ERR_NOENT) {
|
|
break;
|
|
}
|
|
// skip already moved?
|
|
if (memcmp(info.name, "dir", strlen("dir")) != 0) {
|
|
continue;
|
|
}
|
|
assert(i < 2*N);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
char old_path[1024];
|
|
sprintf(old_path, "%s/%s", (PARENT ? "pricklypear" : ""), info.name);
|
|
char new_path[1024];
|
|
sprintf(new_path, "%s/%smved%s",
|
|
(PARENT == 1 ? "pricklypear"
|
|
: PARENT >= 2 ? "quiabentia"
|
|
: ""),
|
|
(BEFORE ? "0" : ""),
|
|
&info.name[strlen("dir")]);
|
|
err = lfsr_rename(&lfs, old_path, new_path);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_NOENT));
|
|
|
|
// seek between renames? this tests that the internal position is
|
|
// updated correctly
|
|
if (SEEK) {
|
|
lfs_ssize_t off = lfsr_dir_tell(&lfs, &dir);
|
|
assert(off >= 0);
|
|
if (SEEK >= 2) {
|
|
lfsr_dir_rewind(&lfs, &dir) => 0;
|
|
}
|
|
lfsr_dir_seek(&lfs, &dir, off) => 0;
|
|
}
|
|
}
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// check that our renames worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
|
|
sprintf(name, "%s/%smved%04d",
|
|
(PARENT == 1 ? "pricklypear"
|
|
: PARENT >= 2 ? "quiabentia"
|
|
: ""),
|
|
(BEFORE ? "0" : ""),
|
|
i);
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "%smved%04d", (BEFORE ? "0" : ""), i);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_open(&lfs, &dir,
|
|
(PARENT == 1 ? "pricklypear"
|
|
: PARENT >= 2 ? "quiabentia"
|
|
: "/")) => 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 < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "%smved%04d", (BEFORE ? "0" : ""), 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;
|
|
# }
|
|
#'''
|
|
#
|