e8b68c4e88
Hopefully third times the charm. The previous solution pretty bluntly did not work outside of the recursive remove case, because the moment we mark the rid as deleted, the directory positions no longer get updates. It's not possible to update the directory position because we don't know how it maps into our mtree without a full seek from the dstart. After staring at it a bit, I think this solution should work: 1. Instead of marking the mid/rid as removed when dropping an mdir, we set the weight to zero and the trunk to zero, causing mdir lookups to return NOENT without actually going to disk. This is very important since later mdirs could be allocated on the same block, and going to disk can result in a corrupted lookup. 2. Eagerly seek to the next mid/rid after every lfsr_dir_read call. This puts us in a position where rid can be >= the current mdir weight without issues, and avoids degenerate cases that may be caused by recursive removes. 3. If we remove an opened dir, instead of marking the mdir as deleted, move the rid to the next rid. If the mdir was dropped, this leaves us with rid == mdir weight, and the mdir trunk == 0. The rid == mdir weight also occurs when we are creating a new file, so we have a bit of common behavior we can rely on. We just need to make sure that mdir updates respect the rid == mdir weight situation. 4. On each lfsr_dir_read call, we do an mtree seek of zero. This just serves to fix our mdir if our rid == mdir weight, without much additional code (yay for code reuse). The use of weight=0, trunk=0, for a dropped mdir here is key, and makes me wonder if this is a better indicator of a dropped mdir than another reserved mid value. This probably deserves some investigation later.
3979 lines
128 KiB
TOML
3979 lines
128 KiB
TOML
# Directory tests
|
|
|
|
|
|
## mkdir tests
|
|
|
|
[cases.t5_dirs_mkdir]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked with stat
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// and with dir_read
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that noent errors work
|
|
[cases.t5_dirs_noent]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to read a nonsense path
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "no", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "no") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that creating the same directory twice errors
|
|
[cases.t5_dirs_mkdir_exists]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// make the same directory, should error
|
|
lfsr_mkdir(&lfs, "ardvark") => LFS_ERR_EXIST;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test what happens if we try to make root
|
|
[cases.t5_dirs_mkdir_root]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// try to make root, which doesn't make sense
|
|
lfsr_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to make root, which doesn't make sense
|
|
lfsr_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that creating a directory with an invalid path errors
|
|
[cases.t5_dirs_mkdir_noent]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// make a nonsense directory, should error
|
|
lfsr_mkdir(&lfs, "no/hmm") => LFS_ERR_NOENT;
|
|
|
|
// make a nonsense child directory, should error
|
|
lfsr_mkdir(&lfs, "ardvark/no/hmm") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_siblings]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_children]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman/cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark/batman") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_backwards]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_2layers]
|
|
defines.N = [1, 2, 4, 8, 16]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// containing this many directories
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "child%04d", j);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", j);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_3layers]
|
|
defines.N = [1, 2, 4]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// containing this many directories
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// containing this many directories
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "child%04d", j);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "grandchild%04d", k);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
}
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", j);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char name[256];
|
|
sprintf(name, "grandchild%04d", k);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_many_linkedlist]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// create this many directory in a sort of linked-list by nesting
|
|
char name[4096];
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", i);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
if (i < N-1) {
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", i+1);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_mkdir_fuzz]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
defines.REMOUNT = [false, true]
|
|
defines.SEED = 'range(10)'
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
if (PARENT) {
|
|
err = lfsr_mkdir(&lfs, "pricklypear");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
}
|
|
|
|
// set up a simulation to compare against
|
|
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
|
lfs_size_t sim_size = 0;
|
|
|
|
uint32_t prng = SEED;
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
// choose a pseudo-random number, truncate to 4 decimals
|
|
lfs_size_t x = TEST_PRNG(&prng) % 1000;
|
|
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen? skip
|
|
if (j < sim_size && sim[j] == x) {
|
|
goto next;
|
|
}
|
|
|
|
// insert
|
|
memmove(&sim[j+1], &sim[j],
|
|
(sim_size-j)*sizeof(lfs_size_t));
|
|
sim_size += 1;
|
|
sim[j] = x;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// create a directory here
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
next:;
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// test that our directories match our simulation
|
|
for (lfs_size_t j = 0; j < sim_size; j++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), sim[j]);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", sim[j]);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < sim_size; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", sim[j]);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// clean up sim/lfs
|
|
free(sim);
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
# test that did collisions don't cause issues
|
|
[cases.t5_dirs_did_collisions]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_SNmwMTHH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "b_skvjpWJH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "c_OnOQhVPH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "d_puMpPjRH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "e_LptKHkHH", 10) == 0x12345678);
|
|
assert(lfs_crc32c(0, "f_lUoVuhJH", 10) == 0x12345678);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_SNmwMTHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_skvjpWJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_OnOQhVPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_puMpPjRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_LptKHkHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_lUoVuhJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_SNmwMTHH", &info) => 0;
|
|
assert(strcmp(info.name, "a_SNmwMTHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_skvjpWJH", &info) => 0;
|
|
assert(strcmp(info.name, "b_skvjpWJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_OnOQhVPH", &info) => 0;
|
|
assert(strcmp(info.name, "c_OnOQhVPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_puMpPjRH", &info) => 0;
|
|
assert(strcmp(info.name, "d_puMpPjRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_LptKHkHH", &info) => 0;
|
|
assert(strcmp(info.name, "e_LptKHkHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_lUoVuhJH", &info) => 0;
|
|
assert(strcmp(info.name, "f_lUoVuhJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_SNmwMTHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_skvjpWJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_OnOQhVPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_puMpPjRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_LptKHkHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_lUoVuhJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# these will also collide with the root
|
|
[cases.t5_dirs_did_zero]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_IplRNrPH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "b_iUwOsqRH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "c_UPNtkpHH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "d_jKLUSLJH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "e_VNunKMPH", 10) == 0x00000000);
|
|
assert(lfs_crc32c(0, "f_vknsvNRH", 10) == 0x00000000);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_IplRNrPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_iUwOsqRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_UPNtkpHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_jKLUSLJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_VNunKMPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_vknsvNRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_IplRNrPH", &info) => 0;
|
|
assert(strcmp(info.name, "a_IplRNrPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_iUwOsqRH", &info) => 0;
|
|
assert(strcmp(info.name, "b_iUwOsqRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_UPNtkpHH", &info) => 0;
|
|
assert(strcmp(info.name, "c_UPNtkpHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_jKLUSLJH", &info) => 0;
|
|
assert(strcmp(info.name, "d_jKLUSLJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_VNunKMPH", &info) => 0;
|
|
assert(strcmp(info.name, "e_VNunKMPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_vknsvNRH", &info) => 0;
|
|
assert(strcmp(info.name, "f_vknsvNRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_IplRNrPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_iUwOsqRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_UPNtkpHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_jKLUSLJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_VNunKMPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_vknsvNRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# these will need to rollover from 0xffffffff -> 0x00000000 correctly
|
|
#
|
|
# note this is true even if you truncate
|
|
[cases.t5_dirs_did_ones]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_iomlVKPH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "b_IJvqkHRH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "c_uOOJsIHH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "d_JTMkKuJH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "e_vQtPStPH", 10) == 0xffffffff);
|
|
assert(lfs_crc32c(0, "f_VtoMnwRH", 10) == 0xffffffff);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_iomlVKPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_IJvqkHRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_uOOJsIHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_JTMkKuJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_vQtPStPH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_VtoMnwRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_iomlVKPH", &info) => 0;
|
|
assert(strcmp(info.name, "a_iomlVKPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_IJvqkHRH", &info) => 0;
|
|
assert(strcmp(info.name, "b_IJvqkHRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_uOOJsIHH", &info) => 0;
|
|
assert(strcmp(info.name, "c_uOOJsIHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_JTMkKuJH", &info) => 0;
|
|
assert(strcmp(info.name, "d_JTMkKuJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_vQtPStPH", &info) => 0;
|
|
assert(strcmp(info.name, "e_vQtPStPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_VtoMnwRH", &info) => 0;
|
|
assert(strcmp(info.name, "f_VtoMnwRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_iomlVKPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_IJvqkHRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_uOOJsIHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_JTMkKuJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_vQtPStPH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_VtoMnwRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# these test some boundary conditions on the underlying leb128 encoding,
|
|
# if the leb128 disk-size is not calculated correctly these can cause
|
|
# issues
|
|
[cases.t5_dirs_did_leb128_boundaries]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
assert(lfs_crc32c(0, "a_IOtUptRH", 10) == 0x0000007f);
|
|
assert(lfs_crc32c(0, "b_nquQsKHH", 10) == 0x00000080);
|
|
assert(lfs_crc32c(0, "c_vwQtKjHH", 10) == 0x00000081);
|
|
assert(lfs_crc32c(0, "d_sVrvrWHH", 10) == 0x00003fff);
|
|
assert(lfs_crc32c(0, "e_thrRIsRH", 10) == 0x00004000);
|
|
assert(lfs_crc32c(0, "f_pNtQTPJH", 10) == 0x00004001);
|
|
|
|
// make directories
|
|
err = lfsr_mkdir(&lfs, "a_IOtUptRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "b_nquQsKHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "c_vwQtKjHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "d_sVrvrWHH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "e_thrRIsRH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "f_pNtQTPJH");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "a_IOtUptRH", &info) => 0;
|
|
assert(strcmp(info.name, "a_IOtUptRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "b_nquQsKHH", &info) => 0;
|
|
assert(strcmp(info.name, "b_nquQsKHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "c_vwQtKjHH", &info) => 0;
|
|
assert(strcmp(info.name, "c_vwQtKjHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "d_sVrvrWHH", &info) => 0;
|
|
assert(strcmp(info.name, "d_sVrvrWHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "e_thrRIsRH", &info) => 0;
|
|
assert(strcmp(info.name, "e_thrRIsRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "f_pNtQTPJH", &info) => 0;
|
|
assert(strcmp(info.name, "f_pNtQTPJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "a_IOtUptRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "b_nquQsKHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "c_vwQtKjHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "d_sVrvrWHH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "e_thrRIsRH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "f_pNtQTPJH") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
## dir remove tests
|
|
|
|
[cases.t5_dirs_rm]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked with stat
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
// and with dir_read
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// and remove the directory
|
|
lfsr_remove(&lfs, "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that remove worked with stat
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
|
|
// and with dir_read
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that noent errors work
|
|
[cases.t5_dirs_rm_noent]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to remove a nonsense directory
|
|
lfsr_remove(&lfs, "no") => LFS_ERR_NOENT;
|
|
|
|
// try to remove a directory in a nonsense directory
|
|
lfsr_remove(&lfs, "no/ardvark") => LFS_ERR_NOENT;
|
|
|
|
// try to remove a nonsense child directory
|
|
lfsr_remove(&lfs, "ardvark/no") => LFS_ERR_NOENT;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that we catch removing of a non-empty directory
|
|
[cases.t5_dirs_rm_notempty]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make a directory
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// fill it with stuff
|
|
err = lfsr_mkdir(&lfs, "ardvark/banana");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// try to remove the parent directory
|
|
lfsr_remove(&lfs, "ardvark") => LFS_ERR_NOTEMPTY;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// and check that this didn't interfere with our original directory
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/banana", &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "banana") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
## TODO make this work eventually
|
|
#
|
|
## test what happens if we try to remove root
|
|
#[cases.t5_dirs_rm_root]
|
|
#defines.REMOUNT = [false, true]
|
|
#reentrant = true
|
|
#code = '''
|
|
# // format once per test
|
|
# lfs_t lfs;
|
|
# int err = lfsr_mount(&lfs, cfg);
|
|
# if (err) {
|
|
# lfsr_format(&lfs, cfg) => 0;
|
|
# lfsr_mount(&lfs, cfg) => 0;
|
|
# }
|
|
#
|
|
# // try to remove root, which doesn't really make sense
|
|
# lfsr_remove(&lfs, "/") => LFS_ERR_INVAL;
|
|
#
|
|
# // make a directory
|
|
# err = lfsr_mkdir(&lfs, "ardvark");
|
|
# assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
#
|
|
# // try to remove root, which doesn't really make sense
|
|
# //
|
|
# // it doesn't really matter which error returns first, so accept both
|
|
# err = lfsr_remove(&lfs, "/");
|
|
# assert(err == LFS_ERR_NOTEMPTY || err == LFS_ERR_INVAL);
|
|
#
|
|
# // remount?
|
|
# if (REMOUNT) {
|
|
# lfsr_unmount(&lfs) => 0;
|
|
# lfsr_mount(&lfs, cfg) => 0;
|
|
# // grm should be zero here
|
|
# assert(lfs.grm[0] == 0);
|
|
# }
|
|
#
|
|
# // and check that this didn't interfere with our original directory
|
|
# struct lfs_info info;
|
|
# lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
# assert(strcmp(info.name, "ardvark") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
#
|
|
# lfsr_dir_t dir;
|
|
# lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
# lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
# assert(strcmp(info.name, ".") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
# assert(strcmp(info.name, "..") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
# assert(strcmp(info.name, "ardvark") == 0);
|
|
# assert(info.type == LFS_TYPE_DIR);
|
|
# lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
# lfsr_dir_close(&lfs, &dir) => 0;
|
|
#
|
|
# lfsr_unmount(&lfs) => 0;
|
|
#'''
|
|
|
|
[cases.t5_dirs_rm_siblings]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove each directory
|
|
lfsr_remove(&lfs, "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "batman") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "cantaloupe") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_children]
|
|
defines.REMOUNT = [false, true]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make some directories
|
|
err = lfsr_mkdir(&lfs, "ardvark");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
err = lfsr_mkdir(&lfs, "ardvark/batman/cantaloupe");
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark/batman") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "cantaloupe") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove each directory
|
|
lfsr_remove(&lfs, "ardvark/batman/cantaloupe") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "batman") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark/batman") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "ardvark/batman") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "ardvark") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/ardvark") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// remove another
|
|
lfsr_remove(&lfs, "ardvark") => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// check that our remove worked
|
|
lfsr_stat(&lfs, "ardvark", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/batman", &info) => LFS_ERR_NOENT;
|
|
lfsr_stat(&lfs, "ardvark/batman/cantaloupe", &info) => LFS_ERR_NOENT;
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_many]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMAINING = [64, 2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 32',
|
|
]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
}
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-REMAINING + i));
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-REMAINING + i));
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_many_backwards]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.REMAINING = [64, 2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 32',
|
|
]
|
|
reentrant = true
|
|
code = '''
|
|
// format once per test
|
|
lfs_t lfs;
|
|
int err = lfsr_mount(&lfs, cfg);
|
|
if (err) {
|
|
lfsr_format(&lfs, cfg) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
}
|
|
|
|
// make this many directories
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// now remove some number of directories
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
lfsr_remove(&lfs, name) => 0;
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our removes worked
|
|
for (lfs_size_t i = 0; i < N-REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", (int)(N-1-i));
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => LFS_ERR_NOENT;
|
|
}
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < REMAINING; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
[cases.t5_dirs_rm_many_2layers]
|
|
defines.N = [1, 2, 4, 8, 16]
|
|
defines.REMAINING = [2, 1, 0]
|
|
defines.REMOUNT = [false, true]
|
|
if = [
|
|
'N > REMAINING',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 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.grm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "child%04d", j);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", j);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
|
|
// 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.grm[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.grm[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',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 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.grm[0] == 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check that our mkdirs worked
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "child%04d", j);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d/grandchild%04d", i, j, k);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
sprintf(name, "grandchild%04d", k);
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
}
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", i);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "child%04d", j);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
for (lfs_size_t j = 0; j < N; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d/child%04d", i, j);
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t k = 0; k < N; k++) {
|
|
char name[256];
|
|
sprintf(name, "grandchild%04d", k);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
}
|
|
|
|
// 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.grm[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.grm[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.grm[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',
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
'!TEST_PL || N <= 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.grm[0] == 0);
|
|
}
|
|
}
|
|
|
|
// check that our mkdir worked
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", i);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
memset(name, 0, sizeof(name));
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
sprintf(&name[strlen(name)], "/dir%04d", i);
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, name) => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
if (i < N-1) {
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", i+1);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
}
|
|
|
|
// 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.grm[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;
|
|
'''
|
|
|
|
# TODO test dir seek
|
|
# TODO test dir seek with mkdirs
|
|
# TODO test dir seek with removes
|
|
# TODO test dir seek with renames
|
|
# TODO test dir seek end idempotency
|
|
# TODO test recursive removes with seeking (test pos updates)
|
|
|
|
# Recursive here just refers to deleting entries in a directory while
|
|
# iterating over the directory
|
|
#
|
|
# This is a useful feature, but it's unintuitive that this should have
|
|
# well-defined behavior, so make sure to test for it
|
|
[cases.t5_dirs_rm_many_recursive]
|
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
defines.PARENT = [false, true]
|
|
# this test sort of fights against itself when powerloss testing,
|
|
# limit it to a _very_ small number of entries for this reason
|
|
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;
|
|
}
|
|
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;
|
|
'''
|
|
|
|
[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) % 1000;
|
|
// insert into our sim
|
|
for (lfs_size_t j = 0;; j++) {
|
|
if (j >= sim_size || sim[j] >= x) {
|
|
// already seen? skip
|
|
if (j < sim_size && sim[j] == x) {
|
|
goto next;
|
|
}
|
|
|
|
// insert
|
|
memmove(&sim[j+1], &sim[j],
|
|
(sim_size-j)*sizeof(lfs_size_t));
|
|
sim_size += 1;
|
|
sim[j] = x;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// create a directory here
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), x);
|
|
err = lfsr_mkdir(&lfs, name);
|
|
assert(!err || (TEST_PL && err == LFS_ERR_EXIST));
|
|
|
|
} 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;
|
|
}
|
|
next:;
|
|
}
|
|
|
|
// remount?
|
|
if (REMOUNT) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, cfg) => 0;
|
|
// grm should be zero here
|
|
assert(lfs.grm[0] == 0);
|
|
}
|
|
|
|
// test that our directories match our simulation
|
|
for (lfs_size_t j = 0; j < sim_size; j++) {
|
|
char name[256];
|
|
sprintf(name, "%s/dir%04d", (PARENT ? "pricklypear" : ""), sim[j]);
|
|
struct lfs_info info;
|
|
lfsr_stat(&lfs, name, &info) => 0;
|
|
char name2[256];
|
|
sprintf(name2, "dir%04d", sim[j]);
|
|
assert(strcmp(info.name, name2) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
|
|
lfsr_dir_t dir;
|
|
lfsr_dir_open(&lfs, &dir, (PARENT ? "pricklypear" : "/")) => 0;
|
|
struct lfs_info info;
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, ".") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, "..") == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
for (lfs_size_t j = 0; j < sim_size; j++) {
|
|
char name[256];
|
|
sprintf(name, "dir%04d", sim[j]);
|
|
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
|
assert(strcmp(info.name, name) == 0);
|
|
assert(info.type == LFS_TYPE_DIR);
|
|
}
|
|
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
|
lfsr_dir_close(&lfs, &dir) => 0;
|
|
|
|
// clean up sim/lfs
|
|
free(sim);
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[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;
|
|
# }
|
|
#'''
|
|
#
|