Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChristopher Haster <geky@geky.net>2023-04-26 21:47:58 +0300
committerChristopher Haster <geky@geky.net>2023-04-26 21:47:58 +0300
commitb6773e68bf3f6377df3c555678acd636b0695a05 (patch)
tree603a62a2307af6155eaa5426d1d023f96e9d84c8 /tests
parentb33a5b3f856db91e556bc13ad4b7a6c86f75e892 (diff)
parent92298c749d868cbc248f00eabd644e5b08e0c8df (diff)
Merge remote-tracking branch 'origin/devel' into fix-dir-seek-endfix-dir-seek-end
Diffstat (limited to 'tests')
-rw-r--r--tests/test_alloc.toml292
-rw-r--r--tests/test_attrs.toml50
-rw-r--r--tests/test_badblocks.toml171
-rw-r--r--tests/test_bd.toml248
-rw-r--r--tests/test_compat.toml1360
-rw-r--r--tests/test_dirs.toml280
-rw-r--r--tests/test_entries.toml87
-rw-r--r--tests/test_evil.toml116
-rw-r--r--tests/test_exhaustion.toml274
-rw-r--r--tests/test_files.toml262
-rw-r--r--tests/test_interspersed.toml72
-rw-r--r--tests/test_move.toml458
-rw-r--r--tests/test_orphans.toml65
-rw-r--r--tests/test_paths.toml121
-rw-r--r--tests/test_powerloss.toml182
-rw-r--r--tests/test_relocations.toml174
-rw-r--r--tests/test_seek.toml97
-rw-r--r--tests/test_superblocks.toml86
-rw-r--r--tests/test_truncate.toml154
19 files changed, 3469 insertions, 1080 deletions
diff --git a/tests/test_alloc.toml b/tests/test_alloc.toml
index fa92da5..205efbb 100644
--- a/tests/test_alloc.toml
+++ b/tests/test_alloc.toml
@@ -1,27 +1,30 @@
# allocator tests
# note for these to work there are a number constraints on the device geometry
-if = 'LFS_BLOCK_CYCLES == -1'
+if = 'BLOCK_CYCLES == -1'
-[[case]] # parallel allocation test
-define.FILES = 3
-define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
+# parallel allocation test
+[cases.test_alloc_parallel]
+defines.FILES = 3
+defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
code = '''
- const char *names[FILES] = {"bacon", "eggs", "pancakes"};
+ const char *names[] = {"bacon", "eggs", "pancakes"};
lfs_file_t files[FILES];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "breakfast") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
lfs_file_open(&lfs, &files[n], path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
}
for (int n = 0; n < FILES; n++) {
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
for (lfs_size_t i = 0; i < SIZE; i += size) {
lfs_file_write(&lfs, &files[n], names[n], size) => size;
}
@@ -31,12 +34,15 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
for (lfs_size_t i = 0; i < SIZE; i += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
assert(memcmp(buffer, names[n], size) == 0);
}
@@ -45,23 +51,28 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # serial allocation test
-define.FILES = 3
-define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
+# serial allocation test
+[cases.test_alloc_serial]
+defines.FILES = 3
+defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
code = '''
- const char *names[FILES] = {"bacon", "eggs", "pancakes"};
+ const char *names[] = {"bacon", "eggs", "pancakes"};
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "breakfast") => 0;
lfs_unmount(&lfs) => 0;
for (int n = 0; n < FILES; n++) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
+ uint8_t buffer[1024];
memcpy(buffer, names[n], size);
for (int i = 0; i < SIZE; i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
@@ -70,12 +81,15 @@ code = '''
lfs_unmount(&lfs) => 0;
}
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
for (int i = 0; i < SIZE; i += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
assert(memcmp(buffer, names[n], size) == 0);
}
@@ -84,29 +98,32 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # parallel allocation reuse test
-define.FILES = 3
-define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
-define.CYCLES = [1, 10]
+# parallel allocation reuse test
+[cases.test_alloc_parallel_reuse]
+defines.FILES = 3
+defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
+defines.CYCLES = [1, 10]
code = '''
- const char *names[FILES] = {"bacon", "eggs", "pancakes"};
+ const char *names[] = {"bacon", "eggs", "pancakes"};
lfs_file_t files[FILES];
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
for (int c = 0; c < CYCLES; c++) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "breakfast") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
lfs_file_open(&lfs, &files[n], path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
}
for (int n = 0; n < FILES; n++) {
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
for (int i = 0; i < SIZE; i += size) {
lfs_file_write(&lfs, &files[n], names[n], size) => size;
}
@@ -116,12 +133,15 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
for (int i = 0; i < SIZE; i += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
assert(memcmp(buffer, names[n], size) == 0);
}
@@ -129,8 +149,9 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
lfs_remove(&lfs, path) => 0;
}
@@ -139,26 +160,31 @@ code = '''
}
'''
-[[case]] # serial allocation reuse test
-define.FILES = 3
-define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
-define.CYCLES = [1, 10]
+# serial allocation reuse test
+[cases.test_alloc_serial_reuse]
+defines.FILES = 3
+defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
+defines.CYCLES = [1, 10]
code = '''
- const char *names[FILES] = {"bacon", "eggs", "pancakes"};
+ const char *names[] = {"bacon", "eggs", "pancakes"};
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
for (int c = 0; c < CYCLES; c++) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "breakfast") => 0;
lfs_unmount(&lfs) => 0;
for (int n = 0; n < FILES; n++) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
+ uint8_t buffer[1024];
memcpy(buffer, names[n], size);
for (int i = 0; i < SIZE; i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
@@ -167,12 +193,15 @@ code = '''
lfs_unmount(&lfs) => 0;
}
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
- size = strlen(names[n]);
+ size_t size = strlen(names[n]);
for (int i = 0; i < SIZE; i += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
assert(memcmp(buffer, names[n], size) == 0);
}
@@ -180,8 +209,9 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int n = 0; n < FILES; n++) {
+ char path[1024];
sprintf(path, "breakfast/%s", names[n]);
lfs_remove(&lfs, path) => 0;
}
@@ -190,12 +220,16 @@ code = '''
}
'''
-[[case]] # exhaustion test
+# exhaustion test
+[cases.test_alloc_exhaustion]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
- size = strlen("exhaustion");
+ size_t size = strlen("exhaustion");
+ uint8_t buffer[1024];
memcpy(buffer, "exhaustion", size);
lfs_file_write(&lfs, &file, buffer, size) => size;
lfs_file_sync(&lfs, &file) => 0;
@@ -216,7 +250,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs_file_size(&lfs, &file) => size;
@@ -226,14 +260,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # exhaustion wraparound test
-define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-4)) / 3)'
+# exhaustion wraparound test
+[cases.test_alloc_exhaustion_wraparound]
+defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-4)) / 3)'
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "padding", LFS_O_WRONLY | LFS_O_CREAT);
- size = strlen("buffering");
+ size_t size = strlen("buffering");
+ uint8_t buffer[1024];
memcpy(buffer, "buffering", size);
for (int i = 0; i < SIZE; i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
@@ -263,7 +301,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs_file_size(&lfs, &file) => size;
@@ -274,17 +312,22 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # dir exhaustion test
+# dir exhaustion test
+[cases.test_alloc_dir_exhaustion]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// find out max file size
lfs_mkdir(&lfs, "exhaustiondir") => 0;
- size = strlen("blahblahblahblah");
+ size_t size = strlen("blahblahblahblah");
+ uint8_t buffer[1024];
memcpy(buffer, "blahblahblahblah", size);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
int count = 0;
+ int err;
while (true) {
err = lfs_file_write(&lfs, &file, buffer, size);
if (err < 0) {
@@ -323,17 +366,21 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # what if we have a bad block during an allocation scan?
+# what if we have a bad block during an allocation scan?
+[cases.test_alloc_bad_blocks]
in = "lfs.c"
-define.LFS_ERASE_CYCLES = 0xffffffff
-define.LFS_BADBLOCK_BEHAVIOR = 'LFS_TESTBD_BADBLOCK_READERROR'
+defines.ERASE_CYCLES = 0xffffffff
+defines.BADBLOCK_BEHAVIOR = 'LFS_EMUBD_BADBLOCK_READERROR'
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// first fill to exhaustion to find available space
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "waka");
- size = strlen("waka");
+ size_t size = strlen("waka");
lfs_size_t filesize = 0;
while (true) {
lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
@@ -345,7 +392,7 @@ code = '''
}
lfs_file_close(&lfs, &file) => 0;
// now fill all but a couple of blocks of the filesystem with data
- filesize -= 3*LFS_BLOCK_SIZE;
+ filesize -= 3*BLOCK_SIZE;
lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
strcpy((char*)buffer, "waka");
size = strlen("waka");
@@ -358,11 +405,11 @@ code = '''
lfs_unmount(&lfs) => 0;
// remount to force an alloc scan
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// but mark the head of our file as a "bad block", this is force our
// scan to bail early
- lfs_testbd_setwear(&cfg, fileblock, 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, fileblock, 0xffffffff) => 0;
lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
strcpy((char*)buffer, "chomp");
size = strlen("chomp");
@@ -377,7 +424,7 @@ code = '''
// now reverse the "bad block" and try to write the file again until we
// run out of space
- lfs_testbd_setwear(&cfg, fileblock, 0) => 0;
+ lfs_emubd_setwear(cfg, fileblock, 0) => 0;
lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
strcpy((char*)buffer, "chomp");
size = strlen("chomp");
@@ -393,7 +440,7 @@ code = '''
lfs_unmount(&lfs) => 0;
// check that the disk isn't hurt
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "pacman", LFS_O_RDONLY) => 0;
strcpy((char*)buffer, "waka");
size = strlen("waka");
@@ -411,24 +458,29 @@ code = '''
# on the geometry of the block device. But they are valuable. Eventually they
# should be removed and replaced with generalized tests.
-[[case]] # chained dir exhaustion test
-define.LFS_BLOCK_SIZE = 512
-define.LFS_BLOCK_COUNT = 1024
-if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
+# chained dir exhaustion test
+[cases.test_alloc_chained_dir_exhaustion]
+if = 'BLOCK_SIZE == 512'
+defines.BLOCK_COUNT = 1024
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// find out max file size
lfs_mkdir(&lfs, "exhaustiondir") => 0;
for (int i = 0; i < 10; i++) {
+ char path[1024];
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
lfs_mkdir(&lfs, path) => 0;
}
- size = strlen("blahblahblahblah");
+ size_t size = strlen("blahblahblahblah");
+ uint8_t buffer[1024];
memcpy(buffer, "blahblahblahblah", size);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
int count = 0;
+ int err;
while (true) {
err = lfs_file_write(&lfs, &file, buffer, size);
if (err < 0) {
@@ -443,6 +495,7 @@ code = '''
lfs_remove(&lfs, "exhaustion") => 0;
lfs_remove(&lfs, "exhaustiondir") => 0;
for (int i = 0; i < 10; i++) {
+ char path[1024];
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
lfs_remove(&lfs, path) => 0;
}
@@ -455,6 +508,7 @@ code = '''
lfs_file_sync(&lfs, &file) => 0;
for (int i = 0; i < 10; i++) {
+ char path[1024];
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
lfs_mkdir(&lfs, path) => 0;
}
@@ -482,27 +536,31 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # split dir test
-define.LFS_BLOCK_SIZE = 512
-define.LFS_BLOCK_COUNT = 1024
-if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
+# split dir test
+[cases.test_alloc_split_dir]
+if = 'BLOCK_SIZE == 512'
+defines.BLOCK_COUNT = 1024
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// create one block hole for half a directory
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "bump", LFS_O_WRONLY | LFS_O_CREAT) => 0;
- for (lfs_size_t i = 0; i < cfg.block_size; i += 2) {
+ for (lfs_size_t i = 0; i < cfg->block_size; i += 2) {
+ uint8_t buffer[1024];
memcpy(&buffer[i], "hi", 2);
}
- lfs_file_write(&lfs, &file, buffer, cfg.block_size) => cfg.block_size;
+ uint8_t buffer[1024];
+ lfs_file_write(&lfs, &file, buffer, cfg->block_size) => cfg->block_size;
lfs_file_close(&lfs, &file) => 0;
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
- size = strlen("blahblahblahblah");
+ size_t size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < (cfg.block_count-4)*(cfg.block_size-8);
+ i < (cfg->block_count-4)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -510,7 +568,7 @@ code = '''
// remount to force reset of lookahead
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// open hole
lfs_remove(&lfs, "bump") => 0;
@@ -518,30 +576,33 @@ code = '''
lfs_mkdir(&lfs, "splitdir") => 0;
lfs_file_open(&lfs, &file, "splitdir/bump",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
- for (lfs_size_t i = 0; i < cfg.block_size; i += 2) {
+ for (lfs_size_t i = 0; i < cfg->block_size; i += 2) {
memcpy(&buffer[i], "hi", 2);
}
- lfs_file_write(&lfs, &file, buffer, 2*cfg.block_size) => LFS_ERR_NOSPC;
+ lfs_file_write(&lfs, &file, buffer, 2*cfg->block_size) => LFS_ERR_NOSPC;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
'''
-[[case]] # outdated lookahead test
-define.LFS_BLOCK_SIZE = 512
-define.LFS_BLOCK_COUNT = 1024
-if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
+# outdated lookahead test
+[cases.test_alloc_outdated_lookahead]
+if = 'BLOCK_SIZE == 512'
+defines.BLOCK_COUNT = 1024
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// fill completely with two files
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "exhaustion1",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
- size = strlen("blahblahblahblah");
+ size_t size = strlen("blahblahblahblah");
+ uint8_t buffer[1024];
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2)/2)*(cfg.block_size-8);
+ i < ((cfg->block_count-2)/2)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -552,7 +613,7 @@ code = '''
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2+1)/2)*(cfg.block_size-8);
+ i < ((cfg->block_count-2+1)/2)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -560,7 +621,7 @@ code = '''
// remount to force reset of lookahead
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// rewrite one file
lfs_file_open(&lfs, &file, "exhaustion1",
@@ -569,7 +630,7 @@ code = '''
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2)/2)*(cfg.block_size-8);
+ i < ((cfg->block_count-2)/2)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -583,7 +644,7 @@ code = '''
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2+1)/2)*(cfg.block_size-8);
+ i < ((cfg->block_count-2+1)/2)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -592,21 +653,24 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # outdated lookahead and split dir test
-define.LFS_BLOCK_SIZE = 512
-define.LFS_BLOCK_COUNT = 1024
-if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
+# outdated lookahead and split dir test
+[cases.test_alloc_outdated_lookahead_split_dir]
+if = 'BLOCK_SIZE == 512'
+defines.BLOCK_COUNT = 1024
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// fill completely with two files
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "exhaustion1",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
- size = strlen("blahblahblahblah");
+ size_t size = strlen("blahblahblahblah");
+ uint8_t buffer[1024];
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2)/2)*(cfg.block_size-8);
+ i < ((cfg->block_count-2)/2)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -617,7 +681,7 @@ code = '''
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2+1)/2)*(cfg.block_size-8);
+ i < ((cfg->block_count-2+1)/2)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -625,7 +689,7 @@ code = '''
// remount to force reset of lookahead
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// rewrite one file with a hole of one block
lfs_file_open(&lfs, &file, "exhaustion1",
@@ -634,7 +698,7 @@ code = '''
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0;
- i < ((cfg.block_count-2)/2 - 1)*(cfg.block_size-8);
+ i < ((cfg->block_count-2)/2 - 1)*(cfg->block_size-8);
i += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
diff --git a/tests/test_attrs.toml b/tests/test_attrs.toml
index db8d0c7..3c69001 100644
--- a/tests/test_attrs.toml
+++ b/tests/test_attrs.toml
@@ -1,14 +1,17 @@
-[[case]] # set/get attribute
+[cases.test_attrs_get_set]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "hello") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ uint8_t buffer[1024];
memset(buffer, 0, sizeof(buffer));
lfs_setattr(&lfs, "hello", 'A', "aaaa", 4) => 0;
lfs_setattr(&lfs, "hello", 'B', "bbbbbb", 6) => 0;
@@ -60,7 +63,7 @@ code = '''
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
memset(buffer, 0, sizeof(buffer));
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
lfs_getattr(&lfs, "hello", 'B', buffer+4, 9) => 9;
@@ -76,17 +79,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # set/get root attribute
+[cases.test_attrs_get_set_root]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "hello") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ uint8_t buffer[1024];
memset(buffer, 0, sizeof(buffer));
lfs_setattr(&lfs, "/", 'A', "aaaa", 4) => 0;
lfs_setattr(&lfs, "/", 'B', "bbbbbb", 6) => 0;
@@ -137,7 +143,7 @@ code = '''
lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
memset(buffer, 0, sizeof(buffer));
lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
lfs_getattr(&lfs, "/", 'B', buffer+4, 9) => 9;
@@ -153,17 +159,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # set/get file attribute
+[cases.test_attrs_get_set_file]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "hello") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ uint8_t buffer[1024];
memset(buffer, 0, sizeof(buffer));
struct lfs_attr attrs1[] = {
{'A', buffer, 4},
@@ -238,7 +247,7 @@ code = '''
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
memset(buffer, 0, sizeof(buffer));
struct lfs_attr attrs3[] = {
{'A', buffer, 4},
@@ -260,20 +269,23 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # deferred file attributes
+[cases.test_attrs_deferred_file]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "hello") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_setattr(&lfs, "hello/hello", 'B', "fffffffff", 9) => 0;
lfs_setattr(&lfs, "hello/hello", 'C', "ccccc", 5) => 0;
+ uint8_t buffer[1024];
memset(buffer, 0, sizeof(buffer));
struct lfs_attr attrs1[] = {
{'B', "gggg", 4},
diff --git a/tests/test_badblocks.toml b/tests/test_badblocks.toml
index 06967a6..b50b393 100644
--- a/tests/test_badblocks.toml
+++ b/tests/test_badblocks.toml
@@ -1,28 +1,30 @@
# bad blocks with block cycles should be tested in test_relocations
-if = 'LFS_BLOCK_CYCLES == -1'
-
-[[case]] # single bad blocks
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_ERASE_CYCLES = 0xffffffff
-define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
-define.LFS_BADBLOCK_BEHAVIOR = [
- 'LFS_TESTBD_BADBLOCK_PROGERROR',
- 'LFS_TESTBD_BADBLOCK_ERASEERROR',
- 'LFS_TESTBD_BADBLOCK_READERROR',
- 'LFS_TESTBD_BADBLOCK_PROGNOOP',
- 'LFS_TESTBD_BADBLOCK_ERASENOOP',
+if = '(int32_t)BLOCK_CYCLES == -1'
+
+[cases.test_badblocks_single]
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.ERASE_CYCLES = 0xffffffff
+defines.ERASE_VALUE = [0x00, 0xff, -1]
+defines.BADBLOCK_BEHAVIOR = [
+ 'LFS_EMUBD_BADBLOCK_PROGERROR',
+ 'LFS_EMUBD_BADBLOCK_ERASEERROR',
+ 'LFS_EMUBD_BADBLOCK_READERROR',
+ 'LFS_EMUBD_BADBLOCK_PROGNOOP',
+ 'LFS_EMUBD_BADBLOCK_ERASENOOP',
]
-define.NAMEMULT = 64
-define.FILEMULT = 1
+defines.NAMEMULT = 64
+defines.FILEMULT = 1
code = '''
- for (lfs_block_t badblock = 2; badblock < LFS_BLOCK_COUNT; badblock++) {
- lfs_testbd_setwear(&cfg, badblock-1, 0) => 0;
- lfs_testbd_setwear(&cfg, badblock, 0xffffffff) => 0;
-
- lfs_format(&lfs, &cfg) => 0;
+ for (lfs_block_t badblock = 2; badblock < BLOCK_COUNT; badblock++) {
+ lfs_emubd_setwear(cfg, badblock-1, 0) => 0;
+ lfs_emubd_setwear(cfg, badblock, 0xffffffff) => 0;
+
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 1; i < 10; i++) {
+ uint8_t buffer[1024];
for (int j = 0; j < NAMEMULT; j++) {
buffer[j] = '0'+i;
}
@@ -34,10 +36,11 @@ code = '''
buffer[j+NAMEMULT+1] = '0'+i;
}
buffer[2*NAMEMULT+1] = '\0';
+ lfs_file_t file;
lfs_file_open(&lfs, &file, (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT) => 0;
- size = NAMEMULT;
+ lfs_size_t size = NAMEMULT;
for (int j = 0; j < i*FILEMULT; j++) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -46,12 +49,14 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 1; i < 10; i++) {
+ uint8_t buffer[1024];
for (int j = 0; j < NAMEMULT; j++) {
buffer[j] = '0'+i;
}
buffer[NAMEMULT] = '\0';
+ struct lfs_info info;
lfs_stat(&lfs, (char*)buffer, &info) => 0;
info.type => LFS_TYPE_DIR;
@@ -60,9 +65,10 @@ code = '''
buffer[j+NAMEMULT+1] = '0'+i;
}
buffer[2*NAMEMULT+1] = '\0';
+ lfs_file_t file;
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
- size = NAMEMULT;
+ int size = NAMEMULT;
for (int j = 0; j < i*FILEMULT; j++) {
uint8_t rbuffer[1024];
lfs_file_read(&lfs, &file, rbuffer, size) => size;
@@ -75,28 +81,30 @@ code = '''
}
'''
-[[case]] # region corruption (causes cascading failures)
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_ERASE_CYCLES = 0xffffffff
-define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
-define.LFS_BADBLOCK_BEHAVIOR = [
- 'LFS_TESTBD_BADBLOCK_PROGERROR',
- 'LFS_TESTBD_BADBLOCK_ERASEERROR',
- 'LFS_TESTBD_BADBLOCK_READERROR',
- 'LFS_TESTBD_BADBLOCK_PROGNOOP',
- 'LFS_TESTBD_BADBLOCK_ERASENOOP',
+[cases.test_badblocks_region_corruption] # (causes cascading failures)
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.ERASE_CYCLES = 0xffffffff
+defines.ERASE_VALUE = [0x00, 0xff, -1]
+defines.BADBLOCK_BEHAVIOR = [
+ 'LFS_EMUBD_BADBLOCK_PROGERROR',
+ 'LFS_EMUBD_BADBLOCK_ERASEERROR',
+ 'LFS_EMUBD_BADBLOCK_READERROR',
+ 'LFS_EMUBD_BADBLOCK_PROGNOOP',
+ 'LFS_EMUBD_BADBLOCK_ERASENOOP',
]
-define.NAMEMULT = 64
-define.FILEMULT = 1
+defines.NAMEMULT = 64
+defines.FILEMULT = 1
code = '''
- for (lfs_block_t i = 0; i < (LFS_BLOCK_COUNT-2)/2; i++) {
- lfs_testbd_setwear(&cfg, i+2, 0xffffffff) => 0;
+ for (lfs_block_t i = 0; i < (BLOCK_COUNT-2)/2; i++) {
+ lfs_emubd_setwear(cfg, i+2, 0xffffffff) => 0;
}
-
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 1; i < 10; i++) {
+ uint8_t buffer[1024];
for (int j = 0; j < NAMEMULT; j++) {
buffer[j] = '0'+i;
}
@@ -108,10 +116,11 @@ code = '''
buffer[j+NAMEMULT+1] = '0'+i;
}
buffer[2*NAMEMULT+1] = '\0';
+ lfs_file_t file;
lfs_file_open(&lfs, &file, (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT) => 0;
- size = NAMEMULT;
+ lfs_size_t size = NAMEMULT;
for (int j = 0; j < i*FILEMULT; j++) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -120,12 +129,14 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 1; i < 10; i++) {
+ uint8_t buffer[1024];
for (int j = 0; j < NAMEMULT; j++) {
buffer[j] = '0'+i;
}
buffer[NAMEMULT] = '\0';
+ struct lfs_info info;
lfs_stat(&lfs, (char*)buffer, &info) => 0;
info.type => LFS_TYPE_DIR;
@@ -134,9 +145,10 @@ code = '''
buffer[j+NAMEMULT+1] = '0'+i;
}
buffer[2*NAMEMULT+1] = '\0';
+ lfs_file_t file;
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
- size = NAMEMULT;
+ lfs_size_t size = NAMEMULT;
for (int j = 0; j < i*FILEMULT; j++) {
uint8_t rbuffer[1024];
lfs_file_read(&lfs, &file, rbuffer, size) => size;
@@ -148,28 +160,30 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # alternating corruption (causes cascading failures)
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_ERASE_CYCLES = 0xffffffff
-define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
-define.LFS_BADBLOCK_BEHAVIOR = [
- 'LFS_TESTBD_BADBLOCK_PROGERROR',
- 'LFS_TESTBD_BADBLOCK_ERASEERROR',
- 'LFS_TESTBD_BADBLOCK_READERROR',
- 'LFS_TESTBD_BADBLOCK_PROGNOOP',
- 'LFS_TESTBD_BADBLOCK_ERASENOOP',
+[cases.test_badblocks_alternating_corruption] # (causes cascading failures)
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.ERASE_CYCLES = 0xffffffff
+defines.ERASE_VALUE = [0x00, 0xff, -1]
+defines.BADBLOCK_BEHAVIOR = [
+ 'LFS_EMUBD_BADBLOCK_PROGERROR',
+ 'LFS_EMUBD_BADBLOCK_ERASEERROR',
+ 'LFS_EMUBD_BADBLOCK_READERROR',
+ 'LFS_EMUBD_BADBLOCK_PROGNOOP',
+ 'LFS_EMUBD_BADBLOCK_ERASENOOP',
]
-define.NAMEMULT = 64
-define.FILEMULT = 1
+defines.NAMEMULT = 64
+defines.FILEMULT = 1
code = '''
- for (lfs_block_t i = 0; i < (LFS_BLOCK_COUNT-2)/2; i++) {
- lfs_testbd_setwear(&cfg, (2*i) + 2, 0xffffffff) => 0;
+ for (lfs_block_t i = 0; i < (BLOCK_COUNT-2)/2; i++) {
+ lfs_emubd_setwear(cfg, (2*i) + 2, 0xffffffff) => 0;
}
-
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 1; i < 10; i++) {
+ uint8_t buffer[1024];
for (int j = 0; j < NAMEMULT; j++) {
buffer[j] = '0'+i;
}
@@ -181,10 +195,11 @@ code = '''
buffer[j+NAMEMULT+1] = '0'+i;
}
buffer[2*NAMEMULT+1] = '\0';
+ lfs_file_t file;
lfs_file_open(&lfs, &file, (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT) => 0;
- size = NAMEMULT;
+ lfs_size_t size = NAMEMULT;
for (int j = 0; j < i*FILEMULT; j++) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -193,12 +208,14 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 1; i < 10; i++) {
+ uint8_t buffer[1024];
for (int j = 0; j < NAMEMULT; j++) {
buffer[j] = '0'+i;
}
buffer[NAMEMULT] = '\0';
+ struct lfs_info info;
lfs_stat(&lfs, (char*)buffer, &info) => 0;
info.type => LFS_TYPE_DIR;
@@ -207,9 +224,10 @@ code = '''
buffer[j+NAMEMULT+1] = '0'+i;
}
buffer[2*NAMEMULT+1] = '\0';
+ lfs_file_t file;
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
- size = NAMEMULT;
+ lfs_size_t size = NAMEMULT;
for (int j = 0; j < i*FILEMULT; j++) {
uint8_t rbuffer[1024];
lfs_file_read(&lfs, &file, rbuffer, size) => size;
@@ -222,20 +240,21 @@ code = '''
'''
# other corner cases
-[[case]] # bad superblocks (corrupt 1 or 0)
-define.LFS_ERASE_CYCLES = 0xffffffff
-define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
-define.LFS_BADBLOCK_BEHAVIOR = [
- 'LFS_TESTBD_BADBLOCK_PROGERROR',
- 'LFS_TESTBD_BADBLOCK_ERASEERROR',
- 'LFS_TESTBD_BADBLOCK_READERROR',
- 'LFS_TESTBD_BADBLOCK_PROGNOOP',
- 'LFS_TESTBD_BADBLOCK_ERASENOOP',
+[cases.test_badblocks_superblocks] # (corrupt 1 or 0)
+defines.ERASE_CYCLES = 0xffffffff
+defines.ERASE_VALUE = [0x00, 0xff, -1]
+defines.BADBLOCK_BEHAVIOR = [
+ 'LFS_EMUBD_BADBLOCK_PROGERROR',
+ 'LFS_EMUBD_BADBLOCK_ERASEERROR',
+ 'LFS_EMUBD_BADBLOCK_READERROR',
+ 'LFS_EMUBD_BADBLOCK_PROGNOOP',
+ 'LFS_EMUBD_BADBLOCK_ERASENOOP',
]
code = '''
- lfs_testbd_setwear(&cfg, 0, 0xffffffff) => 0;
- lfs_testbd_setwear(&cfg, 1, 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, 0, 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, 1, 0xffffffff) => 0;
- lfs_format(&lfs, &cfg) => LFS_ERR_NOSPC;
- lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => LFS_ERR_NOSPC;
+ lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
'''
diff --git a/tests/test_bd.toml b/tests/test_bd.toml
new file mode 100644
index 0000000..8c6510d
--- /dev/null
+++ b/tests/test_bd.toml
@@ -0,0 +1,248 @@
+# These tests don't really test littlefs at all, they are here only to make
+# sure the underlying block device is working.
+#
+# Note we use 251, a prime, in places to avoid aliasing powers of 2.
+#
+
+[cases.test_bd_one_block]
+defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
+defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
+code = '''
+ uint8_t buffer[lfs_max(READ, PROG)];
+
+ // write data
+ cfg->erase(cfg, 0) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (i+j) % 251;
+ }
+ cfg->prog(cfg, 0, i, buffer, PROG) => 0;
+ }
+
+ // read data
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, 0, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (i+j) % 251);
+ }
+ }
+'''
+
+[cases.test_bd_two_block]
+defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
+defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
+code = '''
+ uint8_t buffer[lfs_max(READ, PROG)];
+ lfs_block_t block;
+
+ // write block 0
+ block = 0;
+ cfg->erase(cfg, block) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (block+i+j) % 251;
+ }
+ cfg->prog(cfg, block, i, buffer, PROG) => 0;
+ }
+
+ // read block 0
+ block = 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ // write block 1
+ block = 1;
+ cfg->erase(cfg, block) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (block+i+j) % 251;
+ }
+ cfg->prog(cfg, block, i, buffer, PROG) => 0;
+ }
+
+ // read block 1
+ block = 1;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ // read block 0 again
+ block = 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+'''
+
+[cases.test_bd_last_block]
+defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
+defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
+code = '''
+ uint8_t buffer[lfs_max(READ, PROG)];
+ lfs_block_t block;
+
+ // write block 0
+ block = 0;
+ cfg->erase(cfg, block) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (block+i+j) % 251;
+ }
+ cfg->prog(cfg, block, i, buffer, PROG) => 0;
+ }
+
+ // read block 0
+ block = 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ // write block n-1
+ block = cfg->block_count-1;
+ cfg->erase(cfg, block) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (block+i+j) % 251;
+ }
+ cfg->prog(cfg, block, i, buffer, PROG) => 0;
+ }
+
+ // read block n-1
+ block = cfg->block_count-1;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ // read block 0 again
+ block = 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+'''
+
+[cases.test_bd_powers_of_two]
+defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
+defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
+code = '''
+ uint8_t buffer[lfs_max(READ, PROG)];
+
+ // write/read every power of 2
+ lfs_block_t block = 1;
+ while (block < cfg->block_count) {
+ // write
+ cfg->erase(cfg, block) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (block+i+j) % 251;
+ }
+ cfg->prog(cfg, block, i, buffer, PROG) => 0;
+ }
+
+ // read
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ block *= 2;
+ }
+
+ // read every power of 2 again
+ block = 1;
+ while (block < cfg->block_count) {
+ // read
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ block *= 2;
+ }
+'''
+
+[cases.test_bd_fibonacci]
+defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
+defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
+code = '''
+ uint8_t buffer[lfs_max(READ, PROG)];
+
+ // write/read every fibonacci number on our device
+ lfs_block_t block = 1;
+ lfs_block_t block_ = 1;
+ while (block < cfg->block_count) {
+ // write
+ cfg->erase(cfg, block) => 0;
+ for (lfs_off_t i = 0; i < cfg->block_size; i += PROG) {
+ for (lfs_off_t j = 0; j < PROG; j++) {
+ buffer[j] = (block+i+j) % 251;
+ }
+ cfg->prog(cfg, block, i, buffer, PROG) => 0;
+ }
+
+ // read
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ lfs_block_t nblock = block + block_;
+ block_ = block;
+ block = nblock;
+ }
+
+ // read every fibonacci number again
+ block = 1;
+ block_ = 1;
+ while (block < cfg->block_count) {
+ // read
+ for (lfs_off_t i = 0; i < cfg->block_size; i += READ) {
+ cfg->read(cfg, block, i, buffer, READ) => 0;
+
+ for (lfs_off_t j = 0; j < READ; j++) {
+ LFS_ASSERT(buffer[j] == (block+i+j) % 251);
+ }
+ }
+
+ lfs_block_t nblock = block + block_;
+ block_ = block;
+ block = nblock;
+ }
+'''
+
+
+
+
diff --git a/tests/test_compat.toml b/tests/test_compat.toml
new file mode 100644
index 0000000..a36c38a
--- /dev/null
+++ b/tests/test_compat.toml
@@ -0,0 +1,1360 @@
+# Test for compatibility between different littlefs versions
+#
+# Note, these tests are a bit special. They expect to be linked against two
+# different versions of littlefs:
+# - lfs => the new/current version of littlefs
+# - lfsp => the previous version of littlefs
+#
+# If lfsp is not linked, and LFSP is not defined, these tests will alias
+# the relevant lfs types/functions as necessary so at least the tests can
+# themselves be tested locally.
+#
+# But to get value from these tests, it's expected that the previous version
+# of littlefs be linked in during CI, with the help of scripts/changeprefix.py
+#
+
+# alias littlefs symbols as needed
+#
+# there may be a better way to do this, but oh well, explicit aliases works
+code = '''
+#ifdef LFSP
+#define STRINGIZE(x) STRINGIZE_(x)
+#define STRINGIZE_(x) #x
+#include STRINGIZE(LFSP)
+#else
+#define LFSP_VERSION LFS_VERSION
+#define LFSP_VERSION_MAJOR LFS_VERSION_MAJOR
+#define LFSP_VERSION_MINOR LFS_VERSION_MINOR
+#define lfsp_t lfs_t
+#define lfsp_config lfs_config
+#define lfsp_format lfs_format
+#define lfsp_mount lfs_mount
+#define lfsp_unmount lfs_unmount
+#define lfsp_dir_t lfs_dir_t
+#define lfsp_info lfs_info
+#define LFSP_TYPE_REG LFS_TYPE_REG
+#define LFSP_TYPE_DIR LFS_TYPE_DIR
+#define lfsp_mkdir lfs_mkdir
+#define lfsp_dir_open lfs_dir_open
+#define lfsp_dir_read lfs_dir_read
+#define lfsp_dir_close lfs_dir_close
+#define lfsp_file_t lfs_file_t
+#define LFSP_O_RDONLY LFS_O_RDONLY
+#define LFSP_O_WRONLY LFS_O_WRONLY
+#define LFSP_O_CREAT LFS_O_CREAT
+#define LFSP_O_EXCL LFS_O_EXCL
+#define LFSP_SEEK_SET LFS_SEEK_SET
+#define lfsp_file_open lfs_file_open
+#define lfsp_file_write lfs_file_write
+#define lfsp_file_read lfs_file_read
+#define lfsp_file_seek lfs_file_seek
+#define lfsp_file_close lfs_file_close
+#endif
+'''
+
+
+
+## forward-compatibility tests ##
+
+# test we can mount in a new version
+[cases.test_compat_forward_mount]
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // confirm the previous mount works
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // now test the new mount
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_unmount(&lfs) => 0;
+'''
+
+# test we can read dirs in a new version
+[cases.test_compat_forward_read_dirs]
+defines.COUNT = 5
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // write COUNT dirs
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfsp_mkdir(&lfsp, name) => 0;
+ }
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // mount the new version
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+
+ // can we list the directories?
+ 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 (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_dir_read(&lfs, &dir, &info) => 1;
+ assert(info.type == LFS_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+ lfs_dir_close(&lfs, &dir) => 0;
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+# test we can read files in a new version
+[cases.test_compat_forward_read_files]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 4
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // write COUNT files
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfsp_file_open(&lfsp, &file, name,
+ LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // mount the new version
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+
+ // can we list the files?
+ 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 (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_dir_read(&lfs, &dir, &info) => 1;
+ assert(info.type == LFS_TYPE_REG);
+ char name[8];
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+ }
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+# test we can read files in dirs in a new version
+[cases.test_compat_forward_read_files_in_dirs]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 4
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // write COUNT files+dirs
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[16];
+ sprintf(name, "dir%03d", i);
+ lfsp_mkdir(&lfsp, name) => 0;
+
+ lfsp_file_t file;
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfsp_file_open(&lfsp, &file, name,
+ LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // mount the new version
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+
+ // can we list the directories?
+ 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 (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_dir_read(&lfs, &dir, &info) => 1;
+ assert(info.type == LFS_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+ lfs_dir_close(&lfs, &dir) => 0;
+
+ // can we list the files?
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfs_dir_t dir;
+ lfs_dir_open(&lfs, &dir, name) => 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);
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+ lfs_dir_close(&lfs, &dir) => 0;
+ }
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_file_t file;
+ char name[16];
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+# test we can write dirs in a new version
+[cases.test_compat_forward_write_dirs]
+defines.COUNT = 10
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // write COUNT/2 dirs
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ for (lfs_size_t i = 0; i < COUNT/2; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfsp_mkdir(&lfsp, name) => 0;
+ }
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // mount the new version
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+
+ // write another COUNT/2 dirs
+ for (lfs_size_t i = COUNT/2; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfs_mkdir(&lfs, name) => 0;
+ }
+
+ // can we list the directories?
+ 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 (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_dir_read(&lfs, &dir, &info) => 1;
+ assert(info.type == LFS_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+ lfs_dir_close(&lfs, &dir) => 0;
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+# test we can write files in a new version
+[cases.test_compat_forward_write_files]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 2
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // write half COUNT files
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ // write half
+ lfsp_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfsp_file_open(&lfsp, &file, name,
+ LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+
+ // skip the other half but keep our prng reproducible
+ for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
+ TEST_PRNG(&prng);
+ }
+ }
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // mount the new version
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+
+ // write half COUNT files
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ // skip half but keep our prng reproducible
+ for (lfs_size_t j = 0; j < SIZE/2; j++) {
+ TEST_PRNG(&prng);
+ }
+
+ // write the other half
+ lfs_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfs_file_open(&lfs, &file, name, LFS_O_WRONLY) => 0;
+ lfs_file_seek(&lfs, &file, SIZE/2, LFS_SEEK_SET) => SIZE/2;
+
+ for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+
+ // can we list the files?
+ 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 (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_dir_read(&lfs, &dir, &info) => 1;
+ assert(info.type == LFS_TYPE_REG);
+ char name[8];
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+ }
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+# test we can write files in dirs in a new version
+[cases.test_compat_forward_write_files_in_dirs]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 2
+if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
+code = '''
+ // create the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_format(&lfsp, &cfgp) => 0;
+
+ // write half COUNT files
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[16];
+ sprintf(name, "dir%03d", i);
+ lfsp_mkdir(&lfsp, name) => 0;
+
+ // write half
+ lfsp_file_t file;
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfsp_file_open(&lfsp, &file, name,
+ LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+
+ // skip the other half but keep our prng reproducible
+ for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
+ TEST_PRNG(&prng);
+ }
+ }
+ lfsp_unmount(&lfsp) => 0;
+
+
+ // mount the new version
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => 0;
+
+ // write half COUNT files
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ // skip half but keep our prng reproducible
+ for (lfs_size_t j = 0; j < SIZE/2; j++) {
+ TEST_PRNG(&prng);
+ }
+
+ // write the other half
+ lfs_file_t file;
+ char name[16];
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfs_file_open(&lfs, &file, name, LFS_O_WRONLY) => 0;
+ lfs_file_seek(&lfs, &file, SIZE/2, LFS_SEEK_SET) => SIZE/2;
+
+ for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+
+ // can we list the directories?
+ 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 (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_dir_read(&lfs, &dir, &info) => 1;
+ assert(info.type == LFS_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+ lfs_dir_close(&lfs, &dir) => 0;
+
+ // can we list the files?
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfs_dir_t dir;
+ lfs_dir_open(&lfs, &dir, name) => 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);
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+
+ lfs_dir_read(&lfs, &dir, &info) => 0;
+ lfs_dir_close(&lfs, &dir) => 0;
+ }
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_file_t file;
+ char name[16];
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfs_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfs_file_read(&lfs, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+
+
+## backwards-compatibility tests ##
+
+# test we can mount in an old version
+[cases.test_compat_backward_mount]
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the new version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // confirm the new mount works
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // now test the previous mount
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+# test we can read dirs in an old version
+[cases.test_compat_backward_read_dirs]
+defines.COUNT = 5
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the new version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // write COUNT dirs
+ lfs_mount(&lfs, cfg) => 0;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfs_mkdir(&lfs, name) => 0;
+ }
+ lfs_unmount(&lfs) => 0;
+
+
+ // mount the new version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+
+ // can we list the directories?
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, "/") => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+ lfsp_dir_close(&lfsp, &dir) => 0;
+
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+# test we can read files in an old version
+[cases.test_compat_backward_read_files]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 4
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the new version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // write COUNT files
+ lfs_mount(&lfs, cfg) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfs_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfs_file_open(&lfs, &file, name,
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+ lfs_unmount(&lfs) => 0;
+
+
+ // mount the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+
+ // can we list the files?
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, "/") => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_REG);
+ char name[8];
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+ }
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+# test we can read files in dirs in an old version
+[cases.test_compat_backward_read_files_in_dirs]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 4
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the new version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // write COUNT files+dirs
+ lfs_mount(&lfs, cfg) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[16];
+ sprintf(name, "dir%03d", i);
+ lfs_mkdir(&lfs, name) => 0;
+
+ lfs_file_t file;
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfs_file_open(&lfs, &file, name,
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ }
+ lfs_unmount(&lfs) => 0;
+
+
+ // mount the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+
+ // can we list the directories?
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, "/") => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+ lfsp_dir_close(&lfsp, &dir) => 0;
+
+ // can we list the files?
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, name) => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_REG);
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+ lfsp_dir_close(&lfsp, &dir) => 0;
+ }
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_file_t file;
+ char name[16];
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+# test we can write dirs in an old version
+[cases.test_compat_backward_write_dirs]
+defines.COUNT = 10
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the new version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // write COUNT/2 dirs
+ lfs_mount(&lfs, cfg) => 0;
+ for (lfs_size_t i = 0; i < COUNT/2; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfs_mkdir(&lfs, name) => 0;
+ }
+ lfs_unmount(&lfs) => 0;
+
+
+ // mount the previous version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+
+ // write another COUNT/2 dirs
+ for (lfs_size_t i = COUNT/2; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfsp_mkdir(&lfsp, name) => 0;
+ }
+
+ // can we list the directories?
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, "/") => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+ lfsp_dir_close(&lfsp, &dir) => 0;
+
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+# test we can write files in an old version
+[cases.test_compat_backward_write_files]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 2
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the previous version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // write half COUNT files
+ lfs_mount(&lfs, cfg) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ // write half
+ lfs_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfs_file_open(&lfs, &file, name,
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ // skip the other half but keep our prng reproducible
+ for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
+ TEST_PRNG(&prng);
+ }
+ }
+ lfs_unmount(&lfs) => 0;
+
+
+ // mount the new version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+
+ // write half COUNT files
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ // skip half but keep our prng reproducible
+ for (lfs_size_t j = 0; j < SIZE/2; j++) {
+ TEST_PRNG(&prng);
+ }
+
+ // write the other half
+ lfsp_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfsp_file_open(&lfsp, &file, name, LFSP_O_WRONLY) => 0;
+ lfsp_file_seek(&lfsp, &file, SIZE/2, LFSP_SEEK_SET) => SIZE/2;
+
+ for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+
+ // can we list the files?
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, "/") => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_REG);
+ char name[8];
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+ }
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_file_t file;
+ char name[8];
+ sprintf(name, "file%03d", i);
+ lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+# test we can write files in dirs in an old version
+[cases.test_compat_backward_write_files_in_dirs]
+defines.COUNT = 5
+defines.SIZE = [4, 32, 512, 8192]
+defines.CHUNK = 2
+if = 'LFS_VERSION == LFSP_VERSION'
+code = '''
+ // create the previous version
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // write half COUNT files
+ lfs_mount(&lfs, cfg) => 0;
+ uint32_t prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[16];
+ sprintf(name, "dir%03d", i);
+ lfs_mkdir(&lfs, name) => 0;
+
+ // write half
+ lfs_file_t file;
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfs_file_open(&lfs, &file, name,
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
+ for (lfs_size_t j = 0; j < SIZE/2; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfs_file_write(&lfs, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ // skip the other half but keep our prng reproducible
+ for (lfs_size_t j = SIZE/2; j < SIZE; j++) {
+ TEST_PRNG(&prng);
+ }
+ }
+ lfs_unmount(&lfs) => 0;
+
+
+ // mount the new version
+ struct lfsp_config cfgp;
+ memcpy(&cfgp, cfg, sizeof(cfgp));
+ lfsp_t lfsp;
+ lfsp_mount(&lfsp, &cfgp) => 0;
+
+ // write half COUNT files
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ // skip half but keep our prng reproducible
+ for (lfs_size_t j = 0; j < SIZE/2; j++) {
+ TEST_PRNG(&prng);
+ }
+
+ // write the other half
+ lfsp_file_t file;
+ char name[16];
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfsp_file_open(&lfsp, &file, name, LFSP_O_WRONLY) => 0;
+ lfsp_file_seek(&lfsp, &file, SIZE/2, LFSP_SEEK_SET) => SIZE/2;
+
+ for (lfs_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ chunk[k] = TEST_PRNG(&prng) & 0xff;
+ }
+
+ lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+
+ // can we list the directories?
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, "/") => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ }
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+ lfsp_dir_close(&lfsp, &dir) => 0;
+
+ // can we list the files?
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ char name[8];
+ sprintf(name, "dir%03d", i);
+ lfsp_dir_t dir;
+ lfsp_dir_open(&lfsp, &dir, name) => 0;
+ struct lfsp_info info;
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, ".") == 0);
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_DIR);
+ assert(strcmp(info.name, "..") == 0);
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 1;
+ assert(info.type == LFSP_TYPE_REG);
+ sprintf(name, "file%03d", i);
+ assert(strcmp(info.name, name) == 0);
+ assert(info.size == SIZE);
+
+ lfsp_dir_read(&lfsp, &dir, &info) => 0;
+ lfsp_dir_close(&lfsp, &dir) => 0;
+ }
+
+ // now can we read the files?
+ prng = 42;
+ for (lfs_size_t i = 0; i < COUNT; i++) {
+ lfsp_file_t file;
+ char name[16];
+ sprintf(name, "dir%03d/file%03d", i, i);
+ lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
+ for (lfs_size_t j = 0; j < SIZE; j += CHUNK) {
+ uint8_t chunk[CHUNK];
+ lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
+
+ for (lfs_size_t k = 0; k < CHUNK; k++) {
+ assert(chunk[k] == TEST_PRNG(&prng) & 0xff);
+ }
+ }
+ lfsp_file_close(&lfsp, &file) => 0;
+ }
+
+ lfsp_unmount(&lfsp) => 0;
+'''
+
+
+
+## incompatiblity tests ##
+
+# test that we fail to mount after a major version bump
+[cases.test_compat_major_incompat]
+in = 'lfs.c'
+code = '''
+ // create a superblock
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // bump the major version
+ //
+ // note we're messing around with internals to do this! this
+ // is not a user API
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_mdir_t mdir;
+ lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
+ lfs_superblock_t superblock = {
+ .version = LFS_DISK_VERSION + 0x00010000,
+ .block_size = lfs.cfg->block_size,
+ .block_count = lfs.cfg->block_count,
+ .name_max = lfs.name_max,
+ .file_max = lfs.file_max,
+ .attr_max = lfs.attr_max,
+ };
+ lfs_superblock_tole32(&superblock);
+ lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
+ {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
+ &superblock})) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // mount should now fail
+ lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
+'''
+
+# test that we fail to mount after a minor version bump
+[cases.test_compat_minor_incompat]
+in = 'lfs.c'
+code = '''
+ // create a superblock
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ // bump the minor version
+ //
+ // note we're messing around with internals to do this! this
+ // is not a user API
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_mdir_t mdir;
+ lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
+ lfs_superblock_t superblock = {
+ .version = LFS_DISK_VERSION + 0x00000001,
+ .block_size = lfs.cfg->block_size,
+ .block_count = lfs.cfg->block_count,
+ .name_max = lfs.name_max,
+ .file_max = lfs.file_max,
+ .attr_max = lfs.attr_max,
+ };
+ lfs_superblock_tole32(&superblock);
+ lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
+ {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
+ &superblock})) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // mount should now fail
+ lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
+'''
+
+# test that we correctly bump the minor version
+[cases.test_compat_minor_bump]
+in = 'lfs.c'
+if = 'LFS_DISK_VERSION_MINOR > 0'
+code = '''
+ // create a superblock
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
+ lfs_file_open(&lfs, &file, "test",
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
+ lfs_file_write(&lfs, &file, "testtest", 8) => 8;
+ lfs_file_close(&lfs, &file) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // write an old minor version
+ //
+ // note we're messing around with internals to do this! this
+ // is not a user API
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_mdir_t mdir;
+ lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
+ lfs_superblock_t superblock = {
+ .version = LFS_DISK_VERSION - 0x00000001,
+ .block_size = lfs.cfg->block_size,
+ .block_count = lfs.cfg->block_count,
+ .name_max = lfs.name_max,
+ .file_max = lfs.file_max,
+ .attr_max = lfs.attr_max,
+ };
+ lfs_superblock_tole32(&superblock);
+ lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
+ {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
+ &superblock})) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // mount should still work
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
+ uint8_t buffer[8];
+ lfs_file_read(&lfs, &file, buffer, 8) => 8;
+ assert(memcmp(buffer, "testtest", 8) == 0);
+ lfs_file_close(&lfs, &file) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // if we write, we need to bump the minor version
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_open(&lfs, &file, "test", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
+ lfs_file_write(&lfs, &file, "teeeeest", 8) => 8;
+ lfs_file_close(&lfs, &file) => 0;
+
+ // minor version should have changed
+ lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
+ lfs_dir_get(&lfs, &mdir, LFS_MKTAG(0x7ff, 0x3ff, 0),
+ LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
+ &superblock)
+ => LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock));
+ lfs_superblock_fromle32(&superblock);
+ assert((superblock.version >> 16) & 0xffff == LFS_DISK_VERSION_MAJOR);
+ assert((superblock.version >> 0) & 0xffff == LFS_DISK_VERSION_MINOR);
+ lfs_unmount(&lfs) => 0;
+
+ // and of course mount should still work
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
+ lfs_file_read(&lfs, &file, buffer, 8) => 8;
+ assert(memcmp(buffer, "teeeeest", 8) == 0);
+ lfs_file_close(&lfs, &file) => 0;
+
+ // minor version should have changed
+ lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
+ lfs_dir_get(&lfs, &mdir, LFS_MKTAG(0x7ff, 0x3ff, 0),
+ LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
+ &superblock)
+ => LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock));
+ lfs_superblock_fromle32(&superblock);
+ assert((superblock.version >> 16) & 0xffff == LFS_DISK_VERSION_MAJOR);
+ assert((superblock.version >> 0) & 0xffff == LFS_DISK_VERSION_MINOR);
+ lfs_unmount(&lfs) => 0;
+'''
diff --git a/tests/test_dirs.toml b/tests/test_dirs.toml
index 7ff46e6..4262a1a 100644
--- a/tests/test_dirs.toml
+++ b/tests/test_dirs.toml
@@ -1,8 +1,11 @@
-[[case]] # root
+[cases.test_dirs_root]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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);
@@ -14,20 +17,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # many directory creation
-define.N = 'range(0, 100, 3)'
+[cases.test_dirs_many_creation]
+defines.N = 'range(3, 100, 3)'
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&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_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);
@@ -35,6 +43,7 @@ code = '''
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);
@@ -45,20 +54,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # many directory removal
-define.N = 'range(3, 100, 11)'
+[cases.test_dirs_many_removal]
+defines.N = 'range(3, 100, 11)'
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&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_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);
@@ -66,6 +80,7 @@ code = '''
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);
@@ -75,14 +90,15 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ 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_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(info.type == LFS_TYPE_DIR);
@@ -95,20 +111,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # many directory rename
-define.N = 'range(3, 100, 11)'
+[cases.test_dirs_many_rename]
+defines.N = 'range(3, 100, 11)'
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&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_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);
@@ -116,6 +137,7 @@ code = '''
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);
@@ -125,7 +147,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 0; i < N; i++) {
char oldpath[128];
char newpath[128];
@@ -135,7 +157,7 @@ code = '''
}
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(info.type == LFS_TYPE_DIR);
@@ -144,6 +166,7 @@ code = '''
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);
@@ -154,29 +177,35 @@ code = '''
lfs_unmount(&lfs);
'''
-[[case]] # reentrant many directory creation/rename/removal
-define.N = [5, 11]
+[cases.test_dirs_many_reentrant]
+defines.N = [5, 11]
+if = 'BLOCK_COUNT >= 4*N'
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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);
@@ -184,6 +213,7 @@ code = '''
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);
@@ -209,6 +239,7 @@ code = '''
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);
@@ -218,6 +249,7 @@ code = '''
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;
}
@@ -234,22 +266,28 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # file creation
-define.N = 'range(3, 100, 11)'
+[cases.test_dirs_file_creation]
+defines.N = 'range(3, 100, 11)'
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&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_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);
@@ -257,6 +295,7 @@ code = '''
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);
@@ -267,22 +306,28 @@ code = '''
lfs_unmount(&lfs);
'''
-[[case]] # file removal
-define.N = 'range(0, 100, 3)'
+[cases.test_dirs_file_removal]
+defines.N = 'range(3, 100, 11)'
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&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_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);
@@ -290,6 +335,7 @@ code = '''
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);
@@ -299,14 +345,15 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ 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_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(info.type == LFS_TYPE_DIR);
@@ -319,22 +366,28 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # file rename
-define.N = 'range(0, 100, 3)'
+[cases.test_dirs_file_rename]
+defines.N = 'range(3, 100, 11)'
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&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_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);
@@ -342,6 +395,7 @@ code = '''
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);
@@ -351,7 +405,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 0; i < N; i++) {
char oldpath[128];
char newpath[128];
@@ -361,7 +415,7 @@ code = '''
}
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(info.type == LFS_TYPE_DIR);
@@ -370,6 +424,7 @@ code = '''
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);
@@ -380,29 +435,36 @@ code = '''
lfs_unmount(&lfs);
'''
-[[case]] # reentrant file creation/rename/removal
-define.N = [5, 25]
+[cases.test_dirs_file_reentrant]
+defines.N = [5, 25]
+if = 'N < BLOCK_COUNT/2'
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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);
@@ -410,6 +472,7 @@ code = '''
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);
@@ -435,6 +498,7 @@ code = '''
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);
@@ -444,6 +508,7 @@ code = '''
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;
}
@@ -460,24 +525,28 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # nested directories
+[cases.test_dirs_nested]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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_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_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;
@@ -498,21 +567,21 @@ code = '''
lfs_unmount(&lfs) => 0;
// try removing?
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY;
lfs_unmount(&lfs) => 0;
// try renaming?
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "potato", "coldpotato") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 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_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;
@@ -520,7 +589,7 @@ code = '''
lfs_unmount(&lfs) => 0;
// try cross-directory renaming
- lfs_mount(&lfs, &cfg) => 0;
+ 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;
@@ -536,7 +605,7 @@ code = '''
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 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);
@@ -558,7 +627,7 @@ code = '''
lfs_unmount(&lfs) => 0;
// final remove
- lfs_mount(&lfs, &cfg) => 0;
+ 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;
@@ -568,7 +637,7 @@ code = '''
lfs_remove(&lfs, "hotpotato") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -584,17 +653,22 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # recursive remove
-define.N = [10, 100]
+[cases.test_dirs_recursive_remove]
+defines.N = [10, 100]
+if = 'N < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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);
@@ -602,6 +676,7 @@ code = '''
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);
@@ -611,7 +686,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs);
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY;
lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
@@ -622,6 +697,7 @@ code = '''
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);
@@ -636,22 +712,24 @@ code = '''
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
lfs_unmount(&lfs) => 0;
'''
-[[case]] # other error cases
+[cases.test_dirs_other_errors]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "potato") => LFS_ERR_EXIST;
lfs_mkdir(&lfs, "burito") => LFS_ERR_EXIST;
@@ -659,6 +737,7 @@ code = '''
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;
@@ -678,6 +757,7 @@ code = '''
// 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);
@@ -696,7 +776,7 @@ code = '''
lfs_unmount(&lfs) => 0;
// or on disk
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(info.type == LFS_TYPE_DIR);
@@ -715,13 +795,16 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # directory seek
-define.COUNT = [4, 128, 132]
+[cases.test_dirs_seek]
+defines.COUNT = [4, 128, 132]
+if = 'COUNT < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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;
}
@@ -729,8 +812,10 @@ code = '''
// try seeking to each dir entry
for (int j = 0; j < COUNT; j++) {
- lfs_mount(&lfs, &cfg) => 0;
+ 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);
@@ -739,6 +824,7 @@ code = '''
assert(info.type == LFS_TYPE_DIR);
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);
@@ -748,13 +834,14 @@ code = '''
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%03d", 0);
+ sprintf(path, "kitty%03u", 0);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
@@ -776,8 +863,10 @@ code = '''
}
// try seeking to end of dir
- lfs_mount(&lfs, &cfg) => 0;
+ 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);
@@ -786,6 +875,7 @@ code = '''
assert(info.type == LFS_TYPE_DIR);
for (int i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "kitty%03d", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, path) == 0);
@@ -800,6 +890,7 @@ code = '''
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_rewind(&lfs, &dir) => 0;
+ char path[1024];
sprintf(path, "kitty%03d", 0);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -818,20 +909,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # root seek
-define.COUNT = [4, 128, 132]
+[cases.test_dirs_toot_seek]
+defines.COUNT = [4, 128, 132]
+if = 'COUNT < BLOCK_COUNT/2'
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ 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 = 0; j < COUNT; j++) {
- lfs_mount(&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(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
@@ -840,6 +936,7 @@ code = '''
assert(info.type == LFS_TYPE_DIR);
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);
@@ -849,13 +946,14 @@ code = '''
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%03d", 0);
+ sprintf(path, "hi%03u", 0);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
@@ -877,8 +975,10 @@ code = '''
}
// try seeking to end of dir
- lfs_mount(&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(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
@@ -887,6 +987,7 @@ code = '''
assert(info.type == LFS_TYPE_DIR);
for (int i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "hi%03d", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, path) == 0);
@@ -901,6 +1002,7 @@ code = '''
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_rewind(&lfs, &dir) => 0;
+ char path[1024];
sprintf(path, "hi%03d", 0);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
diff --git a/tests/test_entries.toml b/tests/test_entries.toml
index 81e175f..7aa551e 100644
--- a/tests/test_entries.toml
+++ b/tests/test_entries.toml
@@ -2,19 +2,23 @@
# Note that these tests are intended for 512 byte inline sizes. They should
# still pass with other inline sizes but wouldn't be testing anything.
-define.LFS_CACHE_SIZE = 512
-if = 'LFS_CACHE_SIZE % LFS_PROG_SIZE == 0 && LFS_CACHE_SIZE == 512'
+defines.CACHE_SIZE = 512
+if = 'CACHE_SIZE % PROG_SIZE == 0 && CACHE_SIZE == 512'
-[[case]] # entry grow test
+[cases.test_entries_grow]
code = '''
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// write hi0 20
+ char path[1024];
+ lfs_size_t size;
sprintf(path, "hi0"); size = 20;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
memset(wbuffer, 'c', size);
@@ -94,16 +98,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # entry shrink test
+[cases.test_entries_shrink]
code = '''
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// write hi0 20
+ char path[1024];
+ lfs_size_t size;
sprintf(path, "hi0"); size = 20;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
memset(wbuffer, 'c', size);
@@ -183,16 +191,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # entry spill test
+[cases.test_entries_spill]
code = '''
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// write hi0 200
+ char path[1024];
+ lfs_size_t size;
sprintf(path, "hi0"); size = 200;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
memset(wbuffer, 'c', size);
@@ -256,16 +268,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # entry push spill test
+[cases.test_entries_push_spill]
code = '''
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// write hi0 200
+ char path[1024];
+ lfs_size_t size;
sprintf(path, "hi0"); size = 200;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
memset(wbuffer, 'c', size);
@@ -345,16 +361,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # entry push spill two test
+[cases.test_entries_push_spill_two]
code = '''
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// write hi0 200
+ char path[1024];
+ lfs_size_t size;
sprintf(path, "hi0"); size = 200;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
memset(wbuffer, 'c', size);
@@ -449,16 +469,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # entry drop test
+[cases.test_entries_drop]
code = '''
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// write hi0 200
+ char path[1024];
+ lfs_size_t size;
sprintf(path, "hi0"); size = 200;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
memset(wbuffer, 'c', size);
@@ -491,6 +515,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_remove(&lfs, "hi1") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "hi1", &info) => LFS_ERR_NOENT;
// read hi0 200
sprintf(path, "hi0"); size = 200;
@@ -547,15 +572,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # create too big
+[cases.test_entries_create_too_big]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ char path[1024];
memset(path, 'm', 200);
path[200] = '\0';
- size = 400;
+ lfs_size_t size = 400;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
uint8_t wbuffer[1024];
@@ -572,15 +600,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # resize too big
+[cases.test_entries_resize_too_big]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ char path[1024];
memset(path, 'm', 200);
path[200] = '\0';
- size = 40;
+ lfs_size_t size = 40;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
uint8_t wbuffer[1024];
diff --git a/tests/test_evil.toml b/tests/test_evil.toml
index 920d3a0..4acd5ef 100644
--- a/tests/test_evil.toml
+++ b/tests/test_evil.toml
@@ -3,16 +3,17 @@
# invalid pointer tests (outside of block_count)
-[[case]] # invalid tail-pointer test
-define.TAIL_TYPE = ['LFS_TYPE_HARDTAIL', 'LFS_TYPE_SOFTTAIL']
-define.INVALSET = [0x3, 0x1, 0x2]
+[cases.test_evil_invalid_tail_pointer]
+defines.TAIL_TYPE = ['LFS_TYPE_HARDTAIL', 'LFS_TYPE_SOFTTAIL']
+defines.INVALSET = [0x3, 0x1, 0x2]
in = "lfs.c"
code = '''
// create littlefs
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// change tail-pointer to invalid pointers
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
@@ -23,25 +24,27 @@ code = '''
lfs_deinit(&lfs) => 0;
// test that mount fails gracefully
- lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
+ lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
'''
-[[case]] # invalid dir pointer test
-define.INVALSET = [0x3, 0x1, 0x2]
+[cases.test_evil_invalid_dir_pointer]
+defines.INVALSET = [0x3, 0x1, 0x2]
in = "lfs.c"
code = '''
// create littlefs
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// make a dir
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "dir_here") => 0;
lfs_unmount(&lfs) => 0;
// change the dir pointer to be invalid
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
// make sure id 1 == our directory
+ uint8_t buffer[1024];
lfs_dir_get(&lfs, &mdir,
LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_NAME, 1, strlen("dir_here")), buffer)
@@ -57,14 +60,17 @@ code = '''
// test that accessing our bad dir fails, note there's a number
// of ways to access the dir, some can fail, but some don't
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "dir_here", &info) => 0;
assert(strcmp(info.name, "dir_here") == 0);
assert(info.type == LFS_TYPE_DIR);
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "dir_here") => LFS_ERR_CORRUPT;
lfs_stat(&lfs, "dir_here/file_here", &info) => LFS_ERR_CORRUPT;
lfs_dir_open(&lfs, &dir, "dir_here/dir_here") => LFS_ERR_CORRUPT;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "dir_here/file_here",
LFS_O_RDONLY) => LFS_ERR_CORRUPT;
lfs_file_open(&lfs, &file, "dir_here/file_here",
@@ -72,24 +78,27 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # invalid file pointer test
+[cases.test_evil_invalid_file_pointer]
in = "lfs.c"
-define.SIZE = [10, 1000, 100000] # faked file size
+defines.SIZE = [10, 1000, 100000] # faked file size
code = '''
// create littlefs
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// make a file
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "file_here",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
// change the file pointer to be invalid
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
// make sure id 1 == our file
+ uint8_t buffer[1024];
lfs_dir_get(&lfs, &mdir,
LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_NAME, 1, strlen("file_here")), buffer)
@@ -103,7 +112,8 @@ code = '''
// test that accessing our bad file fails, note there's a number
// of ways to access the dir, some can fail, but some don't
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "file_here", &info) => 0;
assert(strcmp(info.name, "file_here") == 0);
assert(info.type == LFS_TYPE_REG);
@@ -114,20 +124,22 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
// any allocs that traverse CTZ must unfortunately must fail
- if (SIZE > 2*LFS_BLOCK_SIZE) {
+ if (SIZE > 2*BLOCK_SIZE) {
lfs_mkdir(&lfs, "dir_here") => LFS_ERR_CORRUPT;
}
lfs_unmount(&lfs) => 0;
'''
-[[case]] # invalid pointer in CTZ skip-list test
-define.SIZE = ['2*LFS_BLOCK_SIZE', '3*LFS_BLOCK_SIZE', '4*LFS_BLOCK_SIZE']
+[cases.test_evil_invalid_ctz_pointer] # invalid pointer in CTZ skip-list test
+defines.SIZE = ['2*BLOCK_SIZE', '3*BLOCK_SIZE', '4*BLOCK_SIZE']
in = "lfs.c"
code = '''
// create littlefs
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// make a file
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "file_here",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
for (int i = 0; i < SIZE; i++) {
@@ -137,10 +149,11 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
// change pointer in CTZ skip-list to be invalid
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
// make sure id 1 == our file and get our CTZ structure
+ uint8_t buffer[4*BLOCK_SIZE];
lfs_dir_get(&lfs, &mdir,
LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_NAME, 1, strlen("file_here")), buffer)
@@ -153,18 +166,19 @@ code = '''
=> LFS_MKTAG(LFS_TYPE_CTZSTRUCT, 1, sizeof(struct lfs_ctz));
lfs_ctz_fromle32(&ctz);
// rewrite block to contain bad pointer
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
+ uint8_t bbuffer[BLOCK_SIZE];
+ cfg->read(cfg, ctz.head, 0, bbuffer, BLOCK_SIZE) => 0;
uint32_t bad = lfs_tole32(0xcccccccc);
memcpy(&bbuffer[0], &bad, sizeof(bad));
memcpy(&bbuffer[4], &bad, sizeof(bad));
- cfg.erase(&cfg, ctz.head) => 0;
- cfg.prog(&cfg, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
+ cfg->erase(cfg, ctz.head) => 0;
+ cfg->prog(cfg, ctz.head, 0, bbuffer, BLOCK_SIZE) => 0;
lfs_deinit(&lfs) => 0;
// test that accessing our bad file fails, note there's a number
// of ways to access the dir, some can fail, but some don't
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "file_here", &info) => 0;
assert(strcmp(info.name, "file_here") == 0);
assert(info.type == LFS_TYPE_REG);
@@ -175,22 +189,23 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
// any allocs that traverse CTZ must unfortunately must fail
- if (SIZE > 2*LFS_BLOCK_SIZE) {
+ if (SIZE > 2*BLOCK_SIZE) {
lfs_mkdir(&lfs, "dir_here") => LFS_ERR_CORRUPT;
}
lfs_unmount(&lfs) => 0;
'''
-[[case]] # invalid gstate pointer
-define.INVALSET = [0x3, 0x1, 0x2]
+[cases.test_evil_invalid_gstate_pointer]
+defines.INVALSET = [0x3, 0x1, 0x2]
in = "lfs.c"
code = '''
// create littlefs
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// create an invalid gstate
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
lfs_fs_prepmove(&lfs, 1, (lfs_block_t [2]){
@@ -202,21 +217,22 @@ code = '''
// test that mount fails gracefully
// mount may not fail, but our first alloc should fail when
// we try to fix the gstate
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "should_fail") => LFS_ERR_CORRUPT;
lfs_unmount(&lfs) => 0;
'''
# cycle detection/recovery tests
-[[case]] # metadata-pair threaded-list loop test
+[cases.test_evil_mdir_loop] # metadata-pair threaded-list loop test
in = "lfs.c"
code = '''
// create littlefs
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// change tail-pointer to point to ourself
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
@@ -225,20 +241,21 @@ code = '''
lfs_deinit(&lfs) => 0;
// test that mount fails gracefully
- lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
+ lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
'''
-[[case]] # metadata-pair threaded-list 2-length loop test
+[cases.test_evil_mdir_loop2] # metadata-pair threaded-list 2-length loop test
in = "lfs.c"
code = '''
// create littlefs with child dir
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "child") => 0;
lfs_unmount(&lfs) => 0;
// find child
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_block_t pair[2];
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
@@ -255,20 +272,21 @@ code = '''
lfs_deinit(&lfs) => 0;
// test that mount fails gracefully
- lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
+ lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
'''
-[[case]] # metadata-pair threaded-list 1-length child loop test
+[cases.test_evil_mdir_loop_child] # metadata-pair threaded-list 1-length child loop test
in = "lfs.c"
code = '''
// create littlefs with child dir
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "child") => 0;
lfs_unmount(&lfs) => 0;
// find child
- lfs_init(&lfs, &cfg) => 0;
+ lfs_init(&lfs, cfg) => 0;
lfs_mdir_t mdir;
lfs_block_t pair[2];
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
@@ -284,5 +302,5 @@ code = '''
lfs_deinit(&lfs) => 0;
// test that mount fails gracefully
- lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
+ lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
'''
diff --git a/tests/test_exhaustion.toml b/tests/test_exhaustion.toml
index 569611c..2cf6aed 100644
--- a/tests/test_exhaustion.toml
+++ b/tests/test_exhaustion.toml
@@ -1,46 +1,50 @@
-[[case]] # test running a filesystem to exhaustion
-define.LFS_ERASE_CYCLES = 10
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
-define.LFS_BADBLOCK_BEHAVIOR = [
- 'LFS_TESTBD_BADBLOCK_PROGERROR',
- 'LFS_TESTBD_BADBLOCK_ERASEERROR',
- 'LFS_TESTBD_BADBLOCK_READERROR',
- 'LFS_TESTBD_BADBLOCK_PROGNOOP',
- 'LFS_TESTBD_BADBLOCK_ERASENOOP',
+# test running a filesystem to exhaustion
+[cases.test_exhaustion_normal]
+defines.ERASE_CYCLES = 10
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
+defines.BADBLOCK_BEHAVIOR = [
+ 'LFS_EMUBD_BADBLOCK_PROGERROR',
+ 'LFS_EMUBD_BADBLOCK_ERASEERROR',
+ 'LFS_EMUBD_BADBLOCK_READERROR',
+ 'LFS_EMUBD_BADBLOCK_PROGNOOP',
+ 'LFS_EMUBD_BADBLOCK_ERASENOOP',
]
-define.FILES = 10
+defines.FILES = 10
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "roadrunner") => 0;
lfs_unmount(&lfs) => 0;
uint32_t cycle = 0;
while (true) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// chose name, roughly random seed, and random 2^n size
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
assert(res == 1 || res == LFS_ERR_NOSPC);
if (res == LFS_ERR_NOSPC) {
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
lfs_unmount(&lfs) => 0;
goto exhausted;
}
}
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
lfs_unmount(&lfs) => 0;
@@ -50,13 +54,15 @@ code = '''
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
char r;
lfs_file_read(&lfs, &file, &r, 1) => 1;
assert(r == c);
@@ -71,10 +77,12 @@ code = '''
exhausted:
// should still be readable
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
+ struct lfs_info info;
lfs_stat(&lfs, path, &info) => 0;
}
lfs_unmount(&lfs) => 0;
@@ -82,47 +90,51 @@ exhausted:
LFS_WARN("completed %d cycles", cycle);
'''
-[[case]] # test running a filesystem to exhaustion
- # which also requires expanding superblocks
-define.LFS_ERASE_CYCLES = 10
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
-define.LFS_BADBLOCK_BEHAVIOR = [
- 'LFS_TESTBD_BADBLOCK_PROGERROR',
- 'LFS_TESTBD_BADBLOCK_ERASEERROR',
- 'LFS_TESTBD_BADBLOCK_READERROR',
- 'LFS_TESTBD_BADBLOCK_PROGNOOP',
- 'LFS_TESTBD_BADBLOCK_ERASENOOP',
+# test running a filesystem to exhaustion
+# which also requires expanding superblocks
+[cases.test_exhaustion_superblocks]
+defines.ERASE_CYCLES = 10
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
+defines.BADBLOCK_BEHAVIOR = [
+ 'LFS_EMUBD_BADBLOCK_PROGERROR',
+ 'LFS_EMUBD_BADBLOCK_ERASEERROR',
+ 'LFS_EMUBD_BADBLOCK_READERROR',
+ 'LFS_EMUBD_BADBLOCK_PROGNOOP',
+ 'LFS_EMUBD_BADBLOCK_ERASENOOP',
]
-define.FILES = 10
+defines.FILES = 10
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
uint32_t cycle = 0;
while (true) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// chose name, roughly random seed, and random 2^n size
+ char path[1024];
sprintf(path, "test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
assert(res == 1 || res == LFS_ERR_NOSPC);
if (res == LFS_ERR_NOSPC) {
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
lfs_unmount(&lfs) => 0;
goto exhausted;
}
}
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
lfs_unmount(&lfs) => 0;
@@ -132,13 +144,15 @@ code = '''
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
sprintf(path, "test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
char r;
lfs_file_read(&lfs, &file, &r, 1) => 1;
assert(r == c);
@@ -153,9 +167,11 @@ code = '''
exhausted:
// should still be readable
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
+ struct lfs_info info;
sprintf(path, "test%d", i);
lfs_stat(&lfs, path, &info) => 0;
}
@@ -169,51 +185,55 @@ exhausted:
# into increasing the block devices lifetime. This is something we can actually
# check for.
-[[case]] # wear-level test running a filesystem to exhaustion
-define.LFS_ERASE_CYCLES = 20
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
-define.FILES = 10
+# wear-level test running a filesystem to exhaustion
+[cases.test_exhuastion_wear_leveling]
+defines.ERASE_CYCLES = 20
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
+defines.FILES = 10
code = '''
uint32_t run_cycles[2];
- const uint32_t run_block_count[2] = {LFS_BLOCK_COUNT/2, LFS_BLOCK_COUNT};
+ const uint32_t run_block_count[2] = {BLOCK_COUNT/2, BLOCK_COUNT};
for (int run = 0; run < 2; run++) {
- for (lfs_block_t b = 0; b < LFS_BLOCK_COUNT; b++) {
- lfs_testbd_setwear(&cfg, b,
- (b < run_block_count[run]) ? 0 : LFS_ERASE_CYCLES) => 0;
+ for (lfs_block_t b = 0; b < BLOCK_COUNT; b++) {
+ lfs_emubd_setwear(cfg, b,
+ (b < run_block_count[run]) ? 0 : ERASE_CYCLES) => 0;
}
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "roadrunner") => 0;
lfs_unmount(&lfs) => 0;
uint32_t cycle = 0;
while (true) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// chose name, roughly random seed, and random 2^n size
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
assert(res == 1 || res == LFS_ERR_NOSPC);
if (res == LFS_ERR_NOSPC) {
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
lfs_unmount(&lfs) => 0;
goto exhausted;
}
}
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
lfs_unmount(&lfs) => 0;
@@ -223,13 +243,15 @@ code = '''
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
char r;
lfs_file_read(&lfs, &file, &r, 1) => 1;
assert(r == c);
@@ -244,9 +266,11 @@ code = '''
exhausted:
// should still be readable
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
+ struct lfs_info info;
sprintf(path, "roadrunner/test%d", i);
lfs_stat(&lfs, path, &info) => 0;
}
@@ -261,48 +285,52 @@ exhausted:
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
'''
-[[case]] # wear-level test + expanding superblock
-define.LFS_ERASE_CYCLES = 20
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
-define.FILES = 10
+# wear-level test + expanding superblock
+[cases.test_exhaustion_wear_leveling_superblocks]
+defines.ERASE_CYCLES = 20
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
+defines.FILES = 10
code = '''
uint32_t run_cycles[2];
- const uint32_t run_block_count[2] = {LFS_BLOCK_COUNT/2, LFS_BLOCK_COUNT};
+ const uint32_t run_block_count[2] = {BLOCK_COUNT/2, BLOCK_COUNT};
for (int run = 0; run < 2; run++) {
- for (lfs_block_t b = 0; b < LFS_BLOCK_COUNT; b++) {
- lfs_testbd_setwear(&cfg, b,
- (b < run_block_count[run]) ? 0 : LFS_ERASE_CYCLES) => 0;
+ for (lfs_block_t b = 0; b < BLOCK_COUNT; b++) {
+ lfs_emubd_setwear(cfg, b,
+ (b < run_block_count[run]) ? 0 : ERASE_CYCLES) => 0;
}
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
uint32_t cycle = 0;
while (true) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// chose name, roughly random seed, and random 2^n size
+ char path[1024];
sprintf(path, "test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
assert(res == 1 || res == LFS_ERR_NOSPC);
if (res == LFS_ERR_NOSPC) {
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
lfs_unmount(&lfs) => 0;
goto exhausted;
}
}
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
lfs_unmount(&lfs) => 0;
@@ -312,13 +340,15 @@ code = '''
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
sprintf(path, "test%d", i);
- srand(cycle * i);
- size = 1 << ((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << ((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
char r;
lfs_file_read(&lfs, &file, &r, 1) => 1;
assert(r == c);
@@ -333,9 +363,11 @@ code = '''
exhausted:
// should still be readable
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
+ struct lfs_info info;
sprintf(path, "test%d", i);
lfs_stat(&lfs, path, &info) => 0;
}
@@ -350,44 +382,48 @@ exhausted:
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
'''
-[[case]] # test that we wear blocks roughly evenly
-define.LFS_ERASE_CYCLES = 0xffffffff
-define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
-define.LFS_BLOCK_CYCLES = [5, 4, 3, 2, 1]
-define.CYCLES = 100
-define.FILES = 10
-if = 'LFS_BLOCK_CYCLES < CYCLES/10'
+# test that we wear blocks roughly evenly
+[cases.test_exhaustion_wear_distribution]
+defines.ERASE_CYCLES = 0xffffffff
+defines.BLOCK_COUNT = 256 # small bd so test runs faster
+defines.BLOCK_CYCLES = [5, 4, 3, 2, 1]
+defines.CYCLES = 100
+defines.FILES = 10
+if = 'BLOCK_CYCLES < CYCLES/10'
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "roadrunner") => 0;
lfs_unmount(&lfs) => 0;
uint32_t cycle = 0;
while (cycle < CYCLES) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// chose name, roughly random seed, and random 2^n size
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
- srand(cycle * i);
- size = 1 << 4; //((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << 4; //((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
assert(res == 1 || res == LFS_ERR_NOSPC);
if (res == LFS_ERR_NOSPC) {
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
lfs_unmount(&lfs) => 0;
goto exhausted;
}
}
- err = lfs_file_close(&lfs, &file);
+ int err = lfs_file_close(&lfs, &file);
assert(err == 0 || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
lfs_unmount(&lfs) => 0;
@@ -397,13 +433,15 @@ code = '''
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
sprintf(path, "roadrunner/test%d", i);
- srand(cycle * i);
- size = 1 << 4; //((rand() % 10)+2);
+ uint32_t prng = cycle * i;
+ lfs_size_t size = 1 << 4; //((TEST_PRNG(&prng) % 10)+2);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
for (lfs_size_t j = 0; j < size; j++) {
- char c = 'a' + (rand() % 26);
+ char c = 'a' + (TEST_PRNG(&prng) % 26);
char r;
lfs_file_read(&lfs, &file, &r, 1) => 1;
assert(r == c);
@@ -418,9 +456,11 @@ code = '''
exhausted:
// should still be readable
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (uint32_t i = 0; i < FILES; i++) {
// check for errors
+ char path[1024];
+ struct lfs_info info;
sprintf(path, "roadrunner/test%d", i);
lfs_stat(&lfs, path, &info) => 0;
}
@@ -429,12 +469,12 @@ exhausted:
LFS_WARN("completed %d cycles", cycle);
// check the wear on our block device
- lfs_testbd_wear_t minwear = -1;
- lfs_testbd_wear_t totalwear = 0;
- lfs_testbd_wear_t maxwear = 0;
+ lfs_emubd_wear_t minwear = -1;
+ lfs_emubd_wear_t totalwear = 0;
+ lfs_emubd_wear_t maxwear = 0;
// skip 0 and 1 as superblock movement is intentionally avoided
- for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
- lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
+ for (lfs_block_t b = 2; b < BLOCK_COUNT; b++) {
+ lfs_emubd_wear_t wear = lfs_emubd_wear(cfg, b);
printf("%08x: wear %d\n", b, wear);
assert(wear >= 0);
if (wear < minwear) {
@@ -445,17 +485,17 @@ exhausted:
}
totalwear += wear;
}
- lfs_testbd_wear_t avgwear = totalwear / LFS_BLOCK_COUNT;
+ lfs_emubd_wear_t avgwear = totalwear / BLOCK_COUNT;
LFS_WARN("max wear: %d cycles", maxwear);
- LFS_WARN("avg wear: %d cycles", totalwear / LFS_BLOCK_COUNT);
+ LFS_WARN("avg wear: %d cycles", totalwear / (int)BLOCK_COUNT);
LFS_WARN("min wear: %d cycles", minwear);
// find standard deviation^2
- lfs_testbd_wear_t dev2 = 0;
- for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
- lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
+ lfs_emubd_wear_t dev2 = 0;
+ for (lfs_block_t b = 2; b < BLOCK_COUNT; b++) {
+ lfs_emubd_wear_t wear = lfs_emubd_wear(cfg, b);
assert(wear >= 0);
- lfs_testbd_swear_t diff = wear - avgwear;
+ lfs_emubd_swear_t diff = wear - avgwear;
dev2 += diff*diff;
}
dev2 /= totalwear;
diff --git a/tests/test_files.toml b/tests/test_files.toml
index 565e665..afb0811 100644
--- a/tests/test_files.toml
+++ b/tests/test_files.toml
@@ -1,17 +1,20 @@
-[[case]] # simple file test
+[cases.test_files_simple]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "hello",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
- size = strlen("Hello World!")+1;
+ lfs_size_t size = strlen("Hello World!")+1;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "Hello World!");
lfs_file_write(&lfs, &file, buffer, size) => size;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0;
lfs_file_read(&lfs, &file, buffer, size) => size;
assert(strcmp((char*)buffer, "Hello World!") == 0);
@@ -19,21 +22,24 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # larger files
-define.SIZE = [32, 8192, 262144, 0, 7, 8193]
-define.CHUNKSIZE = [31, 16, 33, 1, 1023]
+[cases.test_files_large]
+defines.SIZE = [32, 8192, 262144, 0, 7, 8193]
+defines.CHUNKSIZE = [31, 16, 33, 1, 1023]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// write
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "avacado",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
- srand(1);
+ uint32_t prng = 1;
+ uint8_t buffer[1024];
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -41,15 +47,15 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -57,22 +63,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # rewriting files
-define.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
-define.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
-define.CHUNKSIZE = [31, 16, 1]
+[cases.test_files_rewrite]
+defines.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
+defines.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
+defines.CHUNKSIZE = [31, 16, 1]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// write
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
+ uint8_t buffer[1024];
lfs_file_open(&lfs, &file, "avacado",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
- srand(1);
+ uint32_t prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -80,15 +89,15 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE1;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -96,13 +105,13 @@ code = '''
lfs_unmount(&lfs) => 0;
// rewrite
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY) => 0;
- srand(2);
+ prng = 2;
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -110,27 +119,27 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => lfs_max(SIZE1, SIZE2);
- srand(2);
+ prng = 2;
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
if (SIZE1 > SIZE2) {
- srand(1);
+ prng = 1;
for (lfs_size_t b = 0; b < SIZE2; b++) {
- rand();
+ TEST_PRNG(&prng);
}
for (lfs_size_t i = SIZE2; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
}
@@ -139,22 +148,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # appending files
-define.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
-define.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
-define.CHUNKSIZE = [31, 16, 1]
+[cases.test_files_append]
+defines.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
+defines.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
+defines.CHUNKSIZE = [31, 16, 1]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// write
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
+ uint8_t buffer[1024];
lfs_file_open(&lfs, &file, "avacado",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
- srand(1);
+ uint32_t prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -162,15 +174,15 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE1;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -178,13 +190,13 @@ code = '''
lfs_unmount(&lfs) => 0;
// append
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_APPEND) => 0;
- srand(2);
+ prng = 2;
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -192,23 +204,23 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE1 + SIZE2;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
- srand(2);
+ prng = 2;
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -216,22 +228,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # truncating files
-define.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
-define.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
-define.CHUNKSIZE = [31, 16, 1]
+[cases.test_files_truncate]
+defines.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
+defines.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
+defines.CHUNKSIZE = [31, 16, 1]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// write
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
+ uint8_t buffer[1024];
lfs_file_open(&lfs, &file, "avacado",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
- srand(1);
+ uint32_t prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -239,15 +254,15 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE1;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -255,13 +270,13 @@ code = '''
lfs_unmount(&lfs) => 0;
// truncate
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
- srand(2);
+ prng = 2;
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -269,15 +284,15 @@ code = '''
lfs_unmount(&lfs) => 0;
// read
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE2;
- srand(2);
+ prng = 2;
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -285,33 +300,36 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant file writing
-define.SIZE = [32, 0, 7, 2049]
-define.CHUNKSIZE = [31, 16, 65]
+[cases.test_files_reentrant_write]
+defines.SIZE = [32, 0, 7, 2049]
+defines.CHUNKSIZE = [31, 16, 65]
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
+ lfs_file_t file;
+ uint8_t buffer[1024];
err = lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY);
assert(err == LFS_ERR_NOENT || err == 0);
if (err == 0) {
// can only be 0 (new file) or full size
- size = lfs_file_size(&lfs, &file);
+ lfs_size_t size = lfs_file_size(&lfs, &file);
assert(size == 0 || size == SIZE);
lfs_file_close(&lfs, &file) => 0;
}
// write
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_CREAT) => 0;
- srand(1);
+ uint32_t prng = 1;
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
}
@@ -320,12 +338,12 @@ code = '''
// read
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -333,8 +351,8 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant file writing with syncs
-define = [
+[cases.test_files_reentrant_write_sync]
+defines = [
# append (O(n))
{MODE='LFS_O_APPEND', SIZE=[32, 0, 7, 2049], CHUNKSIZE=[31, 16, 65]},
# truncate (O(n^2))
@@ -344,24 +362,27 @@ define = [
]
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
+ lfs_file_t file;
+ uint8_t buffer[1024];
err = lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY);
assert(err == LFS_ERR_NOENT || err == 0);
if (err == 0) {
// with syncs we could be any size, but it at least must be valid data
- size = lfs_file_size(&lfs, &file);
+ lfs_size_t size = lfs_file_size(&lfs, &file);
assert(size <= SIZE);
- srand(1);
+ uint32_t prng = 1;
for (lfs_size_t i = 0; i < size; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, size-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_close(&lfs, &file) => 0;
@@ -370,17 +391,17 @@ code = '''
// write
lfs_file_open(&lfs, &file, "avacado",
LFS_O_WRONLY | LFS_O_CREAT | MODE) => 0;
- size = lfs_file_size(&lfs, &file);
+ lfs_size_t size = lfs_file_size(&lfs, &file);
assert(size <= SIZE);
- srand(1);
+ uint32_t prng = 1;
lfs_size_t skip = (MODE == LFS_O_APPEND) ? size : 0;
for (lfs_size_t b = 0; b < skip; b++) {
- rand();
+ TEST_PRNG(&prng);
}
for (lfs_size_t i = skip; i < SIZE; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
for (lfs_size_t b = 0; b < chunk; b++) {
- buffer[b] = rand() & 0xff;
+ buffer[b] = TEST_PRNG(&prng) & 0xff;
}
lfs_file_write(&lfs, &file, buffer, chunk) => chunk;
lfs_file_sync(&lfs, &file) => 0;
@@ -390,12 +411,12 @@ code = '''
// read
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => SIZE;
- srand(1);
+ prng = 1;
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
lfs_file_read(&lfs, &file, buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk; b++) {
- assert(buffer[b] == (rand() & 0xff));
+ assert(buffer[b] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0;
@@ -403,19 +424,22 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # many files
-define.N = 300
+[cases.test_files_many]
+defines.N = 300
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// create N files of 7 bytes
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 0; i < N; i++) {
+ lfs_file_t file;
+ char path[1024];
sprintf(path, "file_%03d", i);
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
char wbuffer[1024];
- size = 7;
- snprintf(wbuffer, size, "Hi %03d", i);
+ lfs_size_t size = 7;
+ sprintf(wbuffer, "Hi %03d", i);
lfs_file_write(&lfs, &file, wbuffer, size) => size;
lfs_file_close(&lfs, &file) => 0;
@@ -428,25 +452,28 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # many files with power cycle
-define.N = 300
+[cases.test_files_many_power_cycle]
+defines.N = 300
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// create N files of 7 bytes
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 0; i < N; i++) {
+ lfs_file_t file;
+ char path[1024];
sprintf(path, "file_%03d", i);
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
char wbuffer[1024];
- size = 7;
- snprintf(wbuffer, size, "Hi %03d", i);
+ lfs_size_t size = 7;
+ sprintf(wbuffer, "Hi %03d", i);
lfs_file_write(&lfs, &file, wbuffer, size) => size;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
char rbuffer[1024];
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
lfs_file_read(&lfs, &file, rbuffer, size) => size;
assert(strcmp(rbuffer, wbuffer) == 0);
@@ -455,22 +482,25 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # many files with power loss
-define.N = 300
+[cases.test_files_many_power_loss]
+defines.N = 300
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
// create N files of 7 bytes
for (int i = 0; i < N; i++) {
+ lfs_file_t file;
+ char path[1024];
sprintf(path, "file_%03d", i);
err = lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT);
char wbuffer[1024];
- size = 7;
- snprintf(wbuffer, size, "Hi %03d", i);
+ lfs_size_t size = 7;
+ sprintf(wbuffer, "Hi %03d", i);
if ((lfs_size_t)lfs_file_size(&lfs, &file) != size) {
lfs_file_write(&lfs, &file, wbuffer, size) => size;
}
diff --git a/tests/test_interspersed.toml b/tests/test_interspersed.toml
index 87a0578..d7143f6 100644
--- a/tests/test_interspersed.toml
+++ b/tests/test_interspersed.toml
@@ -1,13 +1,15 @@
-[[case]] # interspersed file test
-define.SIZE = [10, 100]
-define.FILES = [4, 10, 26]
+[cases.test_interspersed_files]
+defines.SIZE = [10, 100]
+defines.FILES = [4, 10, 26]
code = '''
+ lfs_t lfs;
lfs_file_t files[FILES];
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_file_open(&lfs, &files[j], path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
@@ -23,7 +25,9 @@ code = '''
lfs_file_close(&lfs, &files[j]);
}
+ 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);
@@ -31,6 +35,7 @@ code = '''
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR);
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, path) == 0);
@@ -41,12 +46,14 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_file_open(&lfs, &files[j], path, LFS_O_RDONLY) => 0;
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < FILES; j++) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &files[j], buffer, 1) => 1;
assert(buffer[0] == alphas[j]);
}
@@ -59,15 +66,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # interspersed remove file test
-define.SIZE = [10, 100]
-define.FILES = [4, 10, 26]
+[cases.test_interspersed_remove_files]
+defines.SIZE = [10, 100]
+defines.FILES = [4, 10, 26]
code = '''
+ lfs_t lfs;
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
for (int i = 0; i < SIZE; i++) {
@@ -77,18 +87,22 @@ code = '''
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "zzz", LFS_O_WRONLY | LFS_O_CREAT) => 0;
for (int j = 0; j < FILES; j++) {
lfs_file_write(&lfs, &file, (const void*)"~", 1) => 1;
lfs_file_sync(&lfs, &file) => 0;
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_remove(&lfs, path) => 0;
}
lfs_file_close(&lfs, &file);
+ 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);
@@ -104,6 +118,7 @@ code = '''
lfs_file_open(&lfs, &file, "zzz", LFS_O_RDONLY) => 0;
for (int i = 0; i < FILES; i++) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 1) => 1;
assert(buffer[0] == '~');
}
@@ -112,11 +127,12 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # remove inconveniently test
-define.SIZE = [10, 100]
+[cases.test_interspersed_remove_inconveniently]
+defines.SIZE = [10, 100]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_t files[3];
lfs_file_open(&lfs, &files[0], "e", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_open(&lfs, &files[1], "f", LFS_O_WRONLY | LFS_O_CREAT) => 0;
@@ -140,7 +156,9 @@ code = '''
lfs_file_close(&lfs, &files[1]);
lfs_file_close(&lfs, &files[2]);
+ 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);
@@ -161,6 +179,7 @@ code = '''
lfs_file_open(&lfs, &files[0], "e", LFS_O_RDONLY) => 0;
lfs_file_open(&lfs, &files[1], "g", LFS_O_RDONLY) => 0;
for (int i = 0; i < SIZE; i++) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &files[0], buffer, 1) => 1;
assert(buffer[0] == 'e');
lfs_file_read(&lfs, &files[1], buffer, 1) => 1;
@@ -172,21 +191,23 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant interspersed file test
-define.SIZE = [10, 100]
-define.FILES = [4, 10, 26]
+[cases.test_interspersed_reentrant_files]
+defines.SIZE = [10, 100]
+defines.FILES = [4, 10, 26]
reentrant = true
code = '''
+ lfs_t lfs;
lfs_file_t files[FILES];
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
- err = lfs_mount(&lfs, &cfg);
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_file_open(&lfs, &files[j], path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
@@ -194,8 +215,8 @@ code = '''
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < FILES; j++) {
- size = lfs_file_size(&lfs, &files[j]);
- assert((int)size >= 0);
+ lfs_ssize_t size = lfs_file_size(&lfs, &files[j]);
+ assert(size >= 0);
if ((int)size <= i) {
lfs_file_write(&lfs, &files[j], &alphas[j], 1) => 1;
lfs_file_sync(&lfs, &files[j]) => 0;
@@ -207,7 +228,9 @@ code = '''
lfs_file_close(&lfs, &files[j]);
}
+ 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);
@@ -215,6 +238,7 @@ code = '''
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR);
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, path) == 0);
@@ -225,12 +249,14 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
for (int j = 0; j < FILES; j++) {
+ char path[1024];
sprintf(path, "%c", alphas[j]);
lfs_file_open(&lfs, &files[j], path, LFS_O_RDONLY) => 0;
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < FILES; j++) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &files[j], buffer, 1) => 1;
assert(buffer[0] == alphas[j]);
}
diff --git a/tests/test_move.toml b/tests/test_move.toml
index bb3b713..0537f48 100644
--- a/tests/test_move.toml
+++ b/tests/test_move.toml
@@ -1,11 +1,13 @@
-[[case]] # move file
+[cases.test_move_file]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
lfs_mkdir(&lfs, "d") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
@@ -13,11 +15,13 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -44,6 +48,7 @@ code = '''
lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 5) => 5;
memcmp(buffer, "hola\n", 5) => 0;
lfs_file_read(&lfs, &file, buffer, 8) => 8;
@@ -55,31 +60,35 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # noop move, yes this is legal
+[cases.test_move_nop] # yes this is legal
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "hi") => 0;
lfs_rename(&lfs, "hi", "hi") => 0;
lfs_mkdir(&lfs, "hi/hi") => 0;
lfs_rename(&lfs, "hi/hi", "hi/hi") => 0;
lfs_mkdir(&lfs, "hi/hi/hi") => 0;
lfs_rename(&lfs, "hi/hi/hi", "hi/hi/hi") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "hi/hi/hi", &info) => 0;
assert(strcmp(info.name, "hi") == 0);
assert(info.type == LFS_TYPE_DIR);
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move file corrupt source
+[cases.test_move_file_corrupt_source]
in = "lfs.c"
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
lfs_mkdir(&lfs, "d") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
@@ -87,28 +96,30 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
// corrupt the source
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -146,16 +157,19 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move file corrupt source and dest
+# move file corrupt source and dest
+[cases.test_move_file_corrupt_source_dest]
in = "lfs.c"
-if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit
+if = 'PROG_SIZE <= 0x3fe' # only works with one crc per commit
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
lfs_mkdir(&lfs, "d") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
@@ -163,44 +177,46 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
// corrupt the source
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
// corrupt the destination
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "c") => 0;
block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -238,16 +254,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move file after corrupt
+[cases.test_move_file_after_corrupt]
in = "lfs.c"
-if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit
+if = 'PROG_SIZE <= 0x3fe' # only works with one crc per commit
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
lfs_mkdir(&lfs, "d") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
@@ -255,49 +273,51 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
// corrupt the source
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
// corrupt the destination
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "c") => 0;
block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
// continue move
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -335,13 +355,14 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # simple reentrant move file
+[cases.test_move_reentrant_file]
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
err = lfs_mkdir(&lfs, "a");
assert(!err || err == LFS_ERR_EXIST);
@@ -354,9 +375,10 @@ code = '''
lfs_unmount(&lfs) => 0;
while (true) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// there should never exist _2_ hello files
int count = 0;
+ struct lfs_info info;
if (lfs_stat(&lfs, "a/hello", &info) == 0) {
assert(strcmp(info.name, "hello") == 0);
assert(info.type == LFS_TYPE_REG);
@@ -384,7 +406,7 @@ code = '''
assert(count <= 1);
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
if (lfs_stat(&lfs, "a/hello", &info) == 0 && info.size > 0) {
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
} else if (lfs_stat(&lfs, "b/hello", &info) == 0) {
@@ -397,6 +419,7 @@ code = '''
break;
} else {
// create file
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
@@ -407,7 +430,9 @@ code = '''
lfs_unmount(&lfs) => 0;
}
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -431,10 +456,12 @@ code = '''
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 5) => 5;
memcmp(buffer, "hola\n", 5) => 0;
lfs_file_read(&lfs, &file, buffer, 8) => 8;
@@ -445,10 +472,11 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move dir
+[cases.test_move_dir]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
@@ -459,11 +487,13 @@ code = '''
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -510,11 +540,12 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move dir corrupt source
+[cases.test_move_dir_corrupt_source]
in = "lfs.c"
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
@@ -525,28 +556,30 @@ code = '''
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
lfs_unmount(&lfs) => 0;
// corrupt the source
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -593,12 +626,13 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move dir corrupt source and dest
+[cases.test_move_dir_corrupt_source_dest]
in = "lfs.c"
-if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit
+if = 'PROG_SIZE <= 0x3fe' # only works with one crc per commit
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
@@ -609,44 +643,46 @@ code = '''
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
lfs_unmount(&lfs) => 0;
// corrupt the source
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
// corrupt the destination
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "c") => 0;
block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -693,12 +729,13 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move dir after corrupt
+[cases.test_move_dir_after_corrupt]
in = "lfs.c"
-if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit
+if = 'PROG_SIZE <= 0x3fe' # only works with one crc per commit
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
@@ -709,49 +746,51 @@ code = '''
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
lfs_unmount(&lfs) => 0;
// corrupt the source
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
// corrupt the destination
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "c") => 0;
block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
// continue move
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -798,13 +837,14 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # simple reentrant move dir
+[cases.test_reentrant_dir]
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
err = lfs_mkdir(&lfs, "a");
assert(!err || err == LFS_ERR_EXIST);
@@ -817,9 +857,10 @@ code = '''
lfs_unmount(&lfs) => 0;
while (true) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// there should never exist _2_ hi directories
int count = 0;
+ struct lfs_info info;
if (lfs_stat(&lfs, "a/hi", &info) == 0) {
assert(strcmp(info.name, "hi") == 0);
assert(info.type == LFS_TYPE_DIR);
@@ -843,7 +884,7 @@ code = '''
assert(count <= 1);
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
if (lfs_stat(&lfs, "a/hi", &info) == 0) {
lfs_rename(&lfs, "a/hi", "b/hi") => 0;
} else if (lfs_stat(&lfs, "b/hi", &info) == 0) {
@@ -868,7 +909,9 @@ code = '''
lfs_unmount(&lfs) => 0;
}
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "a") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -915,14 +958,16 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move state stealing
+[cases.test_move_state_stealing]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
lfs_mkdir(&lfs, "d") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
@@ -930,21 +975,22 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "b/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_rename(&lfs, "c/hello", "d/hello") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 5) => 5;
memcmp(buffer, "hola\n", 5) => 0;
lfs_file_read(&lfs, &file, buffer, 8) => 8;
@@ -954,12 +1000,13 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_remove(&lfs, "b") => 0;
lfs_remove(&lfs, "c") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "a", &info) => 0;
lfs_stat(&lfs, "b", &info) => LFS_ERR_NOENT;
lfs_stat(&lfs, "c", &info) => LFS_ERR_NOENT;
@@ -979,12 +1026,16 @@ code = '''
'''
# Other specific corner cases
-[[case]] # create + delete in same commit with neighbors
+
+# create + delete in same commit with neighbors
+[cases.test_move_create_delete_same]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// littlefs keeps files sorted, so we know the order these will be in
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "/1.move_me",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_close(&lfs, &file) => 0;
@@ -1024,6 +1075,8 @@ code = '''
lfs_file_close(&lfs, &files[2]) => 0;
// check that nothing was corrupted
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -1051,6 +1104,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 7) => 7;
assert(strcmp((char*)buffer, "test.4") == 0);
lfs_file_close(&lfs, &file) => 0;
@@ -1124,13 +1178,15 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-# Other specific corner cases
-[[case]] # create + delete + delete in same commit with neighbors
+# create + delete + delete in same commit with neighbors
+[cases.test_move_create_delete_delete_same]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// littlefs keeps files sorted, so we know the order these will be in
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "/1.move_me",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_close(&lfs, &file) => 0;
@@ -1175,6 +1231,8 @@ code = '''
lfs_file_close(&lfs, &files[2]) => 0;
// check that nothing was corrupted
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -1202,6 +1260,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 7) => 7;
assert(strcmp((char*)buffer, "test.4") == 0);
lfs_file_close(&lfs, &file) => 0;
@@ -1281,14 +1340,17 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # create + delete in different dirs with neighbors
+# create + delete in different dirs with neighbors
+[cases.test_move_create_delete_different]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// littlefs keeps files sorted, so we know the order these will be in
lfs_mkdir(&lfs, "/dir.1") => 0;
lfs_mkdir(&lfs, "/dir.2") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "/dir.1/1.move_me",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_close(&lfs, &file) => 0;
@@ -1340,6 +1402,8 @@ code = '''
lfs_file_close(&lfs, &files[3]) => 0;
// check that nothing was corrupted
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -1397,6 +1461,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_file_open(&lfs, &file, "/dir.1/0.before", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 7) => 7;
assert(strcmp((char*)buffer, "test.5") == 0);
lfs_file_close(&lfs, &file) => 0;
@@ -1518,17 +1583,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move fix in relocation
+# move fix in relocation
+[cases.test_move_fix_relocation]
in = "lfs.c"
-define.RELOCATIONS = 'range(0x3+1)'
-define.LFS_ERASE_CYCLES = 0xffffffff
+defines.RELOCATIONS = 'range(4)'
+defines.ERASE_CYCLES = 0xffffffff
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "/parent") => 0;
lfs_mkdir(&lfs, "/parent/child") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "/parent/1.move_me",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "move me",
@@ -1568,15 +1636,17 @@ code = '''
// force specific directories to relocate
if (RELOCATIONS & 0x1) {
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "/parent");
- lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
- lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
lfs_dir_close(&lfs, &dir) => 0;
}
if (RELOCATIONS & 0x2) {
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "/parent/child");
- lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
- lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
lfs_dir_close(&lfs, &dir) => 0;
}
@@ -1593,6 +1663,8 @@ code = '''
lfs_file_close(&lfs, &files[3]) => 0;
// check that nothing was corrupted
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "/parent") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -1637,6 +1709,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_file_open(&lfs, &file, "/parent/0.before", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 7) => 7;
assert(strcmp((char*)buffer, "test.5") == 0);
lfs_file_close(&lfs, &file) => 0;
@@ -1655,18 +1728,21 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # move fix in relocation with predecessor
+# move fix in relocation with predecessor
+[cases.test_move_fix_relocation_predecessor]
in = "lfs.c"
-define.RELOCATIONS = 'range(0x7+1)'
-define.LFS_ERASE_CYCLES = 0xffffffff
+defines.RELOCATIONS = 'range(8)'
+defines.ERASE_CYCLES = 0xffffffff
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "/parent") => 0;
lfs_mkdir(&lfs, "/parent/child") => 0;
lfs_mkdir(&lfs, "/parent/sibling") => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "/parent/sibling/1.move_me",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "move me",
@@ -1706,21 +1782,24 @@ code = '''
// force specific directories to relocate
if (RELOCATIONS & 0x1) {
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "/parent");
- lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
- lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
lfs_dir_close(&lfs, &dir) => 0;
}
if (RELOCATIONS & 0x2) {
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "/parent/sibling");
- lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
- lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
lfs_dir_close(&lfs, &dir) => 0;
}
if (RELOCATIONS & 0x4) {
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "/parent/child");
- lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
- lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
+ lfs_emubd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
lfs_dir_close(&lfs, &dir) => 0;
}
@@ -1739,6 +1818,8 @@ code = '''
lfs_file_close(&lfs, &files[3]) => 0;
// check that nothing was corrupted
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "/parent") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
assert(strcmp(info.name, ".") == 0);
@@ -1796,6 +1877,7 @@ code = '''
lfs_dir_close(&lfs, &dir) => 0;
lfs_file_open(&lfs, &file, "/parent/sibling/0.before", LFS_O_RDONLY) => 0;
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 7) => 7;
assert(strcmp((char*)buffer, "test.5") == 0);
lfs_file_close(&lfs, &file) => 0;
diff --git a/tests/test_orphans.toml b/tests/test_orphans.toml
index 241e273..b6b182e 100644
--- a/tests/test_orphans.toml
+++ b/tests/test_orphans.toml
@@ -1,9 +1,10 @@
-[[case]] # orphan test
+[cases.test_orphans_normal]
in = "lfs.c"
-if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit
+if = 'PROG_SIZE <= 0x3fe' # only works with one crc per commit
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "parent") => 0;
lfs_mkdir(&lfs, "parent/orphan") => 0;
lfs_mkdir(&lfs, "parent/child") => 0;
@@ -13,29 +14,31 @@ code = '''
// corrupt the child's most recent commit, this should be the update
// to the linked-list entry, which should orphan the orphan. Note this
// makes a lot of assumptions about the remove operation.
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
lfs_dir_open(&lfs, &dir, "parent/child") => 0;
lfs_block_t block = dir.m.pair[0];
lfs_dir_close(&lfs, &dir) => 0;
lfs_unmount(&lfs) => 0;
- uint8_t bbuffer[LFS_BLOCK_SIZE];
- cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- int off = LFS_BLOCK_SIZE-1;
- while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
+ uint8_t buffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ int off = BLOCK_SIZE-1;
+ while (off >= 0 && buffer[off] == ERASE_VALUE) {
off -= 1;
}
- memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
- cfg.erase(&cfg, block) => 0;
- cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
- cfg.sync(&cfg) => 0;
+ memset(&buffer[off-3], BLOCK_SIZE, 3);
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
+ cfg->sync(cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "parent/orphan", &info) => LFS_ERR_NOENT;
lfs_stat(&lfs, "parent/child", &info) => 0;
lfs_fs_size(&lfs) => 8;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_stat(&lfs, "parent/orphan", &info) => LFS_ERR_NOENT;
lfs_stat(&lfs, "parent/child", &info) => 0;
lfs_fs_size(&lfs) => 8;
@@ -48,7 +51,7 @@ code = '''
lfs_fs_size(&lfs) => 8;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_stat(&lfs, "parent/orphan", &info) => LFS_ERR_NOENT;
lfs_stat(&lfs, "parent/child", &info) => 0;
lfs_stat(&lfs, "parent/otherchild", &info) => 0;
@@ -56,43 +59,48 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant testing for orphans, basically just spam mkdir/remove
+# reentrant testing for orphans, basically just spam mkdir/remove
+[cases.test_orphans_reentrant]
reentrant = true
# TODO fix this case, caused by non-DAG trees
-if = '!(DEPTH == 3 && LFS_CACHE_SIZE != 64)'
-define = [
+if = '!(DEPTH == 3 && CACHE_SIZE != 64)'
+defines = [
{FILES=6, DEPTH=1, CYCLES=20},
{FILES=26, DEPTH=1, CYCLES=20},
{FILES=3, DEPTH=3, CYCLES=20},
]
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
- srand(1);
+ uint32_t prng = 1;
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
- for (int i = 0; i < CYCLES; i++) {
+ for (unsigned i = 0; i < CYCLES; i++) {
// create random path
char full_path[256];
- for (int d = 0; d < DEPTH; d++) {
- sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
+ for (unsigned d = 0; d < DEPTH; d++) {
+ sprintf(&full_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
}
// if it does not exist, we create it, else we destroy
+ struct lfs_info info;
int res = lfs_stat(&lfs, full_path, &info);
if (res == LFS_ERR_NOENT) {
// create each directory in turn, ignore if dir already exists
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
err = lfs_mkdir(&lfs, path);
assert(!err || err == LFS_ERR_EXIST);
}
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
lfs_stat(&lfs, path, &info) => 0;
@@ -106,6 +114,7 @@ code = '''
// try to delete path in reverse order, ignore if dir is not empty
for (int d = DEPTH-1; d >= 0; d--) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
err = lfs_remove(&lfs, path);
diff --git a/tests/test_paths.toml b/tests/test_paths.toml
index a7474c0..97a519e 100644
--- a/tests/test_paths.toml
+++ b/tests/test_paths.toml
@@ -1,13 +1,16 @@
-[[case]] # simple path test
+# simple path test
+[cases.test_paths_normal]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
lfs_mkdir(&lfs, "tea/coldtea") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "tea/hottea", &info) => 0;
assert(strcmp(info.name, "hottea") == 0);
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
@@ -21,15 +24,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # redundant slashes
+# redundant slashes
+[cases.test_paths_redundant_slashes]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
lfs_mkdir(&lfs, "tea/coldtea") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
assert(strcmp(info.name, "hottea") == 0);
lfs_stat(&lfs, "//tea//hottea", &info) => 0;
@@ -45,15 +51,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # dot path test
+# dot path test
+[cases.test_paths_dot]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
lfs_mkdir(&lfs, "tea/coldtea") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "./tea/hottea", &info) => 0;
assert(strcmp(info.name, "hottea") == 0);
lfs_stat(&lfs, "/./tea/hottea", &info) => 0;
@@ -71,10 +80,12 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # dot dot path test
+# dot dot path test
+[cases.test_paths_dot_dot]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
@@ -84,6 +95,7 @@ code = '''
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "coffee/../tea/hottea", &info) => 0;
assert(strcmp(info.name, "hottea") == 0);
lfs_stat(&lfs, "tea/coldtea/../hottea", &info) => 0;
@@ -101,15 +113,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # trailing dot path test
+# trailing dot path test
+[cases.test_paths_trailing_dot]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
lfs_mkdir(&lfs, "tea/coldtea") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "tea/hottea/", &info) => 0;
assert(strcmp(info.name, "hottea") == 0);
lfs_stat(&lfs, "tea/hottea/.", &info) => 0;
@@ -123,11 +138,14 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # leading dot path test
+# leading dot path test
+[cases.test_paths_leading_dot]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, ".milk") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, ".milk", &info) => 0;
strcmp(info.name, ".milk") => 0;
lfs_stat(&lfs, "tea/.././.milk", &info) => 0;
@@ -135,10 +153,12 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # root dot dot path test
+# root dot dot path test
+[cases.test_paths_root_dot_dot]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
@@ -148,6 +168,7 @@ code = '''
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
@@ -159,10 +180,13 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # invalid path tests
+# invalid path tests
+[cases.test_paths_invalid]
code = '''
- lfs_format(&lfs, &cfg);
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg);
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "dirt", &info) => LFS_ERR_NOENT;
lfs_stat(&lfs, "dirt/ground", &info) => LFS_ERR_NOENT;
lfs_stat(&lfs, "dirt/ground/earth", &info) => LFS_ERR_NOENT;
@@ -172,6 +196,7 @@ code = '''
lfs_remove(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
lfs_mkdir(&lfs, "dirt/ground") => LFS_ERR_NOENT;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "dirt/ground", LFS_O_WRONLY | LFS_O_CREAT)
=> LFS_ERR_NOENT;
lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
@@ -180,15 +205,19 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # root operations
+# root operations
+[cases.test_paths_root]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "/", &info) => 0;
assert(strcmp(info.name, "/") == 0);
assert(info.type == LFS_TYPE_DIR);
lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY | LFS_O_CREAT)
=> LFS_ERR_ISDIR;
@@ -196,10 +225,13 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # root representations
+# root representations
+[cases.test_paths_root_reprs]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "/", &info) => 0;
assert(strcmp(info.name, "/") == 0);
assert(info.type == LFS_TYPE_DIR);
@@ -221,10 +253,13 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # superblock conflict test
+# superblock conflict test
+[cases.test_paths_superblock_conflict]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT;
lfs_remove(&lfs, "littlefs") => LFS_ERR_NOENT;
@@ -237,18 +272,22 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # max path test
+# max path test
+[cases.test_paths_max]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "coffee") => 0;
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
+ char path[1024];
memset(path, 'w', LFS_NAME_MAX+1);
path[LFS_NAME_MAX+1] = '\0';
lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT)
=> LFS_ERR_NAMETOOLONG;
@@ -261,19 +300,23 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # really big path test
+# really big path test
+[cases.test_paths_really_big]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_mkdir(&lfs, "coffee") => 0;
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
+ char path[1024];
memset(path, 'w', LFS_NAME_MAX);
path[LFS_NAME_MAX] = '\0';
lfs_mkdir(&lfs, path) => 0;
lfs_remove(&lfs, path) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_close(&lfs, &file) => 0;
diff --git a/tests/test_powerloss.toml b/tests/test_powerloss.toml
new file mode 100644
index 0000000..06f8661
--- /dev/null
+++ b/tests/test_powerloss.toml
@@ -0,0 +1,182 @@
+# There are already a number of tests that test general operations under
+# power-loss (see the reentrant attribute). These tests are for explicitly
+# testing specific corner cases.
+
+# only a revision count
+[cases.test_powerloss_only_rev]
+code = '''
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_mkdir(&lfs, "notebook") => 0;
+ lfs_file_t file;
+ lfs_file_open(&lfs, &file, "notebook/paper",
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
+ char buffer[256];
+ strcpy(buffer, "hello");
+ lfs_size_t size = strlen("hello");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_write(&lfs, &file, buffer, size) => size;
+ lfs_file_sync(&lfs, &file) => 0;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ char rbuffer[256];
+ lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // get pair/rev count
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ lfs_dir_open(&lfs, &dir, "notebook") => 0;
+ lfs_block_t pair[2] = {dir.m.pair[0], dir.m.pair[1]};
+ uint32_t rev = dir.m.rev;
+ lfs_dir_close(&lfs, &dir) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // write just the revision count
+ uint8_t bbuffer[BLOCK_SIZE];
+ cfg->read(cfg, pair[1], 0, bbuffer, BLOCK_SIZE) => 0;
+
+ memcpy(bbuffer, &(uint32_t){lfs_tole32(rev+1)}, sizeof(uint32_t));
+
+ cfg->erase(cfg, pair[1]) => 0;
+ cfg->prog(cfg, pair[1], 0, bbuffer, BLOCK_SIZE) => 0;
+
+ lfs_mount(&lfs, cfg) => 0;
+
+ // can read?
+ lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ // can write?
+ lfs_file_open(&lfs, &file, "notebook/paper",
+ LFS_O_WRONLY | LFS_O_APPEND) => 0;
+ strcpy(buffer, "goodbye");
+ size = strlen("goodbye");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_write(&lfs, &file, buffer, size) => size;
+ lfs_file_sync(&lfs, &file) => 0;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
+ strcpy(buffer, "hello");
+ size = strlen("hello");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ strcpy(buffer, "goodbye");
+ size = strlen("goodbye");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ lfs_unmount(&lfs) => 0;
+'''
+
+# partial prog, may not be byte in order!
+[cases.test_powerloss_partial_prog]
+if = "PROG_SIZE < BLOCK_SIZE"
+defines.BYTE_OFF = ["0", "PROG_SIZE-1", "PROG_SIZE/2"]
+defines.BYTE_VALUE = [0x33, 0xcc]
+in = "lfs.c"
+code = '''
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_mkdir(&lfs, "notebook") => 0;
+ lfs_file_t file;
+ lfs_file_open(&lfs, &file, "notebook/paper",
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
+ char buffer[256];
+ strcpy(buffer, "hello");
+ lfs_size_t size = strlen("hello");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_write(&lfs, &file, buffer, size) => size;
+ lfs_file_sync(&lfs, &file) => 0;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ char rbuffer[256];
+ lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ lfs_file_close(&lfs, &file) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // imitate a partial prog, value should not matter, if littlefs
+ // doesn't notice the partial prog testbd will assert
+
+ // get offset to next prog
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ lfs_dir_open(&lfs, &dir, "notebook") => 0;
+ lfs_block_t block = dir.m.pair[0];
+ lfs_off_t off = dir.m.off;
+ lfs_dir_close(&lfs, &dir) => 0;
+ lfs_unmount(&lfs) => 0;
+
+ // tweak byte
+ uint8_t bbuffer[BLOCK_SIZE];
+ cfg->read(cfg, block, 0, bbuffer, BLOCK_SIZE) => 0;
+
+ bbuffer[off + BYTE_OFF] = BYTE_VALUE;
+
+ cfg->erase(cfg, block) => 0;
+ cfg->prog(cfg, block, 0, bbuffer, BLOCK_SIZE) => 0;
+
+ lfs_mount(&lfs, cfg) => 0;
+
+ // can read?
+ lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ // can write?
+ lfs_file_open(&lfs, &file, "notebook/paper",
+ LFS_O_WRONLY | LFS_O_APPEND) => 0;
+ strcpy(buffer, "goodbye");
+ size = strlen("goodbye");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_write(&lfs, &file, buffer, size) => size;
+ lfs_file_sync(&lfs, &file) => 0;
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ lfs_file_open(&lfs, &file, "notebook/paper", LFS_O_RDONLY) => 0;
+ strcpy(buffer, "hello");
+ size = strlen("hello");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ strcpy(buffer, "goodbye");
+ size = strlen("goodbye");
+ for (int i = 0; i < 5; i++) {
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
+ assert(memcmp(rbuffer, buffer, size) == 0);
+ }
+ lfs_file_close(&lfs, &file) => 0;
+
+ lfs_unmount(&lfs) => 0;
+'''
diff --git a/tests/test_relocations.toml b/tests/test_relocations.toml
index 71b1047..d20cb8c 100644
--- a/tests/test_relocations.toml
+++ b/tests/test_relocations.toml
@@ -1,15 +1,18 @@
# specific corner cases worth explicitly testing for
-[[case]] # dangling split dir test
-define.ITERATIONS = 20
-define.COUNT = 10
-define.LFS_BLOCK_CYCLES = [8, 1]
+[cases.test_relocations_dangling_split_dir]
+defines.ITERATIONS = 20
+defines.COUNT = 10
+defines.BLOCK_CYCLES = [8, 1]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// fill up filesystem so only ~16 blocks are left
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "padding", LFS_O_CREAT | LFS_O_WRONLY) => 0;
+ uint8_t buffer[512];
memset(buffer, 0, 512);
- while (LFS_BLOCK_COUNT - lfs_fs_size(&lfs) > 16) {
+ while (BLOCK_COUNT - lfs_fs_size(&lfs) > 16) {
lfs_file_write(&lfs, &file, buffer, 512) => 512;
}
lfs_file_close(&lfs, &file) => 0;
@@ -17,18 +20,22 @@ code = '''
lfs_mkdir(&lfs, "child") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
- for (int j = 0; j < ITERATIONS; j++) {
- for (int i = 0; i < COUNT; i++) {
+ lfs_mount(&lfs, cfg) => 0;
+ for (unsigned j = 0; j < ITERATIONS; j++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_close(&lfs, &file) => 0;
}
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "child") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
@@ -36,46 +43,54 @@ code = '''
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
- if (j == ITERATIONS-1) {
+ if (j == (unsigned)ITERATIONS-1) {
break;
}
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_remove(&lfs, path) => 0;
}
}
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "child") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
}
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_remove(&lfs, path) => 0;
}
lfs_unmount(&lfs) => 0;
'''
-[[case]] # outdated head test
-define.ITERATIONS = 20
-define.COUNT = 10
-define.LFS_BLOCK_CYCLES = [8, 1]
+[cases.test_relocations_outdated_head]
+defines.ITERATIONS = 20
+defines.COUNT = 10
+defines.BLOCK_CYCLES = [8, 1]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
// fill up filesystem so only ~16 blocks are left
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "padding", LFS_O_CREAT | LFS_O_WRONLY) => 0;
+ uint8_t buffer[512];
memset(buffer, 0, 512);
- while (LFS_BLOCK_COUNT - lfs_fs_size(&lfs) > 16) {
+ while (BLOCK_COUNT - lfs_fs_size(&lfs) > 16) {
lfs_file_write(&lfs, &file, buffer, 512) => 512;
}
lfs_file_close(&lfs, &file) => 0;
@@ -83,18 +98,22 @@ code = '''
lfs_mkdir(&lfs, "child") => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
- for (int j = 0; j < ITERATIONS; j++) {
- for (int i = 0; i < COUNT; i++) {
+ lfs_mount(&lfs, cfg) => 0;
+ for (unsigned j = 0; j < ITERATIONS; j++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_close(&lfs, &file) => 0;
}
+ lfs_dir_t dir;
+ struct lfs_info info;
lfs_dir_open(&lfs, &dir, "child") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
@@ -110,7 +129,8 @@ code = '''
lfs_dir_rewind(&lfs, &dir) => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
@@ -126,7 +146,8 @@ code = '''
lfs_dir_rewind(&lfs, &dir) => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
@@ -135,7 +156,8 @@ code = '''
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
- for (int i = 0; i < COUNT; i++) {
+ for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_remove(&lfs, path) => 0;
}
@@ -143,45 +165,51 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant testing for relocations, this is the same as the
- # orphan testing, except here we also set block_cycles so that
- # almost every tree operation needs a relocation
+# reentrant testing for relocations, this is the same as the
+# orphan testing, except here we also set block_cycles so that
+# almost every tree operation needs a relocation
+[cases.test_relocations_reentrant]
reentrant = true
# TODO fix this case, caused by non-DAG trees
-if = '!(DEPTH == 3 && LFS_CACHE_SIZE != 64)'
-define = [
- {FILES=6, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
- {FILES=26, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
- {FILES=3, DEPTH=3, CYCLES=20, LFS_BLOCK_CYCLES=1},
+# NOTE the second condition is required
+if = '!(DEPTH == 3 && CACHE_SIZE != 64) && 2*FILES < BLOCK_COUNT'
+defines = [
+ {FILES=6, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
+ {FILES=26, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
+ {FILES=3, DEPTH=3, CYCLES=20, BLOCK_CYCLES=1},
]
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
- srand(1);
+ uint32_t prng = 1;
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
- for (int i = 0; i < CYCLES; i++) {
+ for (unsigned i = 0; i < CYCLES; i++) {
// create random path
char full_path[256];
- for (int d = 0; d < DEPTH; d++) {
- sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
+ for (unsigned d = 0; d < DEPTH; d++) {
+ sprintf(&full_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
}
// if it does not exist, we create it, else we destroy
+ struct lfs_info info;
int res = lfs_stat(&lfs, full_path, &info);
if (res == LFS_ERR_NOENT) {
// create each directory in turn, ignore if dir already exists
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
err = lfs_mkdir(&lfs, path);
assert(!err || err == LFS_ERR_EXIST);
}
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
lfs_stat(&lfs, path, &info) => 0;
@@ -194,7 +222,8 @@ code = '''
assert(info.type == LFS_TYPE_DIR);
// try to delete path in reverse order, ignore if dir is not empty
- for (int d = DEPTH-1; d >= 0; d--) {
+ for (unsigned d = DEPTH-1; d+1 > 0; d--) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
err = lfs_remove(&lfs, path);
@@ -207,44 +236,50 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant testing for relocations, but now with random renames!
+# reentrant testing for relocations, but now with random renames!
+[cases.test_relocations_reentrant_renames]
reentrant = true
# TODO fix this case, caused by non-DAG trees
-if = '!(DEPTH == 3 && LFS_CACHE_SIZE != 64)'
-define = [
- {FILES=6, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
- {FILES=26, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
- {FILES=3, DEPTH=3, CYCLES=20, LFS_BLOCK_CYCLES=1},
+# NOTE the second condition is required
+if = '!(DEPTH == 3 && CACHE_SIZE != 64) && 2*FILES < BLOCK_COUNT'
+defines = [
+ {FILES=6, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
+ {FILES=26, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
+ {FILES=3, DEPTH=3, CYCLES=20, BLOCK_CYCLES=1},
]
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
- srand(1);
+ uint32_t prng = 1;
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
- for (int i = 0; i < CYCLES; i++) {
+ for (unsigned i = 0; i < CYCLES; i++) {
// create random path
char full_path[256];
- for (int d = 0; d < DEPTH; d++) {
- sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
+ for (unsigned d = 0; d < DEPTH; d++) {
+ sprintf(&full_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
}
// if it does not exist, we create it, else we destroy
+ struct lfs_info info;
int res = lfs_stat(&lfs, full_path, &info);
assert(!res || res == LFS_ERR_NOENT);
if (res == LFS_ERR_NOENT) {
// create each directory in turn, ignore if dir already exists
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
err = lfs_mkdir(&lfs, path);
assert(!err || err == LFS_ERR_EXIST);
}
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
lfs_stat(&lfs, path, &info) => 0;
@@ -257,8 +292,8 @@ code = '''
// create new random path
char new_path[256];
- for (int d = 0; d < DEPTH; d++) {
- sprintf(&new_path[2*d], "/%c", alpha[rand() % FILES]);
+ for (unsigned d = 0; d < DEPTH; d++) {
+ sprintf(&new_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
}
// if new path does not exist, rename, otherwise destroy
@@ -266,7 +301,8 @@ code = '''
assert(!res || res == LFS_ERR_NOENT);
if (res == LFS_ERR_NOENT) {
// stop once some dir is renamed
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(&path[2*d], &full_path[2*d]);
path[2*d+2] = '\0';
strcpy(&path[128+2*d], &new_path[2*d]);
@@ -278,7 +314,8 @@ code = '''
}
}
- for (int d = 0; d < DEPTH; d++) {
+ for (unsigned d = 0; d < DEPTH; d++) {
+ char path[1024];
strcpy(path, new_path);
path[2*d+2] = '\0';
lfs_stat(&lfs, path, &info) => 0;
@@ -290,7 +327,8 @@ code = '''
} else {
// try to delete path in reverse order,
// ignore if dir is not empty
- for (int d = DEPTH-1; d >= 0; d--) {
+ for (unsigned d = DEPTH-1; d+1 > 0; d--) {
+ char path[1024];
strcpy(path, full_path);
path[2*d+2] = '\0';
err = lfs_remove(&lfs, path);
diff --git a/tests/test_seek.toml b/tests/test_seek.toml
index 79d7728..b976057 100644
--- a/tests/test_seek.toml
+++ b/tests/test_seek.toml
@@ -1,6 +1,7 @@
-[[case]] # simple file seek
-define = [
+# simple file seek
+[cases.test_seek_read]
+defines = [
{COUNT=132, SKIP=4},
{COUNT=132, SKIP=128},
{COUNT=200, SKIP=10},
@@ -9,11 +10,14 @@ define = [
{COUNT=4, SKIP=2},
]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "kitty",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- size = strlen("kittycatcat");
+ size_t size = strlen("kittycatcat");
+ uint8_t buffer[1024];
memcpy(buffer, "kittycatcat", size);
for (int j = 0; j < COUNT; j++) {
lfs_file_write(&lfs, &file, buffer, size);
@@ -21,7 +25,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY) => 0;
lfs_soff_t pos = -1;
@@ -68,8 +72,9 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # simple file seek and write
-define = [
+# simple file seek and write
+[cases.test_seek_write]
+defines = [
{COUNT=132, SKIP=4},
{COUNT=132, SKIP=128},
{COUNT=200, SKIP=10},
@@ -78,11 +83,14 @@ define = [
{COUNT=4, SKIP=2},
]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "kitty",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- size = strlen("kittycatcat");
+ size_t size = strlen("kittycatcat");
+ uint8_t buffer[1024];
memcpy(buffer, "kittycatcat", size);
for (int j = 0; j < COUNT; j++) {
lfs_file_write(&lfs, &file, buffer, size);
@@ -90,7 +98,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
lfs_soff_t pos = -1;
@@ -129,15 +137,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # boundary seek and writes
-define.COUNT = 132
-define.OFFSETS = '"{512, 1020, 513, 1021, 511, 1019, 1441}"'
+# boundary seek and writes
+[cases.test_seek_boundary_write]
+defines.COUNT = 132
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "kitty",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- size = strlen("kittycatcat");
+ size_t size = strlen("kittycatcat");
+ uint8_t buffer[1024];
memcpy(buffer, "kittycatcat", size);
for (int j = 0; j < COUNT; j++) {
lfs_file_write(&lfs, &file, buffer, size);
@@ -145,11 +156,11 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
size = strlen("hedgehoghog");
- const lfs_soff_t offsets[] = OFFSETS;
+ const lfs_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019, 1441};
for (unsigned i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) {
lfs_soff_t off = offsets[i];
@@ -183,8 +194,9 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # out of bounds seek
-define = [
+# out of bounds seek
+[cases.test_seek_out_of_bounds]
+defines = [
{COUNT=132, SKIP=4},
{COUNT=132, SKIP=128},
{COUNT=200, SKIP=10},
@@ -193,18 +205,21 @@ define = [
{COUNT=4, SKIP=3},
]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "kitty",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
- size = strlen("kittycatcat");
+ size_t size = strlen("kittycatcat");
+ uint8_t buffer[1024];
memcpy(buffer, "kittycatcat", size);
for (int j = 0; j < COUNT; j++) {
lfs_file_write(&lfs, &file, buffer, size);
}
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
size = strlen("kittycatcat");
@@ -238,16 +253,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # inline write and seek
-define.SIZE = [2, 4, 128, 132]
+# inline write and seek
+[cases.test_seek_inline_write]
+defines.SIZE = [2, 4, 128, 132]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "tinykitty",
LFS_O_RDWR | LFS_O_CREAT) => 0;
int j = 0;
int k = 0;
+ uint8_t buffer[1024];
memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26);
for (unsigned i = 0; i < SIZE; i++) {
lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1;
@@ -305,16 +324,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # file seek and write with power-loss
+# file seek and write with power-loss
+[cases.test_seek_reentrant_write]
# must be power-of-2 for quadratic probing to be exhaustive
-define.COUNT = [4, 64, 128]
+defines.COUNT = [4, 64, 128]
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
+ lfs_file_t file;
+ uint8_t buffer[1024];
err = lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY);
assert(!err || err == LFS_ERR_NOENT);
if (!err) {
@@ -334,14 +357,14 @@ code = '''
if (lfs_file_size(&lfs, &file) == 0) {
for (int j = 0; j < COUNT; j++) {
strcpy((char*)buffer, "kittycatcat");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
lfs_file_write(&lfs, &file, buffer, size) => size;
}
}
lfs_file_close(&lfs, &file) => 0;
strcpy((char*)buffer, "doggodogdog");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => COUNT*size;
diff --git a/tests/test_superblocks.toml b/tests/test_superblocks.toml
index 407c845..689bbcd 100644
--- a/tests/test_superblocks.toml
+++ b/tests/test_superblocks.toml
@@ -1,41 +1,53 @@
-[[case]] # simple formatting test
+# simple formatting test
+[cases.test_superblocks_format]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
'''
-[[case]] # mount/unmount
+# mount/unmount
+[cases.test_superblocks_mount]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant format
+# reentrant format
+[cases.test_superblocks_reentrant_format]
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
lfs_unmount(&lfs) => 0;
'''
-[[case]] # invalid mount
+# invalid mount
+[cases.test_superblocks_invalid_mount]
code = '''
- lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
+ lfs_t lfs;
+ lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
'''
-[[case]] # expanding superblock
-define.LFS_BLOCK_CYCLES = [32, 33, 1]
-define.N = [10, 100, 1000]
+# expanding superblock
+[cases.test_superblocks_expand]
+defines.BLOCK_CYCLES = [32, 33, 1]
+defines.N = [10, 100, 1000]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (int i = 0; i < N; i++) {
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "dummy",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
lfs_file_close(&lfs, &file) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "dummy", &info) => 0;
assert(strcmp(info.name, "dummy") == 0);
assert(info.type == LFS_TYPE_REG);
@@ -44,25 +56,30 @@ code = '''
lfs_unmount(&lfs) => 0;
// one last check after power-cycle
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "dummy",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
lfs_file_close(&lfs, &file) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "dummy", &info) => 0;
assert(strcmp(info.name, "dummy") == 0);
assert(info.type == LFS_TYPE_REG);
lfs_unmount(&lfs) => 0;
'''
-[[case]] # expanding superblock with power cycle
-define.LFS_BLOCK_CYCLES = [32, 33, 1]
-define.N = [10, 100, 1000]
+# expanding superblock with power cycle
+[cases.test_superblocks_expand_power_cycle]
+defines.BLOCK_CYCLES = [32, 33, 1]
+defines.N = [10, 100, 1000]
code = '''
- lfs_format(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
for (int i = 0; i < N; i++) {
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
// remove lingering dummy?
- err = lfs_stat(&lfs, "dummy", &info);
+ struct lfs_info info;
+ int err = lfs_stat(&lfs, "dummy", &info);
assert(err == 0 || (err == LFS_ERR_NOENT && i == 0));
if (!err) {
assert(strcmp(info.name, "dummy") == 0);
@@ -70,6 +87,7 @@ code = '''
lfs_remove(&lfs, "dummy") => 0;
}
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "dummy",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
lfs_file_close(&lfs, &file) => 0;
@@ -80,26 +98,30 @@ code = '''
}
// one last check after power-cycle
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "dummy", &info) => 0;
assert(strcmp(info.name, "dummy") == 0);
assert(info.type == LFS_TYPE_REG);
lfs_unmount(&lfs) => 0;
'''
-[[case]] # reentrant expanding superblock
-define.LFS_BLOCK_CYCLES = [2, 1]
-define.N = 24
+# reentrant expanding superblock
+[cases.test_superblocks_reentrant_expand]
+defines.BLOCK_CYCLES = [2, 1]
+defines.N = 24
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
for (int i = 0; i < N; i++) {
// remove lingering dummy?
+ struct lfs_info info;
err = lfs_stat(&lfs, "dummy", &info);
assert(err == 0 || (err == LFS_ERR_NOENT && i == 0));
if (!err) {
@@ -108,6 +130,7 @@ code = '''
lfs_remove(&lfs, "dummy") => 0;
}
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "dummy",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
lfs_file_close(&lfs, &file) => 0;
@@ -119,7 +142,8 @@ code = '''
lfs_unmount(&lfs) => 0;
// one last check after power-cycle
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ struct lfs_info info;
lfs_stat(&lfs, "dummy", &info) => 0;
assert(strcmp(info.name, "dummy") == 0);
assert(info.type == LFS_TYPE_REG);
diff --git a/tests/test_truncate.toml b/tests/test_truncate.toml
index 850d7aa..a0da50e 100644
--- a/tests/test_truncate.toml
+++ b/tests/test_truncate.toml
@@ -1,14 +1,18 @@
-[[case]] # simple truncate
-define.MEDIUMSIZE = [32, 2048]
-define.LARGESIZE = 8192
+# simple truncate
+[cases.test_truncate_simple]
+defines.MEDIUMSIZE = [32, 2048]
+defines.LARGESIZE = 8192
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "baldynoop",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "hair");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -17,7 +21,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldynoop", LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => LARGESIZE;
@@ -27,7 +31,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldynoop", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
@@ -42,17 +46,21 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # truncate and read
-define.MEDIUMSIZE = [32, 2048]
-define.LARGESIZE = 8192
+# truncate and read
+[cases.test_truncate_read]
+defines.MEDIUMSIZE = [32, 2048]
+defines.LARGESIZE = 8192
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "baldyread",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "hair");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -61,7 +69,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldyread", LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => LARGESIZE;
@@ -78,7 +86,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldyread", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
@@ -93,14 +101,18 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # write, truncate, and read
+# write, truncate, and read
+[cases.test_truncate_write_read]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "sequence",
LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0;
- size = lfs_min(lfs.cfg->cache_size, sizeof(buffer)/2);
+ uint8_t buffer[1024];
+ size_t size = lfs_min(lfs.cfg->cache_size, sizeof(buffer)/2);
lfs_size_t qsize = size / 4;
uint8_t *wb = buffer;
uint8_t *rb = buffer + size;
@@ -145,17 +157,21 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # truncate and write
-define.MEDIUMSIZE = [32, 2048]
-define.LARGESIZE = 8192
+# truncate and write
+[cases.test_truncate_write]
+defines.MEDIUMSIZE = [32, 2048]
+defines.LARGESIZE = 8192
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "baldywrite",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "hair");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -164,7 +180,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldywrite", LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => LARGESIZE;
@@ -181,7 +197,7 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldywrite", LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
@@ -196,26 +212,30 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # truncate write under powerloss
-define.SMALLSIZE = [4, 512]
-define.MEDIUMSIZE = [32, 1024]
-define.LARGESIZE = 2048
+# truncate write under powerloss
+[cases.test_truncate_reentrant_write]
+defines.SMALLSIZE = [4, 512]
+defines.MEDIUMSIZE = [32, 1024]
+defines.LARGESIZE = 2048
reentrant = true
code = '''
- err = lfs_mount(&lfs, &cfg);
+ lfs_t lfs;
+ int err = lfs_mount(&lfs, cfg);
if (err) {
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
}
+ lfs_file_t file;
err = lfs_file_open(&lfs, &file, "baldy", LFS_O_RDONLY);
assert(!err || err == LFS_ERR_NOENT);
if (!err) {
- size = lfs_file_size(&lfs, &file);
+ size_t size = lfs_file_size(&lfs, &file);
assert(size == 0 ||
- size == LARGESIZE ||
- size == MEDIUMSIZE ||
- size == SMALLSIZE);
+ size == (size_t)LARGESIZE ||
+ size == (size_t)MEDIUMSIZE ||
+ size == (size_t)SMALLSIZE);
for (lfs_off_t j = 0; j < size; j += 4) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, 4) => 4;
assert(memcmp(buffer, "hair", 4) == 0 ||
memcmp(buffer, "bald", 4) == 0 ||
@@ -227,8 +247,9 @@ code = '''
lfs_file_open(&lfs, &file, "baldy",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
lfs_file_size(&lfs, &file) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "hair");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -262,12 +283,14 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # more aggressive general truncation tests
-define.CONFIG = 'range(6)'
-define.SMALLSIZE = 32
-define.MEDIUMSIZE = 2048
-define.LARGESIZE = 8192
+# more aggressive general truncation tests
+[cases.test_truncate_aggressive]
+defines.CONFIG = 'range(6)'
+defines.SMALLSIZE = 32
+defines.MEDIUMSIZE = 2048
+defines.LARGESIZE = 8192
code = '''
+ lfs_t lfs;
#define COUNT 5
const struct {
lfs_off_t startsizes[COUNT];
@@ -312,16 +335,19 @@ code = '''
const lfs_off_t *hotsizes = configs[CONFIG].hotsizes;
const lfs_off_t *coldsizes = configs[CONFIG].coldsizes;
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "hairyhead%d", i);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "hair");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < startsizes[i]; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
}
@@ -340,21 +366,25 @@ code = '''
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "hairyhead%d", i);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => hotsizes[i];
- size = strlen("hair");
+ size_t size = strlen("hair");
lfs_off_t j = 0;
for (; j < startsizes[i] && j < hotsizes[i]; j += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
memcmp(buffer, "hair", size) => 0;
}
for (; j < hotsizes[i]; j += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
memcmp(buffer, "\0\0\0\0", size) => 0;
}
@@ -367,22 +397,26 @@ code = '''
lfs_unmount(&lfs) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
for (unsigned i = 0; i < COUNT; i++) {
+ char path[1024];
sprintf(path, "hairyhead%d", i);
+ lfs_file_t file;
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file) => coldsizes[i];
- size = strlen("hair");
+ size_t size = strlen("hair");
lfs_off_t j = 0;
for (; j < startsizes[i] && j < hotsizes[i] && j < coldsizes[i];
j += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
memcmp(buffer, "hair", size) => 0;
}
for (; j < coldsizes[i]; j += size) {
+ uint8_t buffer[1024];
lfs_file_read(&lfs, &file, buffer, size) => size;
memcmp(buffer, "\0\0\0\0", size) => 0;
}
@@ -393,16 +427,20 @@ code = '''
lfs_unmount(&lfs) => 0;
'''
-[[case]] # noop truncate
-define.MEDIUMSIZE = [32, 2048]
+# noop truncate
+[cases.test_truncate_nop]
+defines.MEDIUMSIZE = [32, 2048]
code = '''
- lfs_format(&lfs, &cfg) => 0;
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_t lfs;
+ lfs_format(&lfs, cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
+ lfs_file_t file;
lfs_file_open(&lfs, &file, "baldynoop",
LFS_O_RDWR | LFS_O_CREAT) => 0;
+ uint8_t buffer[1024];
strcpy((char*)buffer, "hair");
- size = strlen((char*)buffer);
+ size_t size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
@@ -426,7 +464,7 @@ code = '''
lfs_unmount(&lfs) => 0;
// still there after reboot?
- lfs_mount(&lfs, &cfg) => 0;
+ lfs_mount(&lfs, cfg) => 0;
lfs_file_open(&lfs, &file, "baldynoop", LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {