forked from Imagelibrary/littlefs
Ported tests to new framework
This mostly required names for each test case, declarations of previously-implicit variables since the new test framework is more conservative with what it declares (the small extra effort to add declarations is well worth the simplicity and improved readability), and tweaks to work with not-really-constant defines. Also renamed test_ -> test, replacing the old ./scripts/test.py, unfortunately git seems to have had a hard time with this.
This commit is contained in:
36
Makefile
36
Makefile
@@ -32,7 +32,7 @@ DEP := $(SRC:%.c=$(BUILDDIR)%.d)
|
|||||||
ASM := $(SRC:%.c=$(BUILDDIR)%.s)
|
ASM := $(SRC:%.c=$(BUILDDIR)%.s)
|
||||||
CGI := $(SRC:%.c=$(BUILDDIR)%.ci)
|
CGI := $(SRC:%.c=$(BUILDDIR)%.ci)
|
||||||
|
|
||||||
TESTS ?= $(wildcard tests_/*.toml)
|
TESTS ?= $(wildcard tests/*.toml)
|
||||||
TEST_SRC ?= $(SRC) \
|
TEST_SRC ?= $(SRC) \
|
||||||
$(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
|
$(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
|
||||||
runners/test_runner.c
|
runners/test_runner.c
|
||||||
@@ -53,10 +53,11 @@ override CFLAGS += -g3
|
|||||||
override CFLAGS += -I.
|
override CFLAGS += -I.
|
||||||
override CFLAGS += -std=c99 -Wall -pedantic
|
override CFLAGS += -std=c99 -Wall -pedantic
|
||||||
override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
|
override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
|
||||||
|
override CFLAGS += -ftrack-macro-expansion=0
|
||||||
|
|
||||||
override TESTFLAGS_ += -b
|
override TESTFLAGS += -b
|
||||||
# forward -j flag
|
# forward -j flag
|
||||||
override TESTFLAGS_ += $(filter -j%,$(MAKEFLAGS))
|
override TESTFLAGS += $(filter -j%,$(MAKEFLAGS))
|
||||||
ifdef VERBOSE
|
ifdef VERBOSE
|
||||||
override TESTFLAGS += -v
|
override TESTFLAGS += -v
|
||||||
override CALLSFLAGS += -v
|
override CALLSFLAGS += -v
|
||||||
@@ -65,15 +66,14 @@ override DATAFLAGS += -v
|
|||||||
override STACKFLAGS += -v
|
override STACKFLAGS += -v
|
||||||
override STRUCTSFLAGS += -v
|
override STRUCTSFLAGS += -v
|
||||||
override COVERAGEFLAGS += -v
|
override COVERAGEFLAGS += -v
|
||||||
override TESTFLAGS_ += -v
|
override TESTFLAGS += -v
|
||||||
override TESTCFLAGS_ += -v
|
override TESTCFLAGS += -v
|
||||||
endif
|
endif
|
||||||
ifdef EXEC
|
ifdef EXEC
|
||||||
override TESTFLAGS_ += --exec="$(EXEC)"
|
override TESTFLAGS += --exec="$(EXEC)"
|
||||||
endif
|
endif
|
||||||
ifdef COVERAGE
|
ifdef COVERAGE
|
||||||
override TESTFLAGS += --coverage
|
override TESTFLAGS += --coverage
|
||||||
override TESTFLAGS_ += --coverage
|
|
||||||
endif
|
endif
|
||||||
ifdef BUILDDIR
|
ifdef BUILDDIR
|
||||||
override TESTFLAGS += --build-dir="$(BUILDDIR:/=)"
|
override TESTFLAGS += --build-dir="$(BUILDDIR:/=)"
|
||||||
@@ -112,23 +112,16 @@ tags:
|
|||||||
calls: $(CGI)
|
calls: $(CGI)
|
||||||
./scripts/calls.py $^ $(CALLSFLAGS)
|
./scripts/calls.py $^ $(CALLSFLAGS)
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
test:
|
|
||||||
./scripts/test.py $(TESTFLAGS)
|
|
||||||
.SECONDEXPANSION:
|
|
||||||
test%: tests/test$$(firstword $$(subst \#, ,%)).toml
|
|
||||||
./scripts/test.py $@ $(TESTFLAGS)
|
|
||||||
|
|
||||||
.PHONY: test_runner
|
.PHONY: test_runner
|
||||||
test_runner: $(BUILDDIR)runners/test_runner
|
test_runner: $(BUILDDIR)runners/test_runner
|
||||||
|
|
||||||
.PHONY: test_
|
.PHONY: test
|
||||||
test_: test_runner
|
test: test_runner
|
||||||
./scripts/test_.py --runner=$(BUILDDIR)runners/test_runner $(TESTFLAGS_)
|
./scripts/test.py --runner=$(BUILDDIR)runners/test_runner $(TESTFLAGS)
|
||||||
|
|
||||||
.PHONY: test_list
|
.PHONY: test_list
|
||||||
test_list: test_runner
|
test_list: test_runner
|
||||||
./scripts/test_.py --runner=$(BUILDDIR)runners/test_runner $(TESTFLAGS_) -l
|
./scripts/test.py --runner=$(BUILDDIR)runners/test_runner $(TESTFLAGS) -l
|
||||||
|
|
||||||
.PHONY: code
|
.PHONY: code
|
||||||
code: $(OBJ)
|
code: $(OBJ)
|
||||||
@@ -199,10 +192,10 @@ $(BUILDDIR)%.a.c: $(BUILDDIR)%.c
|
|||||||
./scripts/explode_asserts.py $< -o $@
|
./scripts/explode_asserts.py $< -o $@
|
||||||
|
|
||||||
$(BUILDDIR)%.t.c: %.toml
|
$(BUILDDIR)%.t.c: %.toml
|
||||||
./scripts/test_.py -c $< $(TESTCFLAGS_) -o $@
|
./scripts/test.py -c $< $(TESTCFLAGS) -o $@
|
||||||
|
|
||||||
$(BUILDDIR)%.t.c: %.c $(TESTS)
|
$(BUILDDIR)%.t.c: %.c $(TESTS)
|
||||||
./scripts/test_.py -c $(TESTS) -s $< $(TESTCFLAGS_) -o $@
|
./scripts/test.py -c $(TESTS) -s $< $(TESTCFLAGS) -o $@
|
||||||
|
|
||||||
# clean everything
|
# clean everything
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
@@ -215,7 +208,6 @@ clean:
|
|||||||
rm -f $(CGI)
|
rm -f $(CGI)
|
||||||
rm -f $(DEP)
|
rm -f $(DEP)
|
||||||
rm -f $(ASM)
|
rm -f $(ASM)
|
||||||
rm -f $(BUILDDIR)tests/*.toml.*
|
|
||||||
rm -f $(TEST_TSRC)
|
rm -f $(TEST_TSRC)
|
||||||
rm -f $(TEST_TASRC)
|
rm -f $(TEST_TASRC)
|
||||||
rm -f $(TEST_TAOBJ)
|
rm -f $(TEST_TAOBJ)
|
||||||
|
|||||||
@@ -10,17 +10,17 @@
|
|||||||
// test geometries
|
// test geometries
|
||||||
struct test_geometry {
|
struct test_geometry {
|
||||||
const char *name;
|
const char *name;
|
||||||
uintmax_t defines[TEST_GEOMETRY_DEFINE_COUNT];
|
intmax_t defines[TEST_GEOMETRY_DEFINE_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct test_geometry test_geometries[TEST_GEOMETRY_COUNT]
|
const struct test_geometry test_geometries[TEST_GEOMETRY_COUNT]
|
||||||
= TEST_GEOMETRIES;
|
= TEST_GEOMETRIES;
|
||||||
|
|
||||||
// test define lookup and management
|
// test define lookup and management
|
||||||
const uintmax_t *test_override_defines;
|
const intmax_t *test_override_defines;
|
||||||
uintmax_t (*const *test_case_defines)(void);
|
intmax_t (*const *test_case_defines)(void);
|
||||||
const uintmax_t *test_geometry_defines;
|
const intmax_t *test_geometry_defines;
|
||||||
const uintmax_t test_default_defines[TEST_PREDEFINE_COUNT]
|
const intmax_t test_default_defines[TEST_PREDEFINE_COUNT]
|
||||||
= TEST_DEFAULTS;
|
= TEST_DEFAULTS;
|
||||||
|
|
||||||
uint8_t test_override_predefine_map[TEST_PREDEFINE_COUNT];
|
uint8_t test_override_predefine_map[TEST_PREDEFINE_COUNT];
|
||||||
@@ -37,7 +37,7 @@ const char *const *test_define_names;
|
|||||||
size_t test_define_count;
|
size_t test_define_count;
|
||||||
|
|
||||||
|
|
||||||
uintmax_t test_predefine(size_t define) {
|
intmax_t test_predefine(size_t define) {
|
||||||
if (test_override_defines
|
if (test_override_defines
|
||||||
&& test_override_predefine_map[define] != 0xff) {
|
&& test_override_predefine_map[define] != 0xff) {
|
||||||
return test_override_defines[test_override_predefine_map[define]];
|
return test_override_defines[test_override_predefine_map[define]];
|
||||||
@@ -52,7 +52,7 @@ uintmax_t test_predefine(size_t define) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uintmax_t test_define(size_t define) {
|
intmax_t test_define(size_t define) {
|
||||||
if (test_override_defines
|
if (test_override_defines
|
||||||
&& test_override_define_map[define] != 0xff) {
|
&& test_override_define_map[define] != 0xff) {
|
||||||
return test_override_defines[test_override_define_map[define]];
|
return test_override_defines[test_override_define_map[define]];
|
||||||
@@ -73,7 +73,7 @@ static void test_define_geometry(const struct test_geometry *geometry) {
|
|||||||
|
|
||||||
static void test_define_overrides(
|
static void test_define_overrides(
|
||||||
const char *const *override_names,
|
const char *const *override_names,
|
||||||
const uintmax_t *override_defines,
|
const intmax_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
test_override_defines = override_defines;
|
test_override_defines = override_defines;
|
||||||
test_override_names = override_names;
|
test_override_names = override_names;
|
||||||
@@ -583,7 +583,7 @@ int main(int argc, char **argv) {
|
|||||||
void (*op)(void) = run;
|
void (*op)(void) = run;
|
||||||
|
|
||||||
static const char **override_names = NULL;
|
static const char **override_names = NULL;
|
||||||
static uintmax_t *override_defines = NULL;
|
static intmax_t *override_defines = NULL;
|
||||||
static size_t override_count = 0;
|
static size_t override_count = 0;
|
||||||
static size_t override_cap = 0;
|
static size_t override_cap = 0;
|
||||||
|
|
||||||
@@ -685,10 +685,10 @@ int main(int argc, char **argv) {
|
|||||||
override_names = realloc(override_names, override_cap
|
override_names = realloc(override_names, override_cap
|
||||||
* sizeof(const char *));
|
* sizeof(const char *));
|
||||||
override_defines = realloc(override_defines, override_cap
|
override_defines = realloc(override_defines, override_cap
|
||||||
* sizeof(uintmax_t));
|
* sizeof(intmax_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse into string key/uintmax_t value, cannibalizing the
|
// parse into string key/intmax_t value, cannibalizing the
|
||||||
// arg in the process
|
// arg in the process
|
||||||
char *sep = strchr(optarg, '=');
|
char *sep = strchr(optarg, '=');
|
||||||
char *parsed = NULL;
|
char *parsed = NULL;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct test_case {
|
|||||||
test_types_t types;
|
test_types_t types;
|
||||||
size_t permutations;
|
size_t permutations;
|
||||||
|
|
||||||
uintmax_t (*const *const *defines)(void);
|
intmax_t (*const *const *defines)(void);
|
||||||
|
|
||||||
bool (*filter)(void);
|
bool (*filter)(void);
|
||||||
void (*run)(struct lfs_config *cfg);
|
void (*run)(struct lfs_config *cfg);
|
||||||
@@ -43,8 +43,8 @@ extern const size_t test_suite_count;
|
|||||||
|
|
||||||
|
|
||||||
// access generated test defines
|
// access generated test defines
|
||||||
uintmax_t test_predefine(size_t define);
|
intmax_t test_predefine(size_t define);
|
||||||
uintmax_t test_define(size_t define);
|
intmax_t test_define(size_t define);
|
||||||
|
|
||||||
// a few preconfigured defines that control how tests run
|
// a few preconfigured defines that control how tests run
|
||||||
#define READ_SIZE test_predefine(0)
|
#define READ_SIZE test_predefine(0)
|
||||||
|
|||||||
1735
scripts/test.py
1735
scripts/test.py
File diff suppressed because it is too large
Load Diff
1027
scripts/test_.py
1027
scripts/test_.py
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,30 @@
|
|||||||
# allocator tests
|
# allocator tests
|
||||||
# note for these to work there are a number constraints on the device geometry
|
# 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
|
# parallel allocation test
|
||||||
define.FILES = 3
|
[cases.parallel_allocation]
|
||||||
define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
|
defines.FILES = 3
|
||||||
|
defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
|
||||||
code = '''
|
code = '''
|
||||||
const char *names[FILES] = {"bacon", "eggs", "pancakes"};
|
const char *names[] = {"bacon", "eggs", "pancakes"};
|
||||||
lfs_file_t files[FILES];
|
lfs_file_t files[FILES];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "breakfast") => 0;
|
lfs_mkdir(&lfs, "breakfast") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
lfs_file_open(&lfs, &files[n], path,
|
lfs_file_open(&lfs, &files[n], path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
||||||
}
|
}
|
||||||
for (int n = 0; n < FILES; n++) {
|
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) {
|
for (lfs_size_t i = 0; i < SIZE; i += size) {
|
||||||
lfs_file_write(&lfs, &files[n], names[n], size) => size;
|
lfs_file_write(&lfs, &files[n], names[n], size) => size;
|
||||||
}
|
}
|
||||||
@@ -31,12 +34,15 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
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) {
|
for (lfs_size_t i = 0; i < SIZE; i += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
assert(memcmp(buffer, names[n], size) == 0);
|
assert(memcmp(buffer, names[n], size) == 0);
|
||||||
}
|
}
|
||||||
@@ -45,23 +51,28 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # serial allocation test
|
# serial allocation test
|
||||||
define.FILES = 3
|
[cases.serial_allocation]
|
||||||
define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
|
defines.FILES = 3
|
||||||
|
defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
|
||||||
code = '''
|
code = '''
|
||||||
const char *names[FILES] = {"bacon", "eggs", "pancakes"};
|
const char *names[] = {"bacon", "eggs", "pancakes"};
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "breakfast") => 0;
|
lfs_mkdir(&lfs, "breakfast") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
for (int n = 0; n < FILES; n++) {
|
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]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
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);
|
memcpy(buffer, names[n], size);
|
||||||
for (int i = 0; i < SIZE; i += size) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
@@ -70,12 +81,15 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
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) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
assert(memcmp(buffer, names[n], size) == 0);
|
assert(memcmp(buffer, names[n], size) == 0);
|
||||||
}
|
}
|
||||||
@@ -84,29 +98,32 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # parallel allocation reuse test
|
# parallel allocation reuse test
|
||||||
define.FILES = 3
|
[cases.parallel_allocation_reuse]
|
||||||
define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
|
defines.FILES = 3
|
||||||
define.CYCLES = [1, 10]
|
defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
|
||||||
|
defines.CYCLES = [1, 10]
|
||||||
code = '''
|
code = '''
|
||||||
const char *names[FILES] = {"bacon", "eggs", "pancakes"};
|
const char *names[] = {"bacon", "eggs", "pancakes"};
|
||||||
lfs_file_t files[FILES];
|
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++) {
|
for (int c = 0; c < CYCLES; c++) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "breakfast") => 0;
|
lfs_mkdir(&lfs, "breakfast") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
lfs_file_open(&lfs, &files[n], path,
|
lfs_file_open(&lfs, &files[n], path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
||||||
}
|
}
|
||||||
for (int n = 0; n < FILES; n++) {
|
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) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
lfs_file_write(&lfs, &files[n], names[n], size) => size;
|
lfs_file_write(&lfs, &files[n], names[n], size) => size;
|
||||||
}
|
}
|
||||||
@@ -116,12 +133,15 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
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) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
assert(memcmp(buffer, names[n], size) == 0);
|
assert(memcmp(buffer, names[n], size) == 0);
|
||||||
}
|
}
|
||||||
@@ -129,8 +149,9 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -139,26 +160,31 @@ code = '''
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # serial allocation reuse test
|
# serial allocation reuse test
|
||||||
define.FILES = 3
|
[cases.serial_allocation_reuse]
|
||||||
define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-6)) / FILES)'
|
defines.FILES = 3
|
||||||
define.CYCLES = [1, 10]
|
defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)'
|
||||||
|
defines.CYCLES = [1, 10]
|
||||||
code = '''
|
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++) {
|
for (int c = 0; c < CYCLES; c++) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "breakfast") => 0;
|
lfs_mkdir(&lfs, "breakfast") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
for (int n = 0; n < FILES; n++) {
|
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]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
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);
|
memcpy(buffer, names[n], size);
|
||||||
for (int i = 0; i < SIZE; i += size) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
@@ -167,12 +193,15 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
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) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
assert(memcmp(buffer, names[n], size) == 0);
|
assert(memcmp(buffer, names[n], size) == 0);
|
||||||
}
|
}
|
||||||
@@ -180,8 +209,9 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int n = 0; n < FILES; n++) {
|
for (int n = 0; n < FILES; n++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "breakfast/%s", names[n]);
|
sprintf(path, "breakfast/%s", names[n]);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -190,12 +220,16 @@ code = '''
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # exhaustion test
|
# exhaustion test
|
||||||
|
[cases.exhaustion]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
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);
|
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);
|
memcpy(buffer, "exhaustion", size);
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
lfs_file_sync(&lfs, &file) => 0;
|
lfs_file_sync(&lfs, &file) => 0;
|
||||||
@@ -216,7 +250,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_RDONLY);
|
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_RDONLY);
|
||||||
size = strlen("exhaustion");
|
size = strlen("exhaustion");
|
||||||
lfs_file_size(&lfs, &file) => size;
|
lfs_file_size(&lfs, &file) => size;
|
||||||
@@ -226,14 +260,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # exhaustion wraparound test
|
# exhaustion wraparound test
|
||||||
define.SIZE = '(((LFS_BLOCK_SIZE-8)*(LFS_BLOCK_COUNT-4)) / 3)'
|
[cases.exhaustion_wraparound]
|
||||||
|
defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-4)) / 3)'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
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);
|
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);
|
memcpy(buffer, "buffering", size);
|
||||||
for (int i = 0; i < SIZE; i += size) {
|
for (int i = 0; i < SIZE; i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
@@ -263,7 +301,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_RDONLY);
|
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_RDONLY);
|
||||||
size = strlen("exhaustion");
|
size = strlen("exhaustion");
|
||||||
lfs_file_size(&lfs, &file) => size;
|
lfs_file_size(&lfs, &file) => size;
|
||||||
@@ -274,17 +312,22 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # dir exhaustion test
|
# dir exhaustion test
|
||||||
|
[cases.dir_exhaustion]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// find out max file size
|
// find out max file size
|
||||||
lfs_mkdir(&lfs, "exhaustiondir") => 0;
|
lfs_mkdir(&lfs, "exhaustiondir") => 0;
|
||||||
size = strlen("blahblahblahblah");
|
size_t size = strlen("blahblahblahblah");
|
||||||
|
uint8_t buffer[1024];
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int err;
|
||||||
while (true) {
|
while (true) {
|
||||||
err = lfs_file_write(&lfs, &file, buffer, size);
|
err = lfs_file_write(&lfs, &file, buffer, size);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
@@ -323,17 +366,21 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
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.bad_block_allocation]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = 'LFS_TESTBD_BADBLOCK_READERROR'
|
defines.BADBLOCK_BEHAVIOR = 'LFS_TESTBD_BADBLOCK_READERROR'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
// first fill to exhaustion to find available space
|
// 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;
|
lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "waka");
|
strcpy((char*)buffer, "waka");
|
||||||
size = strlen("waka");
|
size_t size = strlen("waka");
|
||||||
lfs_size_t filesize = 0;
|
lfs_size_t filesize = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
||||||
@@ -345,7 +392,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
// now fill all but a couple of blocks of the filesystem with data
|
// 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;
|
lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
strcpy((char*)buffer, "waka");
|
strcpy((char*)buffer, "waka");
|
||||||
size = strlen("waka");
|
size = strlen("waka");
|
||||||
@@ -358,11 +405,11 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// remount to force an alloc scan
|
// 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
|
// but mark the head of our file as a "bad block", this is force our
|
||||||
// scan to bail early
|
// scan to bail early
|
||||||
lfs_testbd_setwear(&cfg, fileblock, 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, fileblock, 0xffffffff) => 0;
|
||||||
lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
strcpy((char*)buffer, "chomp");
|
strcpy((char*)buffer, "chomp");
|
||||||
size = strlen("chomp");
|
size = strlen("chomp");
|
||||||
@@ -377,7 +424,7 @@ code = '''
|
|||||||
|
|
||||||
// now reverse the "bad block" and try to write the file again until we
|
// now reverse the "bad block" and try to write the file again until we
|
||||||
// run out of space
|
// run out of space
|
||||||
lfs_testbd_setwear(&cfg, fileblock, 0) => 0;
|
lfs_testbd_setwear(cfg, fileblock, 0) => 0;
|
||||||
lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
strcpy((char*)buffer, "chomp");
|
strcpy((char*)buffer, "chomp");
|
||||||
size = strlen("chomp");
|
size = strlen("chomp");
|
||||||
@@ -393,7 +440,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// check that the disk isn't hurt
|
// 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;
|
lfs_file_open(&lfs, &file, "pacman", LFS_O_RDONLY) => 0;
|
||||||
strcpy((char*)buffer, "waka");
|
strcpy((char*)buffer, "waka");
|
||||||
size = strlen("waka");
|
size = strlen("waka");
|
||||||
@@ -411,24 +458,29 @@ code = '''
|
|||||||
# on the geometry of the block device. But they are valuable. Eventually they
|
# on the geometry of the block device. But they are valuable. Eventually they
|
||||||
# should be removed and replaced with generalized tests.
|
# should be removed and replaced with generalized tests.
|
||||||
|
|
||||||
[[case]] # chained dir exhaustion test
|
# chained dir exhaustion test
|
||||||
define.LFS_BLOCK_SIZE = 512
|
[cases.chained_dir_exhaustion]
|
||||||
define.LFS_BLOCK_COUNT = 1024
|
if = 'BLOCK_SIZE == 512'
|
||||||
if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
|
defines.BLOCK_COUNT = 1024
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// find out max file size
|
// find out max file size
|
||||||
lfs_mkdir(&lfs, "exhaustiondir") => 0;
|
lfs_mkdir(&lfs, "exhaustiondir") => 0;
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
|
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
size = strlen("blahblahblahblah");
|
size_t size = strlen("blahblahblahblah");
|
||||||
|
uint8_t buffer[1024];
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int err;
|
||||||
while (true) {
|
while (true) {
|
||||||
err = lfs_file_write(&lfs, &file, buffer, size);
|
err = lfs_file_write(&lfs, &file, buffer, size);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
@@ -443,6 +495,7 @@ code = '''
|
|||||||
lfs_remove(&lfs, "exhaustion") => 0;
|
lfs_remove(&lfs, "exhaustion") => 0;
|
||||||
lfs_remove(&lfs, "exhaustiondir") => 0;
|
lfs_remove(&lfs, "exhaustiondir") => 0;
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
|
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -455,6 +508,7 @@ code = '''
|
|||||||
lfs_file_sync(&lfs, &file) => 0;
|
lfs_file_sync(&lfs, &file) => 0;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
|
sprintf(path, "dirwithanexhaustivelylongnameforpadding%d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -482,27 +536,31 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # split dir test
|
# split dir test
|
||||||
define.LFS_BLOCK_SIZE = 512
|
[cases.split_dir]
|
||||||
define.LFS_BLOCK_COUNT = 1024
|
if = 'BLOCK_SIZE == 512'
|
||||||
if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
|
defines.BLOCK_COUNT = 1024
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// create one block hole for half a directory
|
// 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;
|
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);
|
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_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
lfs_file_open(&lfs, &file, "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
||||||
size = strlen("blahblahblahblah");
|
size_t size = strlen("blahblahblahblah");
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -510,7 +568,7 @@ code = '''
|
|||||||
|
|
||||||
// remount to force reset of lookahead
|
// remount to force reset of lookahead
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// open hole
|
// open hole
|
||||||
lfs_remove(&lfs, "bump") => 0;
|
lfs_remove(&lfs, "bump") => 0;
|
||||||
@@ -518,30 +576,33 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "splitdir") => 0;
|
lfs_mkdir(&lfs, "splitdir") => 0;
|
||||||
lfs_file_open(&lfs, &file, "splitdir/bump",
|
lfs_file_open(&lfs, &file, "splitdir/bump",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
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);
|
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_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # outdated lookahead test
|
# outdated lookahead test
|
||||||
define.LFS_BLOCK_SIZE = 512
|
[cases.outdated_lookahead]
|
||||||
define.LFS_BLOCK_COUNT = 1024
|
if = 'BLOCK_SIZE == 512'
|
||||||
if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
|
defines.BLOCK_COUNT = 1024
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// fill completely with two files
|
// fill completely with two files
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "exhaustion1",
|
lfs_file_open(&lfs, &file, "exhaustion1",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
size = strlen("blahblahblahblah");
|
size_t size = strlen("blahblahblahblah");
|
||||||
|
uint8_t buffer[1024];
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -552,7 +613,7 @@ code = '''
|
|||||||
size = strlen("blahblahblahblah");
|
size = strlen("blahblahblahblah");
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -560,7 +621,7 @@ code = '''
|
|||||||
|
|
||||||
// remount to force reset of lookahead
|
// remount to force reset of lookahead
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// rewrite one file
|
// rewrite one file
|
||||||
lfs_file_open(&lfs, &file, "exhaustion1",
|
lfs_file_open(&lfs, &file, "exhaustion1",
|
||||||
@@ -569,7 +630,7 @@ code = '''
|
|||||||
size = strlen("blahblahblahblah");
|
size = strlen("blahblahblahblah");
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -583,7 +644,7 @@ code = '''
|
|||||||
size = strlen("blahblahblahblah");
|
size = strlen("blahblahblahblah");
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -592,21 +653,24 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # outdated lookahead and split dir test
|
# outdated lookahead and split dir test
|
||||||
define.LFS_BLOCK_SIZE = 512
|
[cases.outdated_lookahead_split_dir]
|
||||||
define.LFS_BLOCK_COUNT = 1024
|
if = 'BLOCK_SIZE == 512'
|
||||||
if = 'LFS_BLOCK_SIZE == 512 && LFS_BLOCK_COUNT == 1024'
|
defines.BLOCK_COUNT = 1024
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// fill completely with two files
|
// fill completely with two files
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "exhaustion1",
|
lfs_file_open(&lfs, &file, "exhaustion1",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
size = strlen("blahblahblahblah");
|
size_t size = strlen("blahblahblahblah");
|
||||||
|
uint8_t buffer[1024];
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -617,7 +681,7 @@ code = '''
|
|||||||
size = strlen("blahblahblahblah");
|
size = strlen("blahblahblahblah");
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -625,7 +689,7 @@ code = '''
|
|||||||
|
|
||||||
// remount to force reset of lookahead
|
// remount to force reset of lookahead
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// rewrite one file with a hole of one block
|
// rewrite one file with a hole of one block
|
||||||
lfs_file_open(&lfs, &file, "exhaustion1",
|
lfs_file_open(&lfs, &file, "exhaustion1",
|
||||||
@@ -634,7 +698,7 @@ code = '''
|
|||||||
size = strlen("blahblahblahblah");
|
size = strlen("blahblahblahblah");
|
||||||
memcpy(buffer, "blahblahblahblah", size);
|
memcpy(buffer, "blahblahblahblah", size);
|
||||||
for (lfs_size_t i = 0;
|
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) {
|
i += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
[[case]] # set/get attribute
|
[cases.get_set_attrs]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "hello") => 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_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
||||||
lfs_file_close(&lfs, &file);
|
lfs_file_close(&lfs, &file);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
lfs_setattr(&lfs, "hello", 'A', "aaaa", 4) => 0;
|
lfs_setattr(&lfs, "hello", 'A', "aaaa", 4) => 0;
|
||||||
lfs_setattr(&lfs, "hello", 'B', "bbbbbb", 6) => 0;
|
lfs_setattr(&lfs, "hello", 'B', "bbbbbb", 6) => 0;
|
||||||
@@ -60,7 +63,7 @@ code = '''
|
|||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
||||||
lfs_getattr(&lfs, "hello", 'B', buffer+4, 9) => 9;
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 9) => 9;
|
||||||
@@ -76,17 +79,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # set/get root attribute
|
[cases.get_set_root_attrs]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "hello") => 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_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
||||||
lfs_file_close(&lfs, &file);
|
lfs_file_close(&lfs, &file);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
lfs_setattr(&lfs, "/", 'A', "aaaa", 4) => 0;
|
lfs_setattr(&lfs, "/", 'A', "aaaa", 4) => 0;
|
||||||
lfs_setattr(&lfs, "/", 'B', "bbbbbb", 6) => 0;
|
lfs_setattr(&lfs, "/", 'B', "bbbbbb", 6) => 0;
|
||||||
@@ -137,7 +143,7 @@ code = '''
|
|||||||
lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
||||||
lfs_getattr(&lfs, "/", 'B', buffer+4, 9) => 9;
|
lfs_getattr(&lfs, "/", 'B', buffer+4, 9) => 9;
|
||||||
@@ -153,17 +159,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # set/get file attribute
|
[cases.get_set_file_attrs]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "hello") => 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_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
||||||
lfs_file_close(&lfs, &file);
|
lfs_file_close(&lfs, &file);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
struct lfs_attr attrs1[] = {
|
struct lfs_attr attrs1[] = {
|
||||||
{'A', buffer, 4},
|
{'A', buffer, 4},
|
||||||
@@ -238,7 +247,7 @@ code = '''
|
|||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
struct lfs_attr attrs3[] = {
|
struct lfs_attr attrs3[] = {
|
||||||
{'A', buffer, 4},
|
{'A', buffer, 4},
|
||||||
@@ -260,20 +269,23 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # deferred file attributes
|
[cases.deferred_file_attrs]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "hello") => 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_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
||||||
lfs_file_close(&lfs, &file);
|
lfs_file_close(&lfs, &file);
|
||||||
lfs_unmount(&lfs) => 0;
|
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", 'B', "fffffffff", 9) => 0;
|
||||||
lfs_setattr(&lfs, "hello/hello", 'C', "ccccc", 5) => 0;
|
lfs_setattr(&lfs, "hello/hello", 'C', "ccccc", 5) => 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
struct lfs_attr attrs1[] = {
|
struct lfs_attr attrs1[] = {
|
||||||
{'B', "gggg", 4},
|
{'B', "gggg", 4},
|
||||||
|
|||||||
@@ -1,28 +1,30 @@
|
|||||||
# bad blocks with block cycles should be tested in test_relocations
|
# bad blocks with block cycles should be tested in test_relocations
|
||||||
if = 'LFS_BLOCK_CYCLES == -1'
|
if = '(int32_t)BLOCK_CYCLES == -1'
|
||||||
|
|
||||||
[[case]] # single bad blocks
|
[cases.single_bad_blocks]
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
|
defines.ERASE_VALUE = [0x00, 0xff, -1]
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = [
|
defines.BADBLOCK_BEHAVIOR = [
|
||||||
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_READERROR',
|
'LFS_TESTBD_BADBLOCK_READERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
||||||
]
|
]
|
||||||
define.NAMEMULT = 64
|
defines.NAMEMULT = 64
|
||||||
define.FILEMULT = 1
|
defines.FILEMULT = 1
|
||||||
code = '''
|
code = '''
|
||||||
for (lfs_block_t badblock = 2; badblock < LFS_BLOCK_COUNT; badblock++) {
|
for (lfs_block_t badblock = 2; badblock < BLOCK_COUNT; badblock++) {
|
||||||
lfs_testbd_setwear(&cfg, badblock-1, 0) => 0;
|
lfs_testbd_setwear(cfg, badblock-1, 0) => 0;
|
||||||
lfs_testbd_setwear(&cfg, badblock, 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, badblock, 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++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (int j = 0; j < NAMEMULT; j++) {
|
for (int j = 0; j < NAMEMULT; j++) {
|
||||||
buffer[j] = '0'+i;
|
buffer[j] = '0'+i;
|
||||||
}
|
}
|
||||||
@@ -34,10 +36,11 @@ code = '''
|
|||||||
buffer[j+NAMEMULT+1] = '0'+i;
|
buffer[j+NAMEMULT+1] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[2*NAMEMULT+1] = '\0';
|
buffer[2*NAMEMULT+1] = '\0';
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, (char*)buffer,
|
lfs_file_open(&lfs, &file, (char*)buffer,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
size = NAMEMULT;
|
lfs_size_t size = NAMEMULT;
|
||||||
for (int j = 0; j < i*FILEMULT; j++) {
|
for (int j = 0; j < i*FILEMULT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -46,12 +49,14 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 1; i < 10; i++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (int j = 0; j < NAMEMULT; j++) {
|
for (int j = 0; j < NAMEMULT; j++) {
|
||||||
buffer[j] = '0'+i;
|
buffer[j] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[NAMEMULT] = '\0';
|
buffer[NAMEMULT] = '\0';
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, (char*)buffer, &info) => 0;
|
lfs_stat(&lfs, (char*)buffer, &info) => 0;
|
||||||
info.type => LFS_TYPE_DIR;
|
info.type => LFS_TYPE_DIR;
|
||||||
|
|
||||||
@@ -60,9 +65,10 @@ code = '''
|
|||||||
buffer[j+NAMEMULT+1] = '0'+i;
|
buffer[j+NAMEMULT+1] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[2*NAMEMULT+1] = '\0';
|
buffer[2*NAMEMULT+1] = '\0';
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
|
||||||
|
|
||||||
size = NAMEMULT;
|
int size = NAMEMULT;
|
||||||
for (int j = 0; j < i*FILEMULT; j++) {
|
for (int j = 0; j < i*FILEMULT; j++) {
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
||||||
@@ -75,28 +81,30 @@ code = '''
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # region corruption (causes cascading failures)
|
[cases.region_corruption] # (causes cascading failures)
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
|
defines.ERASE_VALUE = [0x00, 0xff, -1]
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = [
|
defines.BADBLOCK_BEHAVIOR = [
|
||||||
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_READERROR',
|
'LFS_TESTBD_BADBLOCK_READERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
||||||
]
|
]
|
||||||
define.NAMEMULT = 64
|
defines.NAMEMULT = 64
|
||||||
define.FILEMULT = 1
|
defines.FILEMULT = 1
|
||||||
code = '''
|
code = '''
|
||||||
for (lfs_block_t i = 0; i < (LFS_BLOCK_COUNT-2)/2; i++) {
|
for (lfs_block_t i = 0; i < (BLOCK_COUNT-2)/2; i++) {
|
||||||
lfs_testbd_setwear(&cfg, i+2, 0xffffffff) => 0;
|
lfs_testbd_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++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (int j = 0; j < NAMEMULT; j++) {
|
for (int j = 0; j < NAMEMULT; j++) {
|
||||||
buffer[j] = '0'+i;
|
buffer[j] = '0'+i;
|
||||||
}
|
}
|
||||||
@@ -108,10 +116,11 @@ code = '''
|
|||||||
buffer[j+NAMEMULT+1] = '0'+i;
|
buffer[j+NAMEMULT+1] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[2*NAMEMULT+1] = '\0';
|
buffer[2*NAMEMULT+1] = '\0';
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, (char*)buffer,
|
lfs_file_open(&lfs, &file, (char*)buffer,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
size = NAMEMULT;
|
lfs_size_t size = NAMEMULT;
|
||||||
for (int j = 0; j < i*FILEMULT; j++) {
|
for (int j = 0; j < i*FILEMULT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -120,12 +129,14 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 1; i < 10; i++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (int j = 0; j < NAMEMULT; j++) {
|
for (int j = 0; j < NAMEMULT; j++) {
|
||||||
buffer[j] = '0'+i;
|
buffer[j] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[NAMEMULT] = '\0';
|
buffer[NAMEMULT] = '\0';
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, (char*)buffer, &info) => 0;
|
lfs_stat(&lfs, (char*)buffer, &info) => 0;
|
||||||
info.type => LFS_TYPE_DIR;
|
info.type => LFS_TYPE_DIR;
|
||||||
|
|
||||||
@@ -134,9 +145,10 @@ code = '''
|
|||||||
buffer[j+NAMEMULT+1] = '0'+i;
|
buffer[j+NAMEMULT+1] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[2*NAMEMULT+1] = '\0';
|
buffer[2*NAMEMULT+1] = '\0';
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
|
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++) {
|
for (int j = 0; j < i*FILEMULT; j++) {
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
||||||
@@ -148,28 +160,30 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # alternating corruption (causes cascading failures)
|
[cases.alternating_corruption] # (causes cascading failures)
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
|
defines.ERASE_VALUE = [0x00, 0xff, -1]
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = [
|
defines.BADBLOCK_BEHAVIOR = [
|
||||||
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_READERROR',
|
'LFS_TESTBD_BADBLOCK_READERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
||||||
]
|
]
|
||||||
define.NAMEMULT = 64
|
defines.NAMEMULT = 64
|
||||||
define.FILEMULT = 1
|
defines.FILEMULT = 1
|
||||||
code = '''
|
code = '''
|
||||||
for (lfs_block_t i = 0; i < (LFS_BLOCK_COUNT-2)/2; i++) {
|
for (lfs_block_t i = 0; i < (BLOCK_COUNT-2)/2; i++) {
|
||||||
lfs_testbd_setwear(&cfg, (2*i) + 2, 0xffffffff) => 0;
|
lfs_testbd_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++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (int j = 0; j < NAMEMULT; j++) {
|
for (int j = 0; j < NAMEMULT; j++) {
|
||||||
buffer[j] = '0'+i;
|
buffer[j] = '0'+i;
|
||||||
}
|
}
|
||||||
@@ -181,10 +195,11 @@ code = '''
|
|||||||
buffer[j+NAMEMULT+1] = '0'+i;
|
buffer[j+NAMEMULT+1] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[2*NAMEMULT+1] = '\0';
|
buffer[2*NAMEMULT+1] = '\0';
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, (char*)buffer,
|
lfs_file_open(&lfs, &file, (char*)buffer,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
size = NAMEMULT;
|
lfs_size_t size = NAMEMULT;
|
||||||
for (int j = 0; j < i*FILEMULT; j++) {
|
for (int j = 0; j < i*FILEMULT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -193,12 +208,14 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 1; i < 10; i++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (int j = 0; j < NAMEMULT; j++) {
|
for (int j = 0; j < NAMEMULT; j++) {
|
||||||
buffer[j] = '0'+i;
|
buffer[j] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[NAMEMULT] = '\0';
|
buffer[NAMEMULT] = '\0';
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, (char*)buffer, &info) => 0;
|
lfs_stat(&lfs, (char*)buffer, &info) => 0;
|
||||||
info.type => LFS_TYPE_DIR;
|
info.type => LFS_TYPE_DIR;
|
||||||
|
|
||||||
@@ -207,9 +224,10 @@ code = '''
|
|||||||
buffer[j+NAMEMULT+1] = '0'+i;
|
buffer[j+NAMEMULT+1] = '0'+i;
|
||||||
}
|
}
|
||||||
buffer[2*NAMEMULT+1] = '\0';
|
buffer[2*NAMEMULT+1] = '\0';
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, (char*)buffer, LFS_O_RDONLY) => 0;
|
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++) {
|
for (int j = 0; j < i*FILEMULT; j++) {
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
||||||
@@ -222,10 +240,10 @@ code = '''
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# other corner cases
|
# other corner cases
|
||||||
[[case]] # bad superblocks (corrupt 1 or 0)
|
[cases.bad_superblocks] # (corrupt 1 or 0)
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
define.LFS_ERASE_VALUE = [0x00, 0xff, -1]
|
defines.ERASE_VALUE = [0x00, 0xff, -1]
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = [
|
defines.BADBLOCK_BEHAVIOR = [
|
||||||
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_READERROR',
|
'LFS_TESTBD_BADBLOCK_READERROR',
|
||||||
@@ -233,9 +251,10 @@ define.LFS_BADBLOCK_BEHAVIOR = [
|
|||||||
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_testbd_setwear(&cfg, 0, 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, 0, 0xffffffff) => 0;
|
||||||
lfs_testbd_setwear(&cfg, 1, 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, 1, 0xffffffff) => 0;
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => LFS_ERR_NOSPC;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
|
lfs_format(&lfs, cfg) => LFS_ERR_NOSPC;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
[[case]] # root
|
[cases.root]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -14,20 +17,25 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # many directory creation
|
[cases.many_dir_creation]
|
||||||
define.N = 'range(0, 100, 3)'
|
defines.N = [3,6,9,12,21,33,57,66,72,93,99]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "dir%03d", i);
|
sprintf(path, "dir%03d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -35,6 +43,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "dir%03d", i);
|
sprintf(path, "dir%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -45,20 +54,25 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # many directory removal
|
[cases.many_dir_removal]
|
||||||
define.N = 'range(3, 100, 11)'
|
defines.N = [3,6,9,12,21,33,57,66,72,93,99]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "removeme%03d", i);
|
sprintf(path, "removeme%03d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -66,6 +80,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "removeme%03d", i);
|
sprintf(path, "removeme%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -75,14 +90,15 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "removeme%03d", i);
|
sprintf(path, "removeme%03d", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -95,20 +111,25 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # many directory rename
|
[cases.many_dir_rename]
|
||||||
define.N = 'range(3, 100, 11)'
|
defines.N = [3,6,9,12,21,33,57,66,72,93,99]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%03d", i);
|
sprintf(path, "test%03d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -116,6 +137,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%03d", i);
|
sprintf(path, "test%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -125,7 +147,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
char oldpath[128];
|
char oldpath[128];
|
||||||
char newpath[128];
|
char newpath[128];
|
||||||
@@ -135,7 +157,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -144,6 +166,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "tedd%03d", i);
|
sprintf(path, "tedd%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -154,29 +177,34 @@ code = '''
|
|||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant many directory creation/rename/removal
|
[cases.reentrant_many_dir]
|
||||||
define.N = [5, 11]
|
defines.N = [5, 11]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", i);
|
sprintf(path, "hi%03d", i);
|
||||||
err = lfs_mkdir(&lfs, path);
|
err = lfs_mkdir(&lfs, path);
|
||||||
assert(err == 0 || err == LFS_ERR_EXIST);
|
assert(err == 0 || err == LFS_ERR_EXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello%03d", i);
|
sprintf(path, "hello%03d", i);
|
||||||
err = lfs_remove(&lfs, path);
|
err = lfs_remove(&lfs, path);
|
||||||
assert(err == 0 || err == LFS_ERR_NOENT);
|
assert(err == 0 || err == LFS_ERR_NOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -184,6 +212,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", i);
|
sprintf(path, "hi%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -209,6 +238,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello%03d", i);
|
sprintf(path, "hello%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -218,6 +248,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello%03d", i);
|
sprintf(path, "hello%03d", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -234,22 +265,28 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # file creation
|
[cases.file_creation]
|
||||||
define.N = 'range(3, 100, 11)'
|
defines.N = [3,6,9,12,21,33,57,66,72,93,99]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "file%03d", i);
|
sprintf(path, "file%03d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -257,6 +294,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "file%03d", i);
|
sprintf(path, "file%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -267,22 +305,28 @@ code = '''
|
|||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # file removal
|
[cases.file_removal]
|
||||||
define.N = 'range(0, 100, 3)'
|
defines.N = [3,6,9,12,21,33,57,66,72,93,99]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "removeme%03d", i);
|
sprintf(path, "removeme%03d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -290,6 +334,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "removeme%03d", i);
|
sprintf(path, "removeme%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -299,14 +344,15 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "removeme%03d", i);
|
sprintf(path, "removeme%03d", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -319,22 +365,28 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # file rename
|
[cases.file_rename]
|
||||||
define.N = 'range(0, 100, 3)'
|
defines.N = [3,6,9,12,21,33,57,66,72,93,99]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%03d", i);
|
sprintf(path, "test%03d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -342,6 +394,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%03d", i);
|
sprintf(path, "test%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -351,7 +404,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
char oldpath[128];
|
char oldpath[128];
|
||||||
char newpath[128];
|
char newpath[128];
|
||||||
@@ -361,7 +414,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -370,6 +423,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "tedd%03d", i);
|
sprintf(path, "tedd%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -380,29 +434,36 @@ code = '''
|
|||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant file creation/rename/removal
|
[cases.reentrant_files]
|
||||||
define.N = [5, 25]
|
defines.N = [5, 25]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", i);
|
sprintf(path, "hi%03d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello%03d", i);
|
sprintf(path, "hello%03d", i);
|
||||||
err = lfs_remove(&lfs, path);
|
err = lfs_remove(&lfs, path);
|
||||||
assert(err == 0 || err == LFS_ERR_NOENT);
|
assert(err == 0 || err == LFS_ERR_NOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -410,6 +471,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", i);
|
sprintf(path, "hi%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -435,6 +497,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello%03d", i);
|
sprintf(path, "hello%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -444,6 +507,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello%03d", i);
|
sprintf(path, "hello%03d", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -460,24 +524,28 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # nested directories
|
[cases.nested_dirs]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "potato") => 0;
|
lfs_mkdir(&lfs, "potato") => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "burito",
|
lfs_file_open(&lfs, &file, "burito",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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/baked") => 0;
|
||||||
lfs_mkdir(&lfs, "potato/sweet") => 0;
|
lfs_mkdir(&lfs, "potato/sweet") => 0;
|
||||||
lfs_mkdir(&lfs, "potato/fried") => 0;
|
lfs_mkdir(&lfs, "potato/fried") => 0;
|
||||||
lfs_unmount(&lfs) => 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;
|
lfs_dir_open(&lfs, &dir, "potato") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
info.type => LFS_TYPE_DIR;
|
info.type => LFS_TYPE_DIR;
|
||||||
@@ -498,21 +566,21 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// try removing?
|
// try removing?
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY;
|
lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// try renaming?
|
// try renaming?
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "potato", "coldpotato") => 0;
|
lfs_rename(&lfs, "potato", "coldpotato") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "coldpotato", "warmpotato") => 0;
|
lfs_rename(&lfs, "coldpotato", "warmpotato") => 0;
|
||||||
lfs_rename(&lfs, "warmpotato", "hotpotato") => 0;
|
lfs_rename(&lfs, "warmpotato", "hotpotato") => 0;
|
||||||
lfs_unmount(&lfs) => 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, "potato") => LFS_ERR_NOENT;
|
||||||
lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT;
|
lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT;
|
||||||
lfs_remove(&lfs, "warmpotato") => LFS_ERR_NOENT;
|
lfs_remove(&lfs, "warmpotato") => LFS_ERR_NOENT;
|
||||||
@@ -520,7 +588,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// try cross-directory renaming
|
// try cross-directory renaming
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "coldpotato") => 0;
|
lfs_mkdir(&lfs, "coldpotato") => 0;
|
||||||
lfs_rename(&lfs, "hotpotato/baked", "coldpotato/baked") => 0;
|
lfs_rename(&lfs, "hotpotato/baked", "coldpotato/baked") => 0;
|
||||||
lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY;
|
lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY;
|
||||||
@@ -536,7 +604,7 @@ code = '''
|
|||||||
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "hotpotato") => 0;
|
lfs_dir_open(&lfs, &dir, "hotpotato") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -558,7 +626,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// final remove
|
// final remove
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
||||||
lfs_remove(&lfs, "hotpotato/baked") => 0;
|
lfs_remove(&lfs, "hotpotato/baked") => 0;
|
||||||
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY;
|
||||||
@@ -568,7 +636,7 @@ code = '''
|
|||||||
lfs_remove(&lfs, "hotpotato") => 0;
|
lfs_remove(&lfs, "hotpotato") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -584,17 +652,22 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # recursive remove
|
[cases.recursive_remove]
|
||||||
define.N = [10, 100]
|
defines.N = [10, 100]
|
||||||
|
if = 'N < BLOCK_COUNT/2'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "prickly-pear") => 0;
|
lfs_mkdir(&lfs, "prickly-pear") => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "prickly-pear/cactus%03d", i);
|
sprintf(path, "prickly-pear/cactus%03d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
|
lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -602,6 +675,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "cactus%03d", i);
|
sprintf(path, "cactus%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -611,7 +685,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs);
|
lfs_unmount(&lfs);
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY;
|
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY;
|
||||||
|
|
||||||
lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
|
lfs_dir_open(&lfs, &dir, "prickly-pear") => 0;
|
||||||
@@ -622,6 +696,7 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "cactus%03d", i);
|
sprintf(path, "cactus%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -636,22 +711,24 @@ code = '''
|
|||||||
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
|
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
|
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # other error cases
|
[cases.other_errors]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "potato") => 0;
|
lfs_mkdir(&lfs, "potato") => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "burito",
|
lfs_file_open(&lfs, &file, "burito",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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, "potato") => LFS_ERR_EXIST;
|
||||||
lfs_mkdir(&lfs, "burito") => LFS_ERR_EXIST;
|
lfs_mkdir(&lfs, "burito") => LFS_ERR_EXIST;
|
||||||
@@ -659,6 +736,7 @@ code = '''
|
|||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
|
||||||
lfs_file_open(&lfs, &file, "potato",
|
lfs_file_open(&lfs, &file, "potato",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST;
|
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, "tomato") => LFS_ERR_NOENT;
|
||||||
lfs_dir_open(&lfs, &dir, "burito") => LFS_ERR_NOTDIR;
|
lfs_dir_open(&lfs, &dir, "burito") => LFS_ERR_NOTDIR;
|
||||||
lfs_file_open(&lfs, &file, "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
lfs_file_open(&lfs, &file, "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||||
@@ -678,6 +756,7 @@ code = '''
|
|||||||
|
|
||||||
// check that errors did not corrupt directory
|
// check that errors did not corrupt directory
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -696,7 +775,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// or on disk
|
// or on disk
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -715,21 +794,26 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # directory seek
|
[cases.directory_seek]
|
||||||
define.COUNT = [4, 128, 132]
|
defines.COUNT = [4, 128, 132]
|
||||||
|
if = 'COUNT < BLOCK_COUNT/2'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "hello") => 0;
|
lfs_mkdir(&lfs, "hello") => 0;
|
||||||
for (int i = 0; i < COUNT; i++) {
|
for (int i = 0; i < COUNT; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hello/kitty%03d", i);
|
sprintf(path, "hello/kitty%03d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
for (int j = 2; j < COUNT; j++) {
|
for (int j = 2; j < COUNT; j++) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "hello") => 0;
|
lfs_dir_open(&lfs, &dir, "hello") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -739,6 +823,7 @@ code = '''
|
|||||||
|
|
||||||
lfs_soff_t pos;
|
lfs_soff_t pos;
|
||||||
for (int i = 0; i < j; i++) {
|
for (int i = 0; i < j; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "kitty%03d", i);
|
sprintf(path, "kitty%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, path) == 0);
|
assert(strcmp(info.name, path) == 0);
|
||||||
@@ -748,13 +833,14 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
lfs_dir_seek(&lfs, &dir, pos) => 0;
|
lfs_dir_seek(&lfs, &dir, pos) => 0;
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "kitty%03d", j);
|
sprintf(path, "kitty%03d", j);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, path) == 0);
|
assert(strcmp(info.name, path) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
|
|
||||||
lfs_dir_rewind(&lfs, &dir) => 0;
|
lfs_dir_rewind(&lfs, &dir) => 0;
|
||||||
sprintf(path, "kitty%03d", 0);
|
sprintf(path, "kitty%03u", 0);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -776,20 +862,25 @@ code = '''
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # root seek
|
[cases.root_seek]
|
||||||
define.COUNT = [4, 128, 132]
|
defines.COUNT = [4, 128, 132]
|
||||||
|
if = 'COUNT < BLOCK_COUNT/2'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < COUNT; i++) {
|
for (int i = 0; i < COUNT; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", i);
|
sprintf(path, "hi%03d", i);
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
for (int j = 2; j < COUNT; j++) {
|
for (int j = 2; j < COUNT; j++) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -799,6 +890,7 @@ code = '''
|
|||||||
|
|
||||||
lfs_soff_t pos;
|
lfs_soff_t pos;
|
||||||
for (int i = 0; i < j; i++) {
|
for (int i = 0; i < j; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", i);
|
sprintf(path, "hi%03d", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, path) == 0);
|
assert(strcmp(info.name, path) == 0);
|
||||||
@@ -808,13 +900,14 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
lfs_dir_seek(&lfs, &dir, pos) => 0;
|
lfs_dir_seek(&lfs, &dir, pos) => 0;
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hi%03d", j);
|
sprintf(path, "hi%03d", j);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, path) == 0);
|
assert(strcmp(info.name, path) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
|
|
||||||
lfs_dir_rewind(&lfs, &dir) => 0;
|
lfs_dir_rewind(&lfs, &dir) => 0;
|
||||||
sprintf(path, "hi%03d", 0);
|
sprintf(path, "hi%03u", 0);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
|
|||||||
@@ -2,19 +2,23 @@
|
|||||||
# Note that these tests are intended for 512 byte inline sizes. They should
|
# 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.
|
# still pass with other inline sizes but wouldn't be testing anything.
|
||||||
|
|
||||||
define.LFS_CACHE_SIZE = 512
|
defines.CACHE_SIZE = 512
|
||||||
if = 'LFS_CACHE_SIZE % LFS_PROG_SIZE == 0 && LFS_CACHE_SIZE == 512'
|
if = 'CACHE_SIZE % PROG_SIZE == 0 && CACHE_SIZE == 512'
|
||||||
|
|
||||||
[[case]] # entry grow test
|
[cases.entry_grow]
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write hi0 20
|
// write hi0 20
|
||||||
|
char path[1024];
|
||||||
|
lfs_size_t size;
|
||||||
sprintf(path, "hi0"); size = 20;
|
sprintf(path, "hi0"); size = 20;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
memset(wbuffer, 'c', size);
|
memset(wbuffer, 'c', size);
|
||||||
@@ -94,16 +98,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # entry shrink test
|
[cases.entry_shrink]
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write hi0 20
|
// write hi0 20
|
||||||
|
char path[1024];
|
||||||
|
lfs_size_t size;
|
||||||
sprintf(path, "hi0"); size = 20;
|
sprintf(path, "hi0"); size = 20;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
memset(wbuffer, 'c', size);
|
memset(wbuffer, 'c', size);
|
||||||
@@ -183,16 +191,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # entry spill test
|
[cases.entry_spill]
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write hi0 200
|
// write hi0 200
|
||||||
|
char path[1024];
|
||||||
|
lfs_size_t size;
|
||||||
sprintf(path, "hi0"); size = 200;
|
sprintf(path, "hi0"); size = 200;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
memset(wbuffer, 'c', size);
|
memset(wbuffer, 'c', size);
|
||||||
@@ -256,16 +268,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # entry push spill test
|
[cases.entry_push_spill]
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write hi0 200
|
// write hi0 200
|
||||||
|
char path[1024];
|
||||||
|
lfs_size_t size;
|
||||||
sprintf(path, "hi0"); size = 200;
|
sprintf(path, "hi0"); size = 200;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
memset(wbuffer, 'c', size);
|
memset(wbuffer, 'c', size);
|
||||||
@@ -345,16 +361,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # entry push spill two test
|
[cases.entry_push_spill_two]
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write hi0 200
|
// write hi0 200
|
||||||
|
char path[1024];
|
||||||
|
lfs_size_t size;
|
||||||
sprintf(path, "hi0"); size = 200;
|
sprintf(path, "hi0"); size = 200;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
memset(wbuffer, 'c', size);
|
memset(wbuffer, 'c', size);
|
||||||
@@ -449,16 +469,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # entry drop test
|
[cases.entry_drop]
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
uint8_t rbuffer[1024];
|
uint8_t rbuffer[1024];
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write hi0 200
|
// write hi0 200
|
||||||
|
char path[1024];
|
||||||
|
lfs_size_t size;
|
||||||
sprintf(path, "hi0"); size = 200;
|
sprintf(path, "hi0"); size = 200;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
memset(wbuffer, 'c', size);
|
memset(wbuffer, 'c', size);
|
||||||
@@ -491,6 +515,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
lfs_remove(&lfs, "hi1") => 0;
|
lfs_remove(&lfs, "hi1") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "hi1", &info) => LFS_ERR_NOENT;
|
lfs_stat(&lfs, "hi1", &info) => LFS_ERR_NOENT;
|
||||||
// read hi0 200
|
// read hi0 200
|
||||||
sprintf(path, "hi0"); size = 200;
|
sprintf(path, "hi0"); size = 200;
|
||||||
@@ -547,15 +572,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # create too big
|
[cases.create_too_big]
|
||||||
code = '''
|
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);
|
memset(path, 'm', 200);
|
||||||
path[200] = '\0';
|
path[200] = '\0';
|
||||||
|
|
||||||
size = 400;
|
lfs_size_t size = 400;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
@@ -572,15 +600,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # resize too big
|
[cases.resize_too_big]
|
||||||
code = '''
|
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);
|
memset(path, 'm', 200);
|
||||||
path[200] = '\0';
|
path[200] = '\0';
|
||||||
|
|
||||||
size = 40;
|
lfs_size_t size = 40;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
uint8_t wbuffer[1024];
|
uint8_t wbuffer[1024];
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
|
|
||||||
# invalid pointer tests (outside of block_count)
|
# invalid pointer tests (outside of block_count)
|
||||||
|
|
||||||
[[case]] # invalid tail-pointer test
|
[cases.invalid_tail_pointer]
|
||||||
define.TAIL_TYPE = ['LFS_TYPE_HARDTAIL', 'LFS_TYPE_SOFTTAIL']
|
defines.TAIL_TYPE = ['LFS_TYPE_HARDTAIL', 'LFS_TYPE_SOFTTAIL']
|
||||||
define.INVALSET = [0x3, 0x1, 0x2]
|
defines.INVALSET = [0x3, 0x1, 0x2]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs
|
// create littlefs
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// change tail-pointer to invalid pointers
|
// change tail-pointer to invalid pointers
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
|
lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
|
||||||
@@ -23,25 +24,27 @@ code = '''
|
|||||||
lfs_deinit(&lfs) => 0;
|
lfs_deinit(&lfs) => 0;
|
||||||
|
|
||||||
// test that mount fails gracefully
|
// test that mount fails gracefully
|
||||||
lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
|
lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # invalid dir pointer test
|
[cases.invalid_dir_pointer]
|
||||||
define.INVALSET = [0x3, 0x1, 0x2]
|
defines.INVALSET = [0x3, 0x1, 0x2]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs
|
// create littlefs
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// make a dir
|
// make a dir
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "dir_here") => 0;
|
lfs_mkdir(&lfs, "dir_here") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// change the dir pointer to be invalid
|
// change the dir pointer to be invalid
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
// make sure id 1 == our directory
|
// make sure id 1 == our directory
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_dir_get(&lfs, &mdir,
|
lfs_dir_get(&lfs, &mdir,
|
||||||
LFS_MKTAG(0x700, 0x3ff, 0),
|
LFS_MKTAG(0x700, 0x3ff, 0),
|
||||||
LFS_MKTAG(LFS_TYPE_NAME, 1, strlen("dir_here")), buffer)
|
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
|
// 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
|
// 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;
|
lfs_stat(&lfs, "dir_here", &info) => 0;
|
||||||
assert(strcmp(info.name, "dir_here") == 0);
|
assert(strcmp(info.name, "dir_here") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "dir_here") => LFS_ERR_CORRUPT;
|
lfs_dir_open(&lfs, &dir, "dir_here") => LFS_ERR_CORRUPT;
|
||||||
lfs_stat(&lfs, "dir_here/file_here", &info) => 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_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_file_open(&lfs, &file, "dir_here/file_here",
|
||||||
LFS_O_RDONLY) => LFS_ERR_CORRUPT;
|
LFS_O_RDONLY) => LFS_ERR_CORRUPT;
|
||||||
lfs_file_open(&lfs, &file, "dir_here/file_here",
|
lfs_file_open(&lfs, &file, "dir_here/file_here",
|
||||||
@@ -72,24 +78,27 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # invalid file pointer test
|
[cases.invalid_file_pointer]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
define.SIZE = [10, 1000, 100000] # faked file size
|
defines.SIZE = [10, 1000, 100000] # faked file size
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs
|
// create littlefs
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// make a file
|
// 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_file_open(&lfs, &file, "file_here",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// change the file pointer to be invalid
|
// change the file pointer to be invalid
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
// make sure id 1 == our file
|
// make sure id 1 == our file
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_dir_get(&lfs, &mdir,
|
lfs_dir_get(&lfs, &mdir,
|
||||||
LFS_MKTAG(0x700, 0x3ff, 0),
|
LFS_MKTAG(0x700, 0x3ff, 0),
|
||||||
LFS_MKTAG(LFS_TYPE_NAME, 1, strlen("file_here")), buffer)
|
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
|
// 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
|
// 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;
|
lfs_stat(&lfs, "file_here", &info) => 0;
|
||||||
assert(strcmp(info.name, "file_here") == 0);
|
assert(strcmp(info.name, "file_here") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -114,20 +124,22 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// any allocs that traverse CTZ must unfortunately must fail
|
// 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_mkdir(&lfs, "dir_here") => LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # invalid pointer in CTZ skip-list test
|
[cases.invalid_ctz_pointer] # invalid pointer in CTZ skip-list test
|
||||||
define.SIZE = ['2*LFS_BLOCK_SIZE', '3*LFS_BLOCK_SIZE', '4*LFS_BLOCK_SIZE']
|
defines.SIZE = ['2*BLOCK_SIZE', '3*BLOCK_SIZE', '4*BLOCK_SIZE']
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs
|
// create littlefs
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// make a file
|
// 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_file_open(&lfs, &file, "file_here",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
for (int i = 0; i < SIZE; i++) {
|
for (int i = 0; i < SIZE; i++) {
|
||||||
@@ -137,10 +149,11 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
// change pointer in CTZ skip-list to be invalid
|
// change pointer in CTZ skip-list to be invalid
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
// make sure id 1 == our file and get our CTZ structure
|
// make sure id 1 == our file and get our CTZ structure
|
||||||
|
uint8_t buffer[4*BLOCK_SIZE];
|
||||||
lfs_dir_get(&lfs, &mdir,
|
lfs_dir_get(&lfs, &mdir,
|
||||||
LFS_MKTAG(0x700, 0x3ff, 0),
|
LFS_MKTAG(0x700, 0x3ff, 0),
|
||||||
LFS_MKTAG(LFS_TYPE_NAME, 1, strlen("file_here")), buffer)
|
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_MKTAG(LFS_TYPE_CTZSTRUCT, 1, sizeof(struct lfs_ctz));
|
||||||
lfs_ctz_fromle32(&ctz);
|
lfs_ctz_fromle32(&ctz);
|
||||||
// rewrite block to contain bad pointer
|
// rewrite block to contain bad pointer
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t bbuffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, ctz.head, 0, bbuffer, BLOCK_SIZE) => 0;
|
||||||
uint32_t bad = lfs_tole32(0xcccccccc);
|
uint32_t bad = lfs_tole32(0xcccccccc);
|
||||||
memcpy(&bbuffer[0], &bad, sizeof(bad));
|
memcpy(&bbuffer[0], &bad, sizeof(bad));
|
||||||
memcpy(&bbuffer[4], &bad, sizeof(bad));
|
memcpy(&bbuffer[4], &bad, sizeof(bad));
|
||||||
cfg.erase(&cfg, ctz.head) => 0;
|
cfg->erase(cfg, ctz.head) => 0;
|
||||||
cfg.prog(&cfg, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, ctz.head, 0, bbuffer, BLOCK_SIZE) => 0;
|
||||||
lfs_deinit(&lfs) => 0;
|
lfs_deinit(&lfs) => 0;
|
||||||
|
|
||||||
// test that accessing our bad file fails, note there's a number
|
// 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
|
// 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;
|
lfs_stat(&lfs, "file_here", &info) => 0;
|
||||||
assert(strcmp(info.name, "file_here") == 0);
|
assert(strcmp(info.name, "file_here") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -175,22 +189,23 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// any allocs that traverse CTZ must unfortunately must fail
|
// 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_mkdir(&lfs, "dir_here") => LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
[[case]] # invalid gstate pointer
|
[cases.invalid_gstate_pointer]
|
||||||
define.INVALSET = [0x3, 0x1, 0x2]
|
defines.INVALSET = [0x3, 0x1, 0x2]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs
|
// create littlefs
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// create an invalid gstate
|
// create an invalid gstate
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
lfs_fs_prepmove(&lfs, 1, (lfs_block_t [2]){
|
lfs_fs_prepmove(&lfs, 1, (lfs_block_t [2]){
|
||||||
@@ -202,21 +217,22 @@ code = '''
|
|||||||
// test that mount fails gracefully
|
// test that mount fails gracefully
|
||||||
// mount may not fail, but our first alloc should fail when
|
// mount may not fail, but our first alloc should fail when
|
||||||
// we try to fix the gstate
|
// 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_mkdir(&lfs, "should_fail") => LFS_ERR_CORRUPT;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# cycle detection/recovery tests
|
# cycle detection/recovery tests
|
||||||
|
|
||||||
[[case]] # metadata-pair threaded-list loop test
|
[cases.mdir_loop] # metadata-pair threaded-list loop test
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs
|
// create littlefs
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// change tail-pointer to point to ourself
|
// change tail-pointer to point to ourself
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
|
lfs_dir_commit(&lfs, &mdir, LFS_MKATTRS(
|
||||||
@@ -225,20 +241,21 @@ code = '''
|
|||||||
lfs_deinit(&lfs) => 0;
|
lfs_deinit(&lfs) => 0;
|
||||||
|
|
||||||
// test that mount fails gracefully
|
// 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.mdir_loop_2] # metadata-pair threaded-list 2-length loop test
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs with child dir
|
// create littlefs with child dir
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "child") => 0;
|
lfs_mkdir(&lfs, "child") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// find child
|
// find child
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_block_t pair[2];
|
lfs_block_t pair[2];
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
@@ -255,20 +272,21 @@ code = '''
|
|||||||
lfs_deinit(&lfs) => 0;
|
lfs_deinit(&lfs) => 0;
|
||||||
|
|
||||||
// test that mount fails gracefully
|
// 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.mdir_loop_child] # metadata-pair threaded-list 1-length child loop test
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
// create littlefs with child dir
|
// create littlefs with child dir
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "child") => 0;
|
lfs_mkdir(&lfs, "child") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// find child
|
// find child
|
||||||
lfs_init(&lfs, &cfg) => 0;
|
lfs_init(&lfs, cfg) => 0;
|
||||||
lfs_mdir_t mdir;
|
lfs_mdir_t mdir;
|
||||||
lfs_block_t pair[2];
|
lfs_block_t pair[2];
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
||||||
@@ -284,5 +302,5 @@ code = '''
|
|||||||
lfs_deinit(&lfs) => 0;
|
lfs_deinit(&lfs) => 0;
|
||||||
|
|
||||||
// test that mount fails gracefully
|
// test that mount fails gracefully
|
||||||
lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
|
lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -1,30 +1,34 @@
|
|||||||
[[case]] # test running a filesystem to exhaustion
|
# test running a filesystem to exhaustion
|
||||||
define.LFS_ERASE_CYCLES = 10
|
[cases.exhaustion]
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.ERASE_CYCLES = 10
|
||||||
define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = [
|
defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
|
||||||
|
defines.BADBLOCK_BEHAVIOR = [
|
||||||
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_READERROR',
|
'LFS_TESTBD_BADBLOCK_READERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
||||||
]
|
]
|
||||||
define.FILES = 10
|
defines.FILES = 10
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "roadrunner") => 0;
|
lfs_mkdir(&lfs, "roadrunner") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
uint32_t cycle = 0;
|
uint32_t cycle = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// chose name, roughly random seed, and random 2^n size
|
// chose name, roughly random seed, and random 2^n size
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
|
|
||||||
@@ -33,14 +37,14 @@ code = '''
|
|||||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||||
assert(res == 1 || res == LFS_ERR_NOSPC);
|
assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||||
if (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);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
goto exhausted;
|
goto exhausted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_file_close(&lfs, &file);
|
int err = lfs_file_close(&lfs, &file);
|
||||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS_ERR_NOSPC) {
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
@@ -50,10 +54,12 @@ code = '''
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
for (lfs_size_t j = 0; j < size; j++) {
|
for (lfs_size_t j = 0; j < size; j++) {
|
||||||
char c = 'a' + (rand() % 26);
|
char c = 'a' + (rand() % 26);
|
||||||
@@ -71,10 +77,12 @@ code = '''
|
|||||||
|
|
||||||
exhausted:
|
exhausted:
|
||||||
// should still be readable
|
// should still be readable
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
@@ -82,31 +90,35 @@ exhausted:
|
|||||||
LFS_WARN("completed %d cycles", cycle);
|
LFS_WARN("completed %d cycles", cycle);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # test running a filesystem to exhaustion
|
# test running a filesystem to exhaustion
|
||||||
# which also requires expanding superblocks
|
# which also requires expanding superblocks
|
||||||
define.LFS_ERASE_CYCLES = 10
|
[cases.exhaustion_superblocks]
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.ERASE_CYCLES = 10
|
||||||
define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.LFS_BADBLOCK_BEHAVIOR = [
|
defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
|
||||||
|
defines.BADBLOCK_BEHAVIOR = [
|
||||||
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
'LFS_TESTBD_BADBLOCK_PROGERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
'LFS_TESTBD_BADBLOCK_ERASEERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_READERROR',
|
'LFS_TESTBD_BADBLOCK_READERROR',
|
||||||
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
'LFS_TESTBD_BADBLOCK_PROGNOOP',
|
||||||
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
'LFS_TESTBD_BADBLOCK_ERASENOOP',
|
||||||
]
|
]
|
||||||
define.FILES = 10
|
defines.FILES = 10
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
uint32_t cycle = 0;
|
uint32_t cycle = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// chose name, roughly random seed, and random 2^n size
|
// chose name, roughly random seed, and random 2^n size
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%d", i);
|
sprintf(path, "test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
|
|
||||||
@@ -115,14 +127,14 @@ code = '''
|
|||||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||||
assert(res == 1 || res == LFS_ERR_NOSPC);
|
assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||||
if (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);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
goto exhausted;
|
goto exhausted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_file_close(&lfs, &file);
|
int err = lfs_file_close(&lfs, &file);
|
||||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS_ERR_NOSPC) {
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
@@ -132,10 +144,12 @@ code = '''
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%d", i);
|
sprintf(path, "test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
for (lfs_size_t j = 0; j < size; j++) {
|
for (lfs_size_t j = 0; j < size; j++) {
|
||||||
char c = 'a' + (rand() % 26);
|
char c = 'a' + (rand() % 26);
|
||||||
@@ -153,9 +167,11 @@ code = '''
|
|||||||
|
|
||||||
exhausted:
|
exhausted:
|
||||||
// should still be readable
|
// should still be readable
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
|
struct lfs_info info;
|
||||||
sprintf(path, "test%d", i);
|
sprintf(path, "test%d", i);
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
}
|
}
|
||||||
@@ -169,35 +185,39 @@ exhausted:
|
|||||||
# into increasing the block devices lifetime. This is something we can actually
|
# into increasing the block devices lifetime. This is something we can actually
|
||||||
# check for.
|
# check for.
|
||||||
|
|
||||||
[[case]] # wear-level test running a filesystem to exhaustion
|
# wear-level test running a filesystem to exhaustion
|
||||||
define.LFS_ERASE_CYCLES = 20
|
[cases.wear_leveling_exhaustion]
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.ERASE_CYCLES = 20
|
||||||
define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.FILES = 10
|
defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
|
||||||
|
defines.FILES = 10
|
||||||
code = '''
|
code = '''
|
||||||
uint32_t run_cycles[2];
|
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 (int run = 0; run < 2; run++) {
|
||||||
for (lfs_block_t b = 0; b < LFS_BLOCK_COUNT; b++) {
|
for (lfs_block_t b = 0; b < BLOCK_COUNT; b++) {
|
||||||
lfs_testbd_setwear(&cfg, b,
|
lfs_testbd_setwear(cfg, b,
|
||||||
(b < run_block_count[run]) ? 0 : LFS_ERASE_CYCLES) => 0;
|
(b < run_block_count[run]) ? 0 : ERASE_CYCLES) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "roadrunner") => 0;
|
lfs_mkdir(&lfs, "roadrunner") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
uint32_t cycle = 0;
|
uint32_t cycle = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// chose name, roughly random seed, and random 2^n size
|
// chose name, roughly random seed, and random 2^n size
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
|
|
||||||
@@ -206,14 +226,14 @@ code = '''
|
|||||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||||
assert(res == 1 || res == LFS_ERR_NOSPC);
|
assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||||
if (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);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
goto exhausted;
|
goto exhausted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_file_close(&lfs, &file);
|
int err = lfs_file_close(&lfs, &file);
|
||||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS_ERR_NOSPC) {
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
@@ -223,10 +243,12 @@ code = '''
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
for (lfs_size_t j = 0; j < size; j++) {
|
for (lfs_size_t j = 0; j < size; j++) {
|
||||||
char c = 'a' + (rand() % 26);
|
char c = 'a' + (rand() % 26);
|
||||||
@@ -244,9 +266,11 @@ code = '''
|
|||||||
|
|
||||||
exhausted:
|
exhausted:
|
||||||
// should still be readable
|
// should still be readable
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
|
struct lfs_info info;
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
}
|
}
|
||||||
@@ -261,32 +285,36 @@ exhausted:
|
|||||||
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
|
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # wear-level test + expanding superblock
|
# wear-level test + expanding superblock
|
||||||
define.LFS_ERASE_CYCLES = 20
|
[cases.wear_leveling_exhaustion_superblocks]
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.ERASE_CYCLES = 20
|
||||||
define.LFS_BLOCK_CYCLES = 'LFS_ERASE_CYCLES / 2'
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.FILES = 10
|
defines.BLOCK_CYCLES = 'ERASE_CYCLES / 2'
|
||||||
|
defines.FILES = 10
|
||||||
code = '''
|
code = '''
|
||||||
uint32_t run_cycles[2];
|
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 (int run = 0; run < 2; run++) {
|
||||||
for (lfs_block_t b = 0; b < LFS_BLOCK_COUNT; b++) {
|
for (lfs_block_t b = 0; b < BLOCK_COUNT; b++) {
|
||||||
lfs_testbd_setwear(&cfg, b,
|
lfs_testbd_setwear(cfg, b,
|
||||||
(b < run_block_count[run]) ? 0 : LFS_ERASE_CYCLES) => 0;
|
(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;
|
uint32_t cycle = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// chose name, roughly random seed, and random 2^n size
|
// chose name, roughly random seed, and random 2^n size
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%d", i);
|
sprintf(path, "test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
|
|
||||||
@@ -295,14 +323,14 @@ code = '''
|
|||||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||||
assert(res == 1 || res == LFS_ERR_NOSPC);
|
assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||||
if (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);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
goto exhausted;
|
goto exhausted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_file_close(&lfs, &file);
|
int err = lfs_file_close(&lfs, &file);
|
||||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS_ERR_NOSPC) {
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
@@ -312,10 +340,12 @@ code = '''
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "test%d", i);
|
sprintf(path, "test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << ((rand() % 10)+2);
|
lfs_size_t size = 1 << ((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
for (lfs_size_t j = 0; j < size; j++) {
|
for (lfs_size_t j = 0; j < size; j++) {
|
||||||
char c = 'a' + (rand() % 26);
|
char c = 'a' + (rand() % 26);
|
||||||
@@ -333,9 +363,11 @@ code = '''
|
|||||||
|
|
||||||
exhausted:
|
exhausted:
|
||||||
// should still be readable
|
// should still be readable
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
|
struct lfs_info info;
|
||||||
sprintf(path, "test%d", i);
|
sprintf(path, "test%d", i);
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
}
|
}
|
||||||
@@ -350,28 +382,32 @@ exhausted:
|
|||||||
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
|
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # test that we wear blocks roughly evenly
|
# test that we wear blocks roughly evenly
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
[cases.wear_leveling_distribution]
|
||||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
define.LFS_BLOCK_CYCLES = [5, 4, 3, 2, 1]
|
defines.BLOCK_COUNT = 256 # small bd so test runs faster
|
||||||
define.CYCLES = 100
|
defines.BLOCK_CYCLES = [5, 4, 3, 2, 1]
|
||||||
define.FILES = 10
|
defines.CYCLES = 100
|
||||||
if = 'LFS_BLOCK_CYCLES < CYCLES/10'
|
defines.FILES = 10
|
||||||
|
if = 'BLOCK_CYCLES < CYCLES/10'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "roadrunner") => 0;
|
lfs_mkdir(&lfs, "roadrunner") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
uint32_t cycle = 0;
|
uint32_t cycle = 0;
|
||||||
while (cycle < CYCLES) {
|
while (cycle < CYCLES) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// chose name, roughly random seed, and random 2^n size
|
// chose name, roughly random seed, and random 2^n size
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << 4; //((rand() % 10)+2);
|
lfs_size_t size = 1 << 4; //((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
|
|
||||||
@@ -380,14 +416,14 @@ code = '''
|
|||||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||||
assert(res == 1 || res == LFS_ERR_NOSPC);
|
assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||||
if (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);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
goto exhausted;
|
goto exhausted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_file_close(&lfs, &file);
|
int err = lfs_file_close(&lfs, &file);
|
||||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS_ERR_NOSPC) {
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
@@ -397,10 +433,12 @@ code = '''
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
srand(cycle * i);
|
srand(cycle * i);
|
||||||
size = 1 << 4; //((rand() % 10)+2);
|
lfs_size_t size = 1 << 4; //((rand() % 10)+2);
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
for (lfs_size_t j = 0; j < size; j++) {
|
for (lfs_size_t j = 0; j < size; j++) {
|
||||||
char c = 'a' + (rand() % 26);
|
char c = 'a' + (rand() % 26);
|
||||||
@@ -418,9 +456,11 @@ code = '''
|
|||||||
|
|
||||||
exhausted:
|
exhausted:
|
||||||
// should still be readable
|
// should still be readable
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (uint32_t i = 0; i < FILES; i++) {
|
for (uint32_t i = 0; i < FILES; i++) {
|
||||||
// check for errors
|
// check for errors
|
||||||
|
char path[1024];
|
||||||
|
struct lfs_info info;
|
||||||
sprintf(path, "roadrunner/test%d", i);
|
sprintf(path, "roadrunner/test%d", i);
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
}
|
}
|
||||||
@@ -433,8 +473,8 @@ exhausted:
|
|||||||
lfs_testbd_wear_t totalwear = 0;
|
lfs_testbd_wear_t totalwear = 0;
|
||||||
lfs_testbd_wear_t maxwear = 0;
|
lfs_testbd_wear_t maxwear = 0;
|
||||||
// skip 0 and 1 as superblock movement is intentionally avoided
|
// skip 0 and 1 as superblock movement is intentionally avoided
|
||||||
for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
|
for (lfs_block_t b = 2; b < BLOCK_COUNT; b++) {
|
||||||
lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
|
lfs_testbd_wear_t wear = lfs_testbd_getwear(cfg, b);
|
||||||
printf("%08x: wear %d\n", b, wear);
|
printf("%08x: wear %d\n", b, wear);
|
||||||
assert(wear >= 0);
|
assert(wear >= 0);
|
||||||
if (wear < minwear) {
|
if (wear < minwear) {
|
||||||
@@ -445,15 +485,15 @@ exhausted:
|
|||||||
}
|
}
|
||||||
totalwear += wear;
|
totalwear += wear;
|
||||||
}
|
}
|
||||||
lfs_testbd_wear_t avgwear = totalwear / LFS_BLOCK_COUNT;
|
lfs_testbd_wear_t avgwear = totalwear / BLOCK_COUNT;
|
||||||
LFS_WARN("max wear: %d cycles", maxwear);
|
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);
|
LFS_WARN("min wear: %d cycles", minwear);
|
||||||
|
|
||||||
// find standard deviation^2
|
// find standard deviation^2
|
||||||
lfs_testbd_wear_t dev2 = 0;
|
lfs_testbd_wear_t dev2 = 0;
|
||||||
for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
|
for (lfs_block_t b = 2; b < BLOCK_COUNT; b++) {
|
||||||
lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
|
lfs_testbd_wear_t wear = lfs_testbd_getwear(cfg, b);
|
||||||
assert(wear >= 0);
|
assert(wear >= 0);
|
||||||
lfs_testbd_swear_t diff = wear - avgwear;
|
lfs_testbd_swear_t diff = wear - avgwear;
|
||||||
dev2 += diff*diff;
|
dev2 += diff*diff;
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
|
|
||||||
[[case]] # simple file test
|
[cases.simple_file]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "hello",
|
lfs_file_open(&lfs, &file, "hello",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
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!");
|
strcpy((char*)buffer, "Hello World!");
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
assert(strcmp((char*)buffer, "Hello World!") == 0);
|
assert(strcmp((char*)buffer, "Hello World!") == 0);
|
||||||
@@ -19,17 +22,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # larger files
|
[cases.large_files]
|
||||||
define.SIZE = [32, 8192, 262144, 0, 7, 8193]
|
defines.SIZE = [32, 8192, 262144, 0, 7, 8193]
|
||||||
define.CHUNKSIZE = [31, 16, 33, 1, 1023]
|
defines.CHUNKSIZE = [31, 16, 33, 1, 1023]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write
|
// write
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "avacado",
|
lfs_file_open(&lfs, &file, "avacado",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
srand(1);
|
srand(1);
|
||||||
|
uint8_t buffer[1024];
|
||||||
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
|
for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) {
|
||||||
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
|
lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i);
|
||||||
for (lfs_size_t b = 0; b < chunk; b++) {
|
for (lfs_size_t b = 0; b < chunk; b++) {
|
||||||
@@ -41,7 +47,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => SIZE;
|
lfs_file_size(&lfs, &file) => SIZE;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -57,15 +63,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # rewriting files
|
[cases.rewriting_files]
|
||||||
define.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
|
defines.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
|
||||||
define.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
|
defines.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
|
||||||
define.CHUNKSIZE = [31, 16, 1]
|
defines.CHUNKSIZE = [31, 16, 1]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write
|
// write
|
||||||
lfs_mount(&lfs, &cfg) => 1;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_open(&lfs, &file, "avacado",
|
lfs_file_open(&lfs, &file, "avacado",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -80,7 +89,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => SIZE1;
|
lfs_file_size(&lfs, &file) => SIZE1;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -96,7 +105,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// rewrite
|
// rewrite
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY) => 0;
|
||||||
srand(2);
|
srand(2);
|
||||||
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
|
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
|
||||||
@@ -110,7 +119,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => lfs_max(SIZE1, SIZE2);
|
lfs_file_size(&lfs, &file) => lfs_max(SIZE1, SIZE2);
|
||||||
srand(2);
|
srand(2);
|
||||||
@@ -139,15 +148,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # appending files
|
[cases.appending_files]
|
||||||
define.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
|
defines.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
|
||||||
define.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
|
defines.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
|
||||||
define.CHUNKSIZE = [31, 16, 1]
|
defines.CHUNKSIZE = [31, 16, 1]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write
|
// 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_file_open(&lfs, &file, "avacado",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -162,7 +174,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => SIZE1;
|
lfs_file_size(&lfs, &file) => SIZE1;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -178,7 +190,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// append
|
// append
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_APPEND) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_APPEND) => 0;
|
||||||
srand(2);
|
srand(2);
|
||||||
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
|
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
|
||||||
@@ -192,7 +204,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => SIZE1 + SIZE2;
|
lfs_file_size(&lfs, &file) => SIZE1 + SIZE2;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -216,15 +228,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # truncating files
|
[cases.truncating_files]
|
||||||
define.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
|
defines.SIZE1 = [32, 8192, 131072, 0, 7, 8193]
|
||||||
define.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
|
defines.SIZE2 = [32, 8192, 131072, 0, 7, 8193]
|
||||||
define.CHUNKSIZE = [31, 16, 1]
|
defines.CHUNKSIZE = [31, 16, 1]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// write
|
// 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_file_open(&lfs, &file, "avacado",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -239,7 +254,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => SIZE1;
|
lfs_file_size(&lfs, &file) => SIZE1;
|
||||||
srand(1);
|
srand(1);
|
||||||
@@ -255,7 +270,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// truncate
|
// truncate
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
||||||
srand(2);
|
srand(2);
|
||||||
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
|
for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) {
|
||||||
@@ -269,7 +284,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => SIZE2;
|
lfs_file_size(&lfs, &file) => SIZE2;
|
||||||
srand(2);
|
srand(2);
|
||||||
@@ -285,22 +300,25 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant file writing
|
[cases.reentrant_file_writing]
|
||||||
define.SIZE = [32, 0, 7, 2049]
|
defines.SIZE = [32, 0, 7, 2049]
|
||||||
define.CHUNKSIZE = [31, 16, 65]
|
defines.CHUNKSIZE = [31, 16, 65]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&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);
|
err = lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY);
|
||||||
assert(err == LFS_ERR_NOENT || err == 0);
|
assert(err == LFS_ERR_NOENT || err == 0);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
// can only be 0 (new file) or full size
|
// 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);
|
assert(size == 0 || size == SIZE);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
@@ -333,8 +351,8 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant file writing with syncs
|
[cases.reentrant_file_writing_sync]
|
||||||
define = [
|
defines = [
|
||||||
# append (O(n))
|
# append (O(n))
|
||||||
{MODE='LFS_O_APPEND', SIZE=[32, 0, 7, 2049], CHUNKSIZE=[31, 16, 65]},
|
{MODE='LFS_O_APPEND', SIZE=[32, 0, 7, 2049], CHUNKSIZE=[31, 16, 65]},
|
||||||
# truncate (O(n^2))
|
# truncate (O(n^2))
|
||||||
@@ -344,17 +362,20 @@ define = [
|
|||||||
]
|
]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&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);
|
err = lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY);
|
||||||
assert(err == LFS_ERR_NOENT || err == 0);
|
assert(err == LFS_ERR_NOENT || err == 0);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
// with syncs we could be any size, but it at least must be valid data
|
// 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);
|
assert(size <= SIZE);
|
||||||
srand(1);
|
srand(1);
|
||||||
for (lfs_size_t i = 0; i < size; i += CHUNKSIZE) {
|
for (lfs_size_t i = 0; i < size; i += CHUNKSIZE) {
|
||||||
@@ -370,7 +391,7 @@ code = '''
|
|||||||
// write
|
// write
|
||||||
lfs_file_open(&lfs, &file, "avacado",
|
lfs_file_open(&lfs, &file, "avacado",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | MODE) => 0;
|
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);
|
assert(size <= SIZE);
|
||||||
srand(1);
|
srand(1);
|
||||||
lfs_size_t skip = (MODE == LFS_O_APPEND) ? size : 0;
|
lfs_size_t skip = (MODE == LFS_O_APPEND) ? size : 0;
|
||||||
@@ -403,19 +424,22 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # many files
|
[cases.many_files]
|
||||||
define.N = 300
|
defines.N = 300
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// create N files of 7 bytes
|
// create N files of 7 bytes
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
lfs_file_t file;
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "file_%03d", i);
|
sprintf(path, "file_%03d", i);
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
char wbuffer[1024];
|
char wbuffer[1024];
|
||||||
size = 7;
|
lfs_size_t size = 7;
|
||||||
snprintf(wbuffer, size, "Hi %03d", i);
|
sprintf(wbuffer, "Hi %03d", i);
|
||||||
lfs_file_write(&lfs, &file, wbuffer, size) => size;
|
lfs_file_write(&lfs, &file, wbuffer, size) => size;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
@@ -428,25 +452,28 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # many files with power cycle
|
[cases.many_files_power_cycle]
|
||||||
define.N = 300
|
defines.N = 300
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// create N files of 7 bytes
|
// create N files of 7 bytes
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
lfs_file_t file;
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "file_%03d", i);
|
sprintf(path, "file_%03d", i);
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
char wbuffer[1024];
|
char wbuffer[1024];
|
||||||
size = 7;
|
lfs_size_t size = 7;
|
||||||
snprintf(wbuffer, size, "Hi %03d", i);
|
sprintf(wbuffer, "Hi %03d", i);
|
||||||
lfs_file_write(&lfs, &file, wbuffer, size) => size;
|
lfs_file_write(&lfs, &file, wbuffer, size) => size;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
char rbuffer[1024];
|
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_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
||||||
assert(strcmp(rbuffer, wbuffer) == 0);
|
assert(strcmp(rbuffer, wbuffer) == 0);
|
||||||
@@ -455,22 +482,25 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # many files with power loss
|
[cases.many_files_power_loss]
|
||||||
define.N = 300
|
defines.N = 300
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
// create N files of 7 bytes
|
// create N files of 7 bytes
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
lfs_file_t file;
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "file_%03d", i);
|
sprintf(path, "file_%03d", i);
|
||||||
err = lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT);
|
err = lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT);
|
||||||
char wbuffer[1024];
|
char wbuffer[1024];
|
||||||
size = 7;
|
lfs_size_t size = 7;
|
||||||
snprintf(wbuffer, size, "Hi %03d", i);
|
sprintf(wbuffer, "Hi %03d", i);
|
||||||
if ((lfs_size_t)lfs_file_size(&lfs, &file) != size) {
|
if ((lfs_size_t)lfs_file_size(&lfs, &file) != size) {
|
||||||
lfs_file_write(&lfs, &file, wbuffer, size) => size;
|
lfs_file_write(&lfs, &file, wbuffer, size) => size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
|
|
||||||
[[case]] # interspersed file test
|
[cases.interspersed_files]
|
||||||
define.SIZE = [10, 100]
|
defines.SIZE = [10, 100]
|
||||||
define.FILES = [4, 10, 26]
|
defines.FILES = [4, 10, 26]
|
||||||
code = '''
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
lfs_file_t files[FILES];
|
lfs_file_t files[FILES];
|
||||||
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
|
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_file_open(&lfs, &files[j], path,
|
lfs_file_open(&lfs, &files[j], path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
@@ -23,7 +25,9 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[j]);
|
lfs_file_close(&lfs, &files[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -31,6 +35,7 @@ code = '''
|
|||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, path) == 0);
|
assert(strcmp(info.name, path) == 0);
|
||||||
@@ -41,12 +46,14 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_file_open(&lfs, &files[j], path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &files[j], path, LFS_O_RDONLY) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &files[j], buffer, 1) => 1;
|
lfs_file_read(&lfs, &files[j], buffer, 1) => 1;
|
||||||
assert(buffer[0] == alphas[j]);
|
assert(buffer[0] == alphas[j]);
|
||||||
}
|
}
|
||||||
@@ -59,15 +66,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # interspersed remove file test
|
[cases.interspersed_remove_files]
|
||||||
define.SIZE = [10, 100]
|
defines.SIZE = [10, 100]
|
||||||
define.FILES = [4, 10, 26]
|
defines.FILES = [4, 10, 26]
|
||||||
code = '''
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
|
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
for (int i = 0; i < SIZE; i++) {
|
for (int i = 0; i < SIZE; i++) {
|
||||||
@@ -77,18 +87,22 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
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;
|
lfs_file_open(&lfs, &file, "zzz", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
lfs_file_write(&lfs, &file, (const void*)"~", 1) => 1;
|
lfs_file_write(&lfs, &file, (const void*)"~", 1) => 1;
|
||||||
lfs_file_sync(&lfs, &file) => 0;
|
lfs_file_sync(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_file_close(&lfs, &file);
|
lfs_file_close(&lfs, &file);
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -104,6 +118,7 @@ code = '''
|
|||||||
|
|
||||||
lfs_file_open(&lfs, &file, "zzz", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "zzz", LFS_O_RDONLY) => 0;
|
||||||
for (int i = 0; i < FILES; i++) {
|
for (int i = 0; i < FILES; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 1) => 1;
|
lfs_file_read(&lfs, &file, buffer, 1) => 1;
|
||||||
assert(buffer[0] == '~');
|
assert(buffer[0] == '~');
|
||||||
}
|
}
|
||||||
@@ -112,11 +127,12 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # remove inconveniently test
|
[cases.remove_inconveniently]
|
||||||
define.SIZE = [10, 100]
|
defines.SIZE = [10, 100]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_file_t files[3];
|
lfs_file_t files[3];
|
||||||
lfs_file_open(&lfs, &files[0], "e", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
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;
|
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[1]);
|
||||||
lfs_file_close(&lfs, &files[2]);
|
lfs_file_close(&lfs, &files[2]);
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
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[0], "e", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_open(&lfs, &files[1], "g", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &files[1], "g", LFS_O_RDONLY) => 0;
|
||||||
for (int i = 0; i < SIZE; i++) {
|
for (int i = 0; i < SIZE; i++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &files[0], buffer, 1) => 1;
|
lfs_file_read(&lfs, &files[0], buffer, 1) => 1;
|
||||||
assert(buffer[0] == 'e');
|
assert(buffer[0] == 'e');
|
||||||
lfs_file_read(&lfs, &files[1], buffer, 1) => 1;
|
lfs_file_read(&lfs, &files[1], buffer, 1) => 1;
|
||||||
@@ -172,21 +191,23 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant interspersed file test
|
[cases.reentrant_interspersed_files]
|
||||||
define.SIZE = [10, 100]
|
defines.SIZE = [10, 100]
|
||||||
define.FILES = [4, 10, 26]
|
defines.FILES = [4, 10, 26]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
lfs_file_t files[FILES];
|
lfs_file_t files[FILES];
|
||||||
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
|
const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
err = lfs_mount(&lfs, &cfg);
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_file_open(&lfs, &files[j], path,
|
lfs_file_open(&lfs, &files[j], path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
||||||
@@ -194,8 +215,8 @@ code = '''
|
|||||||
|
|
||||||
for (int i = 0; i < SIZE; i++) {
|
for (int i = 0; i < SIZE; i++) {
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
size = lfs_file_size(&lfs, &files[j]);
|
lfs_ssize_t size = lfs_file_size(&lfs, &files[j]);
|
||||||
assert((int)size >= 0);
|
assert(size >= 0);
|
||||||
if ((int)size <= i) {
|
if ((int)size <= i) {
|
||||||
lfs_file_write(&lfs, &files[j], &alphas[j], 1) => 1;
|
lfs_file_write(&lfs, &files[j], &alphas[j], 1) => 1;
|
||||||
lfs_file_sync(&lfs, &files[j]) => 0;
|
lfs_file_sync(&lfs, &files[j]) => 0;
|
||||||
@@ -207,7 +228,9 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[j]);
|
lfs_file_close(&lfs, &files[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -215,6 +238,7 @@ code = '''
|
|||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, path) == 0);
|
assert(strcmp(info.name, path) == 0);
|
||||||
@@ -225,12 +249,14 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "%c", alphas[j]);
|
sprintf(path, "%c", alphas[j]);
|
||||||
lfs_file_open(&lfs, &files[j], path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &files[j], path, LFS_O_RDONLY) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
for (int j = 0; j < FILES; j++) {
|
for (int j = 0; j < FILES; j++) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &files[j], buffer, 1) => 1;
|
lfs_file_read(&lfs, &files[j], buffer, 1) => 1;
|
||||||
assert(buffer[0] == alphas[j]);
|
assert(buffer[0] == alphas[j]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
[[case]] # move file
|
[cases.move_file]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
lfs_mkdir(&lfs, "d") => 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_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, "hola\n", 5) => 5;
|
||||||
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
||||||
@@ -13,11 +15,13 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
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, "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, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||||
lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 5) => 5;
|
lfs_file_read(&lfs, &file, buffer, 5) => 5;
|
||||||
memcmp(buffer, "hola\n", 5) => 0;
|
memcmp(buffer, "hola\n", 5) => 0;
|
||||||
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
||||||
@@ -55,31 +60,35 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # noop move, yes this is legal
|
[cases.nop_move] # yes this is legal
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "hi") => 0;
|
lfs_mkdir(&lfs, "hi") => 0;
|
||||||
lfs_rename(&lfs, "hi", "hi") => 0;
|
lfs_rename(&lfs, "hi", "hi") => 0;
|
||||||
lfs_mkdir(&lfs, "hi/hi") => 0;
|
lfs_mkdir(&lfs, "hi/hi") => 0;
|
||||||
lfs_rename(&lfs, "hi/hi", "hi/hi") => 0;
|
lfs_rename(&lfs, "hi/hi", "hi/hi") => 0;
|
||||||
lfs_mkdir(&lfs, "hi/hi/hi") => 0;
|
lfs_mkdir(&lfs, "hi/hi/hi") => 0;
|
||||||
lfs_rename(&lfs, "hi/hi/hi", "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;
|
lfs_stat(&lfs, "hi/hi/hi", &info) => 0;
|
||||||
assert(strcmp(info.name, "hi") == 0);
|
assert(strcmp(info.name, "hi") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move file corrupt source
|
[cases.move_file_corrupt_source]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
lfs_mkdir(&lfs, "d") => 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_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, "hola\n", 5) => 5;
|
||||||
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
||||||
@@ -87,28 +96,30 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// corrupt the source
|
// 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_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "a") => 0;
|
lfs_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -146,16 +157,19 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move file corrupt source and dest
|
# move file corrupt source and dest
|
||||||
|
[cases.move_file_corrupt_source_dest]
|
||||||
in = "lfs.c"
|
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 = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
lfs_mkdir(&lfs, "d") => 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_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, "hola\n", 5) => 5;
|
||||||
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
||||||
@@ -163,44 +177,46 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// corrupt the source
|
// 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_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
// corrupt the destination
|
// corrupt the destination
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "c") => 0;
|
lfs_dir_open(&lfs, &dir, "c") => 0;
|
||||||
block = dir.m.pair[0];
|
block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
off = LFS_BLOCK_SIZE-1;
|
off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "a") => 0;
|
lfs_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -238,16 +254,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move file after corrupt
|
[cases.move_file_after_corrupt]
|
||||||
in = "lfs.c"
|
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 = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
lfs_mkdir(&lfs, "d") => 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_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, "hola\n", 5) => 5;
|
||||||
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
||||||
@@ -255,49 +273,51 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// corrupt the source
|
// 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_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
// corrupt the destination
|
// corrupt the destination
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "c") => 0;
|
lfs_dir_open(&lfs, &dir, "c") => 0;
|
||||||
block = dir.m.pair[0];
|
block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
off = LFS_BLOCK_SIZE-1;
|
off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
// continue move
|
// continue move
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "a") => 0;
|
lfs_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -335,13 +355,14 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # simple reentrant move file
|
[cases.reentrant_move_file]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
err = lfs_mkdir(&lfs, "a");
|
err = lfs_mkdir(&lfs, "a");
|
||||||
assert(!err || err == LFS_ERR_EXIST);
|
assert(!err || err == LFS_ERR_EXIST);
|
||||||
@@ -354,9 +375,10 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
// there should never exist _2_ hello files
|
// there should never exist _2_ hello files
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
struct lfs_info info;
|
||||||
if (lfs_stat(&lfs, "a/hello", &info) == 0) {
|
if (lfs_stat(&lfs, "a/hello", &info) == 0) {
|
||||||
assert(strcmp(info.name, "hello") == 0);
|
assert(strcmp(info.name, "hello") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -384,7 +406,7 @@ code = '''
|
|||||||
assert(count <= 1);
|
assert(count <= 1);
|
||||||
lfs_unmount(&lfs) => 0;
|
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) {
|
if (lfs_stat(&lfs, "a/hello", &info) == 0 && info.size > 0) {
|
||||||
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
|
||||||
} else if (lfs_stat(&lfs, "b/hello", &info) == 0) {
|
} else if (lfs_stat(&lfs, "b/hello", &info) == 0) {
|
||||||
@@ -397,6 +419,7 @@ code = '''
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// create file
|
// create file
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "a/hello",
|
lfs_file_open(&lfs, &file, "a/hello",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
|
lfs_file_write(&lfs, &file, "hola\n", 5) => 5;
|
||||||
@@ -407,7 +430,9 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 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_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -431,10 +456,12 @@ code = '''
|
|||||||
lfs_dir_read(&lfs, &dir, &info) => 0;
|
lfs_dir_read(&lfs, &dir, &info) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 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, "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, "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, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||||
lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 5) => 5;
|
lfs_file_read(&lfs, &file, buffer, 5) => 5;
|
||||||
memcmp(buffer, "hola\n", 5) => 0;
|
memcmp(buffer, "hola\n", 5) => 0;
|
||||||
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
||||||
@@ -445,10 +472,11 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move dir
|
[cases.move_dir]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
@@ -459,11 +487,13 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -510,11 +540,12 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move dir corrupt source
|
[cases.move_dir_corrupt_source]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
@@ -525,28 +556,30 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// corrupt the source
|
// 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_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "a") => 0;
|
lfs_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -593,12 +626,13 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move dir corrupt source and dest
|
[cases.move_dir_corrupt_source_dest]
|
||||||
in = "lfs.c"
|
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 = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
@@ -609,44 +643,46 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// corrupt the source
|
// 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_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
// corrupt the destination
|
// corrupt the destination
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "c") => 0;
|
lfs_dir_open(&lfs, &dir, "c") => 0;
|
||||||
block = dir.m.pair[0];
|
block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
off = LFS_BLOCK_SIZE-1;
|
off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "a") => 0;
|
lfs_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -693,12 +729,13 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move dir after corrupt
|
[cases.move_dir_after_corrupt]
|
||||||
in = "lfs.c"
|
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 = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
@@ -709,49 +746,51 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// corrupt the source
|
// 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_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
// corrupt the destination
|
// corrupt the destination
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "c") => 0;
|
lfs_dir_open(&lfs, &dir, "c") => 0;
|
||||||
block = dir.m.pair[0];
|
block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
off = LFS_BLOCK_SIZE-1;
|
off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 0;
|
cfg->sync(cfg) => 0;
|
||||||
|
|
||||||
// continue move
|
// continue move
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
lfs_rename(&lfs, "a/hi", "c/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir, "a") => 0;
|
lfs_dir_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -798,13 +837,14 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # simple reentrant move dir
|
[cases.reentrant_move_dir]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
err = lfs_mkdir(&lfs, "a");
|
err = lfs_mkdir(&lfs, "a");
|
||||||
assert(!err || err == LFS_ERR_EXIST);
|
assert(!err || err == LFS_ERR_EXIST);
|
||||||
@@ -817,9 +857,10 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
// there should never exist _2_ hi directories
|
// there should never exist _2_ hi directories
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
struct lfs_info info;
|
||||||
if (lfs_stat(&lfs, "a/hi", &info) == 0) {
|
if (lfs_stat(&lfs, "a/hi", &info) == 0) {
|
||||||
assert(strcmp(info.name, "hi") == 0);
|
assert(strcmp(info.name, "hi") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -843,7 +884,7 @@ code = '''
|
|||||||
assert(count <= 1);
|
assert(count <= 1);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
if (lfs_stat(&lfs, "a/hi", &info) == 0) {
|
if (lfs_stat(&lfs, "a/hi", &info) == 0) {
|
||||||
lfs_rename(&lfs, "a/hi", "b/hi") => 0;
|
lfs_rename(&lfs, "a/hi", "b/hi") => 0;
|
||||||
} else if (lfs_stat(&lfs, "b/hi", &info) == 0) {
|
} else if (lfs_stat(&lfs, "b/hi", &info) == 0) {
|
||||||
@@ -868,7 +909,9 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 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_open(&lfs, &dir, "a") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -915,14 +958,16 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move state stealing
|
[cases.move_state_stealing]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "a") => 0;
|
lfs_mkdir(&lfs, "a") => 0;
|
||||||
lfs_mkdir(&lfs, "b") => 0;
|
lfs_mkdir(&lfs, "b") => 0;
|
||||||
lfs_mkdir(&lfs, "c") => 0;
|
lfs_mkdir(&lfs, "c") => 0;
|
||||||
lfs_mkdir(&lfs, "d") => 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_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, "hola\n", 5) => 5;
|
||||||
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8;
|
||||||
@@ -930,21 +975,22 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
|
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "b/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "b/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_rename(&lfs, "c/hello", "d/hello") => 0;
|
lfs_rename(&lfs, "c/hello", "d/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 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, "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, "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, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||||
lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 5) => 5;
|
lfs_file_read(&lfs, &file, buffer, 5) => 5;
|
||||||
memcmp(buffer, "hola\n", 5) => 0;
|
memcmp(buffer, "hola\n", 5) => 0;
|
||||||
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
||||||
@@ -954,12 +1000,13 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_remove(&lfs, "b") => 0;
|
lfs_remove(&lfs, "b") => 0;
|
||||||
lfs_remove(&lfs, "c") => 0;
|
lfs_remove(&lfs, "c") => 0;
|
||||||
lfs_unmount(&lfs) => 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, "a", &info) => 0;
|
||||||
lfs_stat(&lfs, "b", &info) => LFS_ERR_NOENT;
|
lfs_stat(&lfs, "b", &info) => LFS_ERR_NOENT;
|
||||||
lfs_stat(&lfs, "c", &info) => LFS_ERR_NOENT;
|
lfs_stat(&lfs, "c", &info) => LFS_ERR_NOENT;
|
||||||
@@ -979,12 +1026,16 @@ code = '''
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# Other specific corner cases
|
# Other specific corner cases
|
||||||
[[case]] # create + delete in same commit with neighbors
|
|
||||||
|
# create + delete in same commit with neighbors
|
||||||
|
[cases.create_delete_same]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// littlefs keeps files sorted, so we know the order these will be in
|
// 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_file_open(&lfs, &file, "/1.move_me",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1024,6 +1075,8 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[2]) => 0;
|
lfs_file_close(&lfs, &files[2]) => 0;
|
||||||
|
|
||||||
// check that nothing was corrupted
|
// check that nothing was corrupted
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -1051,6 +1104,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
||||||
assert(strcmp((char*)buffer, "test.4") == 0);
|
assert(strcmp((char*)buffer, "test.4") == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1124,13 +1178,15 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Other specific corner cases
|
# create + delete + delete in same commit with neighbors
|
||||||
[[case]] # create + delete + delete in same commit with neighbors
|
[cases.create_delete_delete_same]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// littlefs keeps files sorted, so we know the order these will be in
|
// 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_file_open(&lfs, &file, "/1.move_me",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1175,6 +1231,8 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[2]) => 0;
|
lfs_file_close(&lfs, &files[2]) => 0;
|
||||||
|
|
||||||
// check that nothing was corrupted
|
// check that nothing was corrupted
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -1202,6 +1260,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
||||||
assert(strcmp((char*)buffer, "test.4") == 0);
|
assert(strcmp((char*)buffer, "test.4") == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1281,14 +1340,17 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # create + delete in different dirs with neighbors
|
# create + delete in different dirs with neighbors
|
||||||
|
[cases.create_delete_different]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
// littlefs keeps files sorted, so we know the order these will be in
|
// littlefs keeps files sorted, so we know the order these will be in
|
||||||
lfs_mkdir(&lfs, "/dir.1") => 0;
|
lfs_mkdir(&lfs, "/dir.1") => 0;
|
||||||
lfs_mkdir(&lfs, "/dir.2") => 0;
|
lfs_mkdir(&lfs, "/dir.2") => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "/dir.1/1.move_me",
|
lfs_file_open(&lfs, &file, "/dir.1/1.move_me",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1340,6 +1402,8 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[3]) => 0;
|
lfs_file_close(&lfs, &files[3]) => 0;
|
||||||
|
|
||||||
// check that nothing was corrupted
|
// check that nothing was corrupted
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -1397,6 +1461,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "/dir.1/0.before", LFS_O_RDONLY) => 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;
|
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
||||||
assert(strcmp((char*)buffer, "test.5") == 0);
|
assert(strcmp((char*)buffer, "test.5") == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1518,17 +1583,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move fix in relocation
|
# move fix in relocation
|
||||||
|
[cases.move_fix_relocation]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
define.RELOCATIONS = 'range(0x3+1)'
|
defines.RELOCATIONS = [0x0, 0x1, 0x2, 0x3]
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
lfs_mkdir(&lfs, "/parent") => 0;
|
lfs_mkdir(&lfs, "/parent") => 0;
|
||||||
lfs_mkdir(&lfs, "/parent/child") => 0;
|
lfs_mkdir(&lfs, "/parent/child") => 0;
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "/parent/1.move_me",
|
lfs_file_open(&lfs, &file, "/parent/1.move_me",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "move me",
|
lfs_file_write(&lfs, &file, "move me",
|
||||||
@@ -1568,15 +1636,17 @@ code = '''
|
|||||||
|
|
||||||
// force specific directories to relocate
|
// force specific directories to relocate
|
||||||
if (RELOCATIONS & 0x1) {
|
if (RELOCATIONS & 0x1) {
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent");
|
lfs_dir_open(&lfs, &dir, "/parent");
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
}
|
}
|
||||||
if (RELOCATIONS & 0x2) {
|
if (RELOCATIONS & 0x2) {
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent/child");
|
lfs_dir_open(&lfs, &dir, "/parent/child");
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1593,6 +1663,8 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[3]) => 0;
|
lfs_file_close(&lfs, &files[3]) => 0;
|
||||||
|
|
||||||
// check that nothing was corrupted
|
// check that nothing was corrupted
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent") => 0;
|
lfs_dir_open(&lfs, &dir, "/parent") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -1637,6 +1709,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "/parent/0.before", LFS_O_RDONLY) => 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;
|
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
||||||
assert(strcmp((char*)buffer, "test.5") == 0);
|
assert(strcmp((char*)buffer, "test.5") == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -1655,18 +1728,21 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # move fix in relocation with predecessor
|
# move fix in relocation with predecessor
|
||||||
|
[cases.move_fix_relocation_predecessor]
|
||||||
in = "lfs.c"
|
in = "lfs.c"
|
||||||
define.RELOCATIONS = 'range(0x7+1)'
|
defines.RELOCATIONS = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7]
|
||||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
defines.ERASE_CYCLES = 0xffffffff
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
lfs_mkdir(&lfs, "/parent") => 0;
|
lfs_mkdir(&lfs, "/parent") => 0;
|
||||||
lfs_mkdir(&lfs, "/parent/child") => 0;
|
lfs_mkdir(&lfs, "/parent/child") => 0;
|
||||||
lfs_mkdir(&lfs, "/parent/sibling") => 0;
|
lfs_mkdir(&lfs, "/parent/sibling") => 0;
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "/parent/sibling/1.move_me",
|
lfs_file_open(&lfs, &file, "/parent/sibling/1.move_me",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_write(&lfs, &file, "move me",
|
lfs_file_write(&lfs, &file, "move me",
|
||||||
@@ -1706,21 +1782,24 @@ code = '''
|
|||||||
|
|
||||||
// force specific directories to relocate
|
// force specific directories to relocate
|
||||||
if (RELOCATIONS & 0x1) {
|
if (RELOCATIONS & 0x1) {
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent");
|
lfs_dir_open(&lfs, &dir, "/parent");
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
}
|
}
|
||||||
if (RELOCATIONS & 0x2) {
|
if (RELOCATIONS & 0x2) {
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent/sibling");
|
lfs_dir_open(&lfs, &dir, "/parent/sibling");
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
}
|
}
|
||||||
if (RELOCATIONS & 0x4) {
|
if (RELOCATIONS & 0x4) {
|
||||||
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent/child");
|
lfs_dir_open(&lfs, &dir, "/parent/child");
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[0], 0xffffffff) => 0;
|
||||||
lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0;
|
lfs_testbd_setwear(cfg, dir.m.pair[1], 0xffffffff) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1739,6 +1818,8 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &files[3]) => 0;
|
lfs_file_close(&lfs, &files[3]) => 0;
|
||||||
|
|
||||||
// check that nothing was corrupted
|
// check that nothing was corrupted
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "/parent") => 0;
|
lfs_dir_open(&lfs, &dir, "/parent") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
@@ -1796,6 +1877,7 @@ code = '''
|
|||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "/parent/sibling/0.before", LFS_O_RDONLY) => 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;
|
lfs_file_read(&lfs, &file, buffer, 7) => 7;
|
||||||
assert(strcmp((char*)buffer, "test.5") == 0);
|
assert(strcmp((char*)buffer, "test.5") == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
[[case]] # orphan test
|
[cases.orphan]
|
||||||
in = "lfs.c"
|
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 = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "parent") => 0;
|
lfs_mkdir(&lfs, "parent") => 0;
|
||||||
lfs_mkdir(&lfs, "parent/orphan") => 0;
|
lfs_mkdir(&lfs, "parent/orphan") => 0;
|
||||||
lfs_mkdir(&lfs, "parent/child") => 0;
|
lfs_mkdir(&lfs, "parent/child") => 0;
|
||||||
@@ -13,29 +14,31 @@ code = '''
|
|||||||
// corrupt the child's most recent commit, this should be the update
|
// corrupt the child's most recent commit, this should be the update
|
||||||
// to the linked-list entry, which should orphan the orphan. Note this
|
// to the linked-list entry, which should orphan the orphan. Note this
|
||||||
// makes a lot of assumptions about the remove operation.
|
// 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_dir_open(&lfs, &dir, "parent/child") => 0;
|
||||||
lfs_block_t block = dir.m.pair[0];
|
lfs_block_t block = dir.m.pair[0];
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
uint8_t bbuffer[LFS_BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->read(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
int off = LFS_BLOCK_SIZE-1;
|
int off = BLOCK_SIZE-1;
|
||||||
while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) {
|
while (off >= 0 && buffer[off] == ERASE_VALUE) {
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3);
|
memset(&buffer[off-3], BLOCK_SIZE, 3);
|
||||||
cfg.erase(&cfg, block) => 0;
|
cfg->erase(cfg, block) => 0;
|
||||||
cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0;
|
cfg->prog(cfg, block, 0, buffer, BLOCK_SIZE) => 0;
|
||||||
cfg.sync(&cfg) => 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/orphan", &info) => LFS_ERR_NOENT;
|
||||||
lfs_stat(&lfs, "parent/child", &info) => 0;
|
lfs_stat(&lfs, "parent/child", &info) => 0;
|
||||||
lfs_fs_size(&lfs) => 8;
|
lfs_fs_size(&lfs) => 8;
|
||||||
lfs_unmount(&lfs) => 0;
|
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/orphan", &info) => LFS_ERR_NOENT;
|
||||||
lfs_stat(&lfs, "parent/child", &info) => 0;
|
lfs_stat(&lfs, "parent/child", &info) => 0;
|
||||||
lfs_fs_size(&lfs) => 8;
|
lfs_fs_size(&lfs) => 8;
|
||||||
@@ -48,7 +51,7 @@ code = '''
|
|||||||
lfs_fs_size(&lfs) => 8;
|
lfs_fs_size(&lfs) => 8;
|
||||||
lfs_unmount(&lfs) => 0;
|
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/orphan", &info) => LFS_ERR_NOENT;
|
||||||
lfs_stat(&lfs, "parent/child", &info) => 0;
|
lfs_stat(&lfs, "parent/child", &info) => 0;
|
||||||
lfs_stat(&lfs, "parent/otherchild", &info) => 0;
|
lfs_stat(&lfs, "parent/otherchild", &info) => 0;
|
||||||
@@ -56,43 +59,48 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant testing for orphans, basically just spam mkdir/remove
|
# reentrant testing for orphans, basically just spam mkdir/remove
|
||||||
|
[cases.reentrant_orphan]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
# TODO fix this case, caused by non-DAG trees
|
# TODO fix this case, caused by non-DAG trees
|
||||||
if = '!(DEPTH == 3 && LFS_CACHE_SIZE != 64)'
|
if = '!(DEPTH == 3 && CACHE_SIZE != 64)'
|
||||||
define = [
|
defines = [
|
||||||
{FILES=6, DEPTH=1, CYCLES=20},
|
{FILES=6, DEPTH=1, CYCLES=20},
|
||||||
{FILES=26, DEPTH=1, CYCLES=20},
|
{FILES=26, DEPTH=1, CYCLES=20},
|
||||||
{FILES=3, DEPTH=3, CYCLES=20},
|
{FILES=3, DEPTH=3, CYCLES=20},
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
srand(1);
|
srand(1);
|
||||||
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
|
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
for (int i = 0; i < CYCLES; i++) {
|
for (unsigned i = 0; i < CYCLES; i++) {
|
||||||
// create random path
|
// create random path
|
||||||
char full_path[256];
|
char full_path[256];
|
||||||
for (int d = 0; d < DEPTH; d++) {
|
for (unsigned d = 0; d < DEPTH; d++) {
|
||||||
sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
|
sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it does not exist, we create it, else we destroy
|
// if it does not exist, we create it, else we destroy
|
||||||
|
struct lfs_info info;
|
||||||
int res = lfs_stat(&lfs, full_path, &info);
|
int res = lfs_stat(&lfs, full_path, &info);
|
||||||
if (res == LFS_ERR_NOENT) {
|
if (res == LFS_ERR_NOENT) {
|
||||||
// create each directory in turn, ignore if dir already exists
|
// 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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
err = lfs_mkdir(&lfs, path);
|
err = lfs_mkdir(&lfs, path);
|
||||||
assert(!err || err == LFS_ERR_EXIST);
|
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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
lfs_stat(&lfs, path, &info) => 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
|
// try to delete path in reverse order, ignore if dir is not empty
|
||||||
for (int d = DEPTH-1; d >= 0; d--) {
|
for (int d = DEPTH-1; d >= 0; d--) {
|
||||||
|
char path[1024];
|
||||||
strcpy(path, full_path);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
err = lfs_remove(&lfs, path);
|
err = lfs_remove(&lfs, path);
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
|
|
||||||
[[case]] # simple path test
|
# simple path test
|
||||||
|
[cases.path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "tea") => 0;
|
lfs_mkdir(&lfs, "tea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
||||||
|
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "tea/hottea", &info) => 0;
|
||||||
assert(strcmp(info.name, "hottea") == 0);
|
assert(strcmp(info.name, "hottea") == 0);
|
||||||
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
|
||||||
@@ -21,15 +24,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # redundant slashes
|
# redundant slashes
|
||||||
|
[cases.redundant_slashes]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "tea") => 0;
|
lfs_mkdir(&lfs, "tea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
||||||
|
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
|
||||||
assert(strcmp(info.name, "hottea") == 0);
|
assert(strcmp(info.name, "hottea") == 0);
|
||||||
lfs_stat(&lfs, "//tea//hottea", &info) => 0;
|
lfs_stat(&lfs, "//tea//hottea", &info) => 0;
|
||||||
@@ -45,15 +51,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # dot path test
|
# dot path test
|
||||||
|
[cases.dot_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "tea") => 0;
|
lfs_mkdir(&lfs, "tea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
||||||
|
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "./tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "./tea/hottea", &info) => 0;
|
||||||
assert(strcmp(info.name, "hottea") == 0);
|
assert(strcmp(info.name, "hottea") == 0);
|
||||||
lfs_stat(&lfs, "/./tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "/./tea/hottea", &info) => 0;
|
||||||
@@ -71,10 +80,12 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # dot dot path test
|
# dot dot path test
|
||||||
|
[cases.dot_dot_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "tea") => 0;
|
lfs_mkdir(&lfs, "tea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
||||||
@@ -84,6 +95,7 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
||||||
|
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "coffee/../tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "coffee/../tea/hottea", &info) => 0;
|
||||||
assert(strcmp(info.name, "hottea") == 0);
|
assert(strcmp(info.name, "hottea") == 0);
|
||||||
lfs_stat(&lfs, "tea/coldtea/../hottea", &info) => 0;
|
lfs_stat(&lfs, "tea/coldtea/../hottea", &info) => 0;
|
||||||
@@ -101,15 +113,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # trailing dot path test
|
# trailing dot path test
|
||||||
|
[cases.trailing_dot_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "tea") => 0;
|
lfs_mkdir(&lfs, "tea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
lfs_mkdir(&lfs, "tea/coldtea") => 0;
|
||||||
|
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "tea/hottea/", &info) => 0;
|
lfs_stat(&lfs, "tea/hottea/", &info) => 0;
|
||||||
assert(strcmp(info.name, "hottea") == 0);
|
assert(strcmp(info.name, "hottea") == 0);
|
||||||
lfs_stat(&lfs, "tea/hottea/.", &info) => 0;
|
lfs_stat(&lfs, "tea/hottea/.", &info) => 0;
|
||||||
@@ -123,11 +138,14 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # leading dot path test
|
# leading dot path test
|
||||||
|
[cases.leading_dot_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, ".milk") => 0;
|
lfs_mkdir(&lfs, ".milk") => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, ".milk", &info) => 0;
|
lfs_stat(&lfs, ".milk", &info) => 0;
|
||||||
strcmp(info.name, ".milk") => 0;
|
strcmp(info.name, ".milk") => 0;
|
||||||
lfs_stat(&lfs, "tea/.././.milk", &info) => 0;
|
lfs_stat(&lfs, "tea/.././.milk", &info) => 0;
|
||||||
@@ -135,10 +153,12 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # root dot dot path test
|
# root dot dot path test
|
||||||
|
[cases.root_dot_dot_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "tea") => 0;
|
lfs_mkdir(&lfs, "tea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
lfs_mkdir(&lfs, "tea/hottea") => 0;
|
||||||
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
lfs_mkdir(&lfs, "tea/warmtea") => 0;
|
||||||
@@ -148,6 +168,7 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
||||||
|
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0;
|
lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0;
|
||||||
strcmp(info.name, "hottea") => 0;
|
strcmp(info.name, "hottea") => 0;
|
||||||
|
|
||||||
@@ -159,10 +180,13 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # invalid path tests
|
# invalid path tests
|
||||||
|
[cases.invalid_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
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", &info) => LFS_ERR_NOENT;
|
||||||
lfs_stat(&lfs, "dirt/ground", &info) => LFS_ERR_NOENT;
|
lfs_stat(&lfs, "dirt/ground", &info) => LFS_ERR_NOENT;
|
||||||
lfs_stat(&lfs, "dirt/ground/earth", &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_remove(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_mkdir(&lfs, "dirt/ground") => 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_file_open(&lfs, &file, "dirt/ground", LFS_O_WRONLY | LFS_O_CREAT)
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
|
lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
|
||||||
@@ -180,15 +205,19 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # root operations
|
# root operations
|
||||||
|
[cases.root]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "/", &info) => 0;
|
lfs_stat(&lfs, "/", &info) => 0;
|
||||||
assert(strcmp(info.name, "/") == 0);
|
assert(strcmp(info.name, "/") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
|
|
||||||
lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY | LFS_O_CREAT)
|
lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY | LFS_O_CREAT)
|
||||||
=> LFS_ERR_ISDIR;
|
=> LFS_ERR_ISDIR;
|
||||||
|
|
||||||
@@ -196,10 +225,13 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # root representations
|
# root representations
|
||||||
|
[cases.root_reprs]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "/", &info) => 0;
|
lfs_stat(&lfs, "/", &info) => 0;
|
||||||
assert(strcmp(info.name, "/") == 0);
|
assert(strcmp(info.name, "/") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
@@ -221,10 +253,13 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # superblock conflict test
|
# superblock conflict test
|
||||||
|
[cases.superblock_conflict]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT;
|
lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT;
|
||||||
lfs_remove(&lfs, "littlefs") => LFS_ERR_NOENT;
|
lfs_remove(&lfs, "littlefs") => LFS_ERR_NOENT;
|
||||||
|
|
||||||
@@ -237,18 +272,22 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # max path test
|
# max path test
|
||||||
|
[cases.max_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "coffee") => 0;
|
lfs_mkdir(&lfs, "coffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
||||||
|
|
||||||
|
char path[1024];
|
||||||
memset(path, 'w', LFS_NAME_MAX+1);
|
memset(path, 'w', LFS_NAME_MAX+1);
|
||||||
path[LFS_NAME_MAX+1] = '\0';
|
path[LFS_NAME_MAX+1] = '\0';
|
||||||
lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG;
|
lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT)
|
lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT)
|
||||||
=> LFS_ERR_NAMETOOLONG;
|
=> LFS_ERR_NAMETOOLONG;
|
||||||
|
|
||||||
@@ -261,19 +300,23 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # really big path test
|
# really big path test
|
||||||
|
[cases.really_big_path]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_mkdir(&lfs, "coffee") => 0;
|
lfs_mkdir(&lfs, "coffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
|
||||||
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
|
||||||
|
|
||||||
|
char path[1024];
|
||||||
memset(path, 'w', LFS_NAME_MAX);
|
memset(path, 'w', LFS_NAME_MAX);
|
||||||
path[LFS_NAME_MAX] = '\0';
|
path[LFS_NAME_MAX] = '\0';
|
||||||
lfs_mkdir(&lfs, path) => 0;
|
lfs_mkdir(&lfs, path) => 0;
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
# specific corner cases worth explicitly testing for
|
# specific corner cases worth explicitly testing for
|
||||||
[[case]] # dangling split dir test
|
[cases.dangling_split_dir]
|
||||||
define.ITERATIONS = 20
|
defines.ITERATIONS = 20
|
||||||
define.COUNT = 10
|
defines.COUNT = 10
|
||||||
define.LFS_BLOCK_CYCLES = [8, 1]
|
defines.BLOCK_CYCLES = [8, 1]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// fill up filesystem so only ~16 blocks are left
|
// 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;
|
lfs_file_open(&lfs, &file, "padding", LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
||||||
|
uint8_t buffer[512];
|
||||||
memset(buffer, 0, 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_write(&lfs, &file, buffer, 512) => 512;
|
||||||
}
|
}
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -17,18 +20,22 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "child") => 0;
|
lfs_mkdir(&lfs, "child") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int j = 0; j < ITERATIONS; j++) {
|
for (unsigned j = 0; j < ITERATIONS; j++) {
|
||||||
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);
|
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "child") => 0;
|
lfs_dir_open(&lfs, &dir, "child") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
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);
|
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
strcmp(info.name, path) => 0;
|
strcmp(info.name, path) => 0;
|
||||||
@@ -36,46 +43,54 @@ code = '''
|
|||||||
lfs_dir_read(&lfs, &dir, &info) => 0;
|
lfs_dir_read(&lfs, &dir, &info) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 0;
|
lfs_dir_close(&lfs, &dir) => 0;
|
||||||
|
|
||||||
if (j == ITERATIONS-1) {
|
if (j == (unsigned)ITERATIONS-1) {
|
||||||
break;
|
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);
|
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &dir, "child") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
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);
|
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
strcmp(info.name, path) => 0;
|
strcmp(info.name, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 0;
|
lfs_dir_read(&lfs, &dir, &info) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 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);
|
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # outdated head test
|
[cases.outdated_head]
|
||||||
define.ITERATIONS = 20
|
defines.ITERATIONS = 20
|
||||||
define.COUNT = 10
|
defines.COUNT = 10
|
||||||
define.LFS_BLOCK_CYCLES = [8, 1]
|
defines.BLOCK_CYCLES = [8, 1]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
// fill up filesystem so only ~16 blocks are left
|
// 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;
|
lfs_file_open(&lfs, &file, "padding", LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
||||||
|
uint8_t buffer[512];
|
||||||
memset(buffer, 0, 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_write(&lfs, &file, buffer, 512) => 512;
|
||||||
}
|
}
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -83,18 +98,22 @@ code = '''
|
|||||||
lfs_mkdir(&lfs, "child") => 0;
|
lfs_mkdir(&lfs, "child") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int j = 0; j < ITERATIONS; j++) {
|
for (unsigned j = 0; j < ITERATIONS; j++) {
|
||||||
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);
|
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_dir_open(&lfs, &dir, "child") => 0;
|
lfs_dir_open(&lfs, &dir, "child") => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
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);
|
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
strcmp(info.name, path) => 0;
|
strcmp(info.name, path) => 0;
|
||||||
@@ -110,7 +129,8 @@ code = '''
|
|||||||
lfs_dir_rewind(&lfs, &dir) => 0;
|
lfs_dir_rewind(&lfs, &dir) => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
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);
|
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
strcmp(info.name, path) => 0;
|
strcmp(info.name, path) => 0;
|
||||||
@@ -126,7 +146,8 @@ code = '''
|
|||||||
lfs_dir_rewind(&lfs, &dir) => 0;
|
lfs_dir_rewind(&lfs, &dir) => 0;
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
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);
|
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_dir_read(&lfs, &dir, &info) => 1;
|
lfs_dir_read(&lfs, &dir, &info) => 1;
|
||||||
strcmp(info.name, path) => 0;
|
strcmp(info.name, path) => 0;
|
||||||
@@ -135,7 +156,8 @@ code = '''
|
|||||||
lfs_dir_read(&lfs, &dir, &info) => 0;
|
lfs_dir_read(&lfs, &dir, &info) => 0;
|
||||||
lfs_dir_close(&lfs, &dir) => 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);
|
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
|
||||||
lfs_remove(&lfs, path) => 0;
|
lfs_remove(&lfs, path) => 0;
|
||||||
}
|
}
|
||||||
@@ -143,45 +165,50 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant testing for relocations, this is the same as the
|
# reentrant testing for relocations, this is the same as the
|
||||||
# orphan testing, except here we also set block_cycles so that
|
# orphan testing, except here we also set block_cycles so that
|
||||||
# almost every tree operation needs a relocation
|
# almost every tree operation needs a relocation
|
||||||
|
[cases.reentrant_relocations]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
# TODO fix this case, caused by non-DAG trees
|
# TODO fix this case, caused by non-DAG trees
|
||||||
if = '!(DEPTH == 3 && LFS_CACHE_SIZE != 64)'
|
if = '!(DEPTH == 3 && CACHE_SIZE != 64)'
|
||||||
define = [
|
defines = [
|
||||||
{FILES=6, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
|
{FILES=6, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
|
||||||
{FILES=26, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
|
{FILES=26, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
|
||||||
{FILES=3, DEPTH=3, CYCLES=20, LFS_BLOCK_CYCLES=1},
|
{FILES=3, DEPTH=3, CYCLES=20, BLOCK_CYCLES=1},
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
srand(1);
|
srand(1);
|
||||||
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
|
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
for (int i = 0; i < CYCLES; i++) {
|
for (unsigned i = 0; i < CYCLES; i++) {
|
||||||
// create random path
|
// create random path
|
||||||
char full_path[256];
|
char full_path[256];
|
||||||
for (int d = 0; d < DEPTH; d++) {
|
for (unsigned d = 0; d < DEPTH; d++) {
|
||||||
sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
|
sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it does not exist, we create it, else we destroy
|
// if it does not exist, we create it, else we destroy
|
||||||
|
struct lfs_info info;
|
||||||
int res = lfs_stat(&lfs, full_path, &info);
|
int res = lfs_stat(&lfs, full_path, &info);
|
||||||
if (res == LFS_ERR_NOENT) {
|
if (res == LFS_ERR_NOENT) {
|
||||||
// create each directory in turn, ignore if dir already exists
|
// 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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
err = lfs_mkdir(&lfs, path);
|
err = lfs_mkdir(&lfs, path);
|
||||||
assert(!err || err == LFS_ERR_EXIST);
|
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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
@@ -194,7 +221,8 @@ code = '''
|
|||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS_TYPE_DIR);
|
||||||
|
|
||||||
// try to delete path in reverse order, ignore if dir is not empty
|
// 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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
err = lfs_remove(&lfs, path);
|
err = lfs_remove(&lfs, path);
|
||||||
@@ -207,44 +235,49 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant testing for relocations, but now with random renames!
|
# reentrant testing for relocations, but now with random renames!
|
||||||
|
[cases.reentrant_relocations_renames]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
# TODO fix this case, caused by non-DAG trees
|
# TODO fix this case, caused by non-DAG trees
|
||||||
if = '!(DEPTH == 3 && LFS_CACHE_SIZE != 64)'
|
if = '!(DEPTH == 3 && CACHE_SIZE != 64)'
|
||||||
define = [
|
defines = [
|
||||||
{FILES=6, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
|
{FILES=6, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
|
||||||
{FILES=26, DEPTH=1, CYCLES=20, LFS_BLOCK_CYCLES=1},
|
{FILES=26, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
|
||||||
{FILES=3, DEPTH=3, CYCLES=20, LFS_BLOCK_CYCLES=1},
|
{FILES=3, DEPTH=3, CYCLES=20, BLOCK_CYCLES=1},
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
srand(1);
|
srand(1);
|
||||||
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
|
const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
for (int i = 0; i < CYCLES; i++) {
|
for (unsigned i = 0; i < CYCLES; i++) {
|
||||||
// create random path
|
// create random path
|
||||||
char full_path[256];
|
char full_path[256];
|
||||||
for (int d = 0; d < DEPTH; d++) {
|
for (unsigned d = 0; d < DEPTH; d++) {
|
||||||
sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
|
sprintf(&full_path[2*d], "/%c", alpha[rand() % FILES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it does not exist, we create it, else we destroy
|
// if it does not exist, we create it, else we destroy
|
||||||
|
struct lfs_info info;
|
||||||
int res = lfs_stat(&lfs, full_path, &info);
|
int res = lfs_stat(&lfs, full_path, &info);
|
||||||
assert(!res || res == LFS_ERR_NOENT);
|
assert(!res || res == LFS_ERR_NOENT);
|
||||||
if (res == LFS_ERR_NOENT) {
|
if (res == LFS_ERR_NOENT) {
|
||||||
// create each directory in turn, ignore if dir already exists
|
// 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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
err = lfs_mkdir(&lfs, path);
|
err = lfs_mkdir(&lfs, path);
|
||||||
assert(!err || err == LFS_ERR_EXIST);
|
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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
@@ -257,7 +290,7 @@ code = '''
|
|||||||
|
|
||||||
// create new random path
|
// create new random path
|
||||||
char new_path[256];
|
char new_path[256];
|
||||||
for (int d = 0; d < DEPTH; d++) {
|
for (unsigned d = 0; d < DEPTH; d++) {
|
||||||
sprintf(&new_path[2*d], "/%c", alpha[rand() % FILES]);
|
sprintf(&new_path[2*d], "/%c", alpha[rand() % FILES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +299,8 @@ code = '''
|
|||||||
assert(!res || res == LFS_ERR_NOENT);
|
assert(!res || res == LFS_ERR_NOENT);
|
||||||
if (res == LFS_ERR_NOENT) {
|
if (res == LFS_ERR_NOENT) {
|
||||||
// stop once some dir is renamed
|
// 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]);
|
strcpy(&path[2*d], &full_path[2*d]);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
strcpy(&path[128+2*d], &new_path[2*d]);
|
strcpy(&path[128+2*d], &new_path[2*d]);
|
||||||
@@ -278,7 +312,8 @@ code = '''
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int d = 0; d < DEPTH; d++) {
|
for (unsigned d = 0; d < DEPTH; d++) {
|
||||||
|
char path[1024];
|
||||||
strcpy(path, new_path);
|
strcpy(path, new_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
lfs_stat(&lfs, path, &info) => 0;
|
lfs_stat(&lfs, path, &info) => 0;
|
||||||
@@ -290,7 +325,8 @@ code = '''
|
|||||||
} else {
|
} else {
|
||||||
// try to delete path in reverse order,
|
// try to delete path in reverse order,
|
||||||
// ignore if dir is not empty
|
// 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);
|
strcpy(path, full_path);
|
||||||
path[2*d+2] = '\0';
|
path[2*d+2] = '\0';
|
||||||
err = lfs_remove(&lfs, path);
|
err = lfs_remove(&lfs, path);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
[[case]] # simple file seek
|
# simple file seek
|
||||||
define = [
|
[cases.seek]
|
||||||
|
defines = [
|
||||||
{COUNT=132, SKIP=4},
|
{COUNT=132, SKIP=4},
|
||||||
{COUNT=132, SKIP=128},
|
{COUNT=132, SKIP=128},
|
||||||
{COUNT=200, SKIP=10},
|
{COUNT=200, SKIP=10},
|
||||||
@@ -9,11 +10,14 @@ define = [
|
|||||||
{COUNT=4, SKIP=2},
|
{COUNT=4, SKIP=2},
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "kitty",
|
lfs_file_open(&lfs, &file, "kitty",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
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);
|
memcpy(buffer, "kittycatcat", size);
|
||||||
for (int j = 0; j < COUNT; j++) {
|
for (int j = 0; j < COUNT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size);
|
lfs_file_write(&lfs, &file, buffer, size);
|
||||||
@@ -21,7 +25,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_file_open(&lfs, &file, "kitty", LFS_O_RDONLY) => 0;
|
||||||
|
|
||||||
lfs_soff_t pos = -1;
|
lfs_soff_t pos = -1;
|
||||||
@@ -68,8 +72,9 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # simple file seek and write
|
# simple file seek and write
|
||||||
define = [
|
[cases.seek_write]
|
||||||
|
defines = [
|
||||||
{COUNT=132, SKIP=4},
|
{COUNT=132, SKIP=4},
|
||||||
{COUNT=132, SKIP=128},
|
{COUNT=132, SKIP=128},
|
||||||
{COUNT=200, SKIP=10},
|
{COUNT=200, SKIP=10},
|
||||||
@@ -78,11 +83,14 @@ define = [
|
|||||||
{COUNT=4, SKIP=2},
|
{COUNT=4, SKIP=2},
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "kitty",
|
lfs_file_open(&lfs, &file, "kitty",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
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);
|
memcpy(buffer, "kittycatcat", size);
|
||||||
for (int j = 0; j < COUNT; j++) {
|
for (int j = 0; j < COUNT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size);
|
lfs_file_write(&lfs, &file, buffer, size);
|
||||||
@@ -90,7 +98,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
|
||||||
|
|
||||||
lfs_soff_t pos = -1;
|
lfs_soff_t pos = -1;
|
||||||
@@ -129,15 +137,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # boundary seek and writes
|
# boundary seek and writes
|
||||||
define.COUNT = 132
|
[cases.boundary_seek_write]
|
||||||
define.OFFSETS = '"{512, 1020, 513, 1021, 511, 1019, 1441}"'
|
defines.COUNT = 132
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "kitty",
|
lfs_file_open(&lfs, &file, "kitty",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
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);
|
memcpy(buffer, "kittycatcat", size);
|
||||||
for (int j = 0; j < COUNT; j++) {
|
for (int j = 0; j < COUNT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size);
|
lfs_file_write(&lfs, &file, buffer, size);
|
||||||
@@ -145,11 +156,11 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
|
||||||
|
|
||||||
size = strlen("hedgehoghog");
|
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++) {
|
for (unsigned i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) {
|
||||||
lfs_soff_t off = offsets[i];
|
lfs_soff_t off = offsets[i];
|
||||||
@@ -183,8 +194,9 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # out of bounds seek
|
# out of bounds seek
|
||||||
define = [
|
[cases.out_of_bounds_seek]
|
||||||
|
defines = [
|
||||||
{COUNT=132, SKIP=4},
|
{COUNT=132, SKIP=4},
|
||||||
{COUNT=132, SKIP=128},
|
{COUNT=132, SKIP=128},
|
||||||
{COUNT=200, SKIP=10},
|
{COUNT=200, SKIP=10},
|
||||||
@@ -193,18 +205,21 @@ define = [
|
|||||||
{COUNT=4, SKIP=3},
|
{COUNT=4, SKIP=3},
|
||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "kitty",
|
lfs_file_open(&lfs, &file, "kitty",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
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);
|
memcpy(buffer, "kittycatcat", size);
|
||||||
for (int j = 0; j < COUNT; j++) {
|
for (int j = 0; j < COUNT; j++) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size);
|
lfs_file_write(&lfs, &file, buffer, size);
|
||||||
}
|
}
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
|
||||||
|
|
||||||
size = strlen("kittycatcat");
|
size = strlen("kittycatcat");
|
||||||
@@ -238,16 +253,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # inline write and seek
|
# inline write and seek
|
||||||
define.SIZE = [2, 4, 128, 132]
|
[cases.inline_write_seek]
|
||||||
|
defines.SIZE = [2, 4, 128, 132]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "tinykitty",
|
lfs_file_open(&lfs, &file, "tinykitty",
|
||||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26);
|
memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26);
|
||||||
for (unsigned i = 0; i < SIZE; i++) {
|
for (unsigned i = 0; i < SIZE; i++) {
|
||||||
lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1;
|
lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1;
|
||||||
@@ -305,16 +324,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # file seek and write with power-loss
|
# file seek and write with power-loss
|
||||||
|
[cases.reentrant_seek_write]
|
||||||
# must be power-of-2 for quadratic probing to be exhaustive
|
# must be power-of-2 for quadratic probing to be exhaustive
|
||||||
define.COUNT = [4, 64, 128]
|
defines.COUNT = [4, 64, 128]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&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);
|
err = lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY);
|
||||||
assert(!err || err == LFS_ERR_NOENT);
|
assert(!err || err == LFS_ERR_NOENT);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
@@ -334,14 +357,14 @@ code = '''
|
|||||||
if (lfs_file_size(&lfs, &file) == 0) {
|
if (lfs_file_size(&lfs, &file) == 0) {
|
||||||
for (int j = 0; j < COUNT; j++) {
|
for (int j = 0; j < COUNT; j++) {
|
||||||
strcpy((char*)buffer, "kittycatcat");
|
strcpy((char*)buffer, "kittycatcat");
|
||||||
size = strlen((char*)buffer);
|
size_t size = strlen((char*)buffer);
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
strcpy((char*)buffer, "doggodogdog");
|
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_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0;
|
||||||
lfs_file_size(&lfs, &file) => COUNT*size;
|
lfs_file_size(&lfs, &file) => COUNT*size;
|
||||||
|
|||||||
@@ -1,41 +1,53 @@
|
|||||||
[[case]] # simple formatting test
|
# simple formatting test
|
||||||
|
[cases.format]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # mount/unmount
|
# mount/unmount
|
||||||
|
[cases.mount]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant format
|
# reentrant format
|
||||||
|
[cases.reentrant_format]
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # invalid mount
|
# invalid mount
|
||||||
|
[cases.invalid_mount]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
|
lfs_t lfs;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # expanding superblock
|
# expanding superblock
|
||||||
define.LFS_BLOCK_CYCLES = [32, 33, 1]
|
[cases.expanding_superblock]
|
||||||
define.N = [10, 100, 1000]
|
defines.LFS_BLOCK_CYCLES = [32, 33, 1]
|
||||||
|
defines.N = [10, 100, 1000]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "dummy",
|
lfs_file_open(&lfs, &file, "dummy",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "dummy", &info) => 0;
|
lfs_stat(&lfs, "dummy", &info) => 0;
|
||||||
assert(strcmp(info.name, "dummy") == 0);
|
assert(strcmp(info.name, "dummy") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
@@ -44,25 +56,30 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// one last check after power-cycle
|
// 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_file_open(&lfs, &file, "dummy",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
struct lfs_info info;
|
||||||
lfs_stat(&lfs, "dummy", &info) => 0;
|
lfs_stat(&lfs, "dummy", &info) => 0;
|
||||||
assert(strcmp(info.name, "dummy") == 0);
|
assert(strcmp(info.name, "dummy") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # expanding superblock with power cycle
|
# expanding superblock with power cycle
|
||||||
define.LFS_BLOCK_CYCLES = [32, 33, 1]
|
[cases.expanding_superblock_power_cycle]
|
||||||
define.N = [10, 100, 1000]
|
defines.LFS_BLOCK_CYCLES = [32, 33, 1]
|
||||||
|
defines.N = [10, 100, 1000]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
// remove lingering dummy?
|
// 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));
|
assert(err == 0 || (err == LFS_ERR_NOENT && i == 0));
|
||||||
if (!err) {
|
if (!err) {
|
||||||
assert(strcmp(info.name, "dummy") == 0);
|
assert(strcmp(info.name, "dummy") == 0);
|
||||||
@@ -70,6 +87,7 @@ code = '''
|
|||||||
lfs_remove(&lfs, "dummy") => 0;
|
lfs_remove(&lfs, "dummy") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "dummy",
|
lfs_file_open(&lfs, &file, "dummy",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -80,26 +98,30 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// one last check after power-cycle
|
// 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;
|
lfs_stat(&lfs, "dummy", &info) => 0;
|
||||||
assert(strcmp(info.name, "dummy") == 0);
|
assert(strcmp(info.name, "dummy") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # reentrant expanding superblock
|
# reentrant expanding superblock
|
||||||
define.LFS_BLOCK_CYCLES = [2, 1]
|
[cases.reentrant_expanding_superblock]
|
||||||
define.N = 24
|
defines.LFS_BLOCK_CYCLES = [2, 1]
|
||||||
|
defines.N = 24
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
// remove lingering dummy?
|
// remove lingering dummy?
|
||||||
|
struct lfs_info info;
|
||||||
err = lfs_stat(&lfs, "dummy", &info);
|
err = lfs_stat(&lfs, "dummy", &info);
|
||||||
assert(err == 0 || (err == LFS_ERR_NOENT && i == 0));
|
assert(err == 0 || (err == LFS_ERR_NOENT && i == 0));
|
||||||
if (!err) {
|
if (!err) {
|
||||||
@@ -108,6 +130,7 @@ code = '''
|
|||||||
lfs_remove(&lfs, "dummy") => 0;
|
lfs_remove(&lfs, "dummy") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "dummy",
|
lfs_file_open(&lfs, &file, "dummy",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
@@ -119,7 +142,8 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// one last check after power-cycle
|
// 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;
|
lfs_stat(&lfs, "dummy", &info) => 0;
|
||||||
assert(strcmp(info.name, "dummy") == 0);
|
assert(strcmp(info.name, "dummy") == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS_TYPE_REG);
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
[[case]] # simple truncate
|
# simple truncate
|
||||||
define.MEDIUMSIZE = [32, 2048]
|
[cases.truncate]
|
||||||
define.LARGESIZE = 8192
|
defines.MEDIUMSIZE = [32, 2048]
|
||||||
|
defines.LARGESIZE = 8192
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "baldynoop",
|
lfs_file_open(&lfs, &file, "baldynoop",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "hair");
|
strcpy((char*)buffer, "hair");
|
||||||
size = strlen((char*)buffer);
|
size_t size = strlen((char*)buffer);
|
||||||
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -17,7 +21,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "baldynoop", LFS_O_RDWR) => 0;
|
||||||
lfs_file_size(&lfs, &file) => LARGESIZE;
|
lfs_file_size(&lfs, &file) => LARGESIZE;
|
||||||
|
|
||||||
@@ -27,7 +31,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "baldynoop", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
||||||
|
|
||||||
@@ -42,17 +46,21 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # truncate and read
|
# truncate and read
|
||||||
define.MEDIUMSIZE = [32, 2048]
|
[cases.truncate_read]
|
||||||
define.LARGESIZE = 8192
|
defines.MEDIUMSIZE = [32, 2048]
|
||||||
|
defines.LARGESIZE = 8192
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "baldyread",
|
lfs_file_open(&lfs, &file, "baldyread",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "hair");
|
strcpy((char*)buffer, "hair");
|
||||||
size = strlen((char*)buffer);
|
size_t size = strlen((char*)buffer);
|
||||||
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -61,7 +69,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "baldyread", LFS_O_RDWR) => 0;
|
||||||
lfs_file_size(&lfs, &file) => LARGESIZE;
|
lfs_file_size(&lfs, &file) => LARGESIZE;
|
||||||
|
|
||||||
@@ -78,7 +86,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "baldyread", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
||||||
|
|
||||||
@@ -93,14 +101,18 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # write, truncate, and read
|
# write, truncate, and read
|
||||||
|
[cases.write_truncate_read]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "sequence",
|
lfs_file_open(&lfs, &file, "sequence",
|
||||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
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;
|
lfs_size_t qsize = size / 4;
|
||||||
uint8_t *wb = buffer;
|
uint8_t *wb = buffer;
|
||||||
uint8_t *rb = buffer + size;
|
uint8_t *rb = buffer + size;
|
||||||
@@ -145,17 +157,21 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # truncate and write
|
# truncate and write
|
||||||
define.MEDIUMSIZE = [32, 2048]
|
[cases.truncate_write]
|
||||||
define.LARGESIZE = 8192
|
defines.MEDIUMSIZE = [32, 2048]
|
||||||
|
defines.LARGESIZE = 8192
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "baldywrite",
|
lfs_file_open(&lfs, &file, "baldywrite",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "hair");
|
strcpy((char*)buffer, "hair");
|
||||||
size = strlen((char*)buffer);
|
size_t size = strlen((char*)buffer);
|
||||||
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -164,7 +180,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "baldywrite", LFS_O_RDWR) => 0;
|
||||||
lfs_file_size(&lfs, &file) => LARGESIZE;
|
lfs_file_size(&lfs, &file) => LARGESIZE;
|
||||||
|
|
||||||
@@ -181,7 +197,7 @@ code = '''
|
|||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
lfs_unmount(&lfs) => 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_open(&lfs, &file, "baldywrite", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
||||||
|
|
||||||
@@ -196,26 +212,30 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # truncate write under powerloss
|
# truncate write under powerloss
|
||||||
define.SMALLSIZE = [4, 512]
|
[cases.reentrant_truncate_write]
|
||||||
define.MEDIUMSIZE = [32, 1024]
|
defines.SMALLSIZE = [4, 512]
|
||||||
define.LARGESIZE = 2048
|
defines.MEDIUMSIZE = [32, 1024]
|
||||||
|
defines.LARGESIZE = 2048
|
||||||
reentrant = true
|
reentrant = true
|
||||||
code = '''
|
code = '''
|
||||||
err = lfs_mount(&lfs, &cfg);
|
lfs_t lfs;
|
||||||
|
int err = lfs_mount(&lfs, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
}
|
}
|
||||||
|
lfs_file_t file;
|
||||||
err = lfs_file_open(&lfs, &file, "baldy", LFS_O_RDONLY);
|
err = lfs_file_open(&lfs, &file, "baldy", LFS_O_RDONLY);
|
||||||
assert(!err || err == LFS_ERR_NOENT);
|
assert(!err || err == LFS_ERR_NOENT);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
size = lfs_file_size(&lfs, &file);
|
size_t size = lfs_file_size(&lfs, &file);
|
||||||
assert(size == 0 ||
|
assert(size == 0 ||
|
||||||
size == LARGESIZE ||
|
size == (size_t)LARGESIZE ||
|
||||||
size == MEDIUMSIZE ||
|
size == (size_t)MEDIUMSIZE ||
|
||||||
size == SMALLSIZE);
|
size == (size_t)SMALLSIZE);
|
||||||
for (lfs_off_t j = 0; j < size; j += 4) {
|
for (lfs_off_t j = 0; j < size; j += 4) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, 4) => 4;
|
lfs_file_read(&lfs, &file, buffer, 4) => 4;
|
||||||
assert(memcmp(buffer, "hair", 4) == 0 ||
|
assert(memcmp(buffer, "hair", 4) == 0 ||
|
||||||
memcmp(buffer, "bald", 4) == 0 ||
|
memcmp(buffer, "bald", 4) == 0 ||
|
||||||
@@ -227,8 +247,9 @@ code = '''
|
|||||||
lfs_file_open(&lfs, &file, "baldy",
|
lfs_file_open(&lfs, &file, "baldy",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
lfs_file_size(&lfs, &file) => 0;
|
lfs_file_size(&lfs, &file) => 0;
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "hair");
|
strcpy((char*)buffer, "hair");
|
||||||
size = strlen((char*)buffer);
|
size_t size = strlen((char*)buffer);
|
||||||
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
for (lfs_off_t j = 0; j < LARGESIZE; j += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -262,12 +283,14 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # more aggressive general truncation tests
|
# more aggressive general truncation tests
|
||||||
define.CONFIG = 'range(6)'
|
[cases.aggressive_truncate]
|
||||||
define.SMALLSIZE = 32
|
defines.CONFIG = [0,1,2,3,4,5]
|
||||||
define.MEDIUMSIZE = 2048
|
defines.SMALLSIZE = 32
|
||||||
define.LARGESIZE = 8192
|
defines.MEDIUMSIZE = 2048
|
||||||
|
defines.LARGESIZE = 8192
|
||||||
code = '''
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
#define COUNT 5
|
#define COUNT 5
|
||||||
const struct {
|
const struct {
|
||||||
lfs_off_t startsizes[COUNT];
|
lfs_off_t startsizes[COUNT];
|
||||||
@@ -312,16 +335,19 @@ code = '''
|
|||||||
const lfs_off_t *hotsizes = configs[CONFIG].hotsizes;
|
const lfs_off_t *hotsizes = configs[CONFIG].hotsizes;
|
||||||
const lfs_off_t *coldsizes = configs[CONFIG].coldsizes;
|
const lfs_off_t *coldsizes = configs[CONFIG].coldsizes;
|
||||||
|
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < COUNT; i++) {
|
for (unsigned i = 0; i < COUNT; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hairyhead%d", i);
|
sprintf(path, "hairyhead%d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path,
|
lfs_file_open(&lfs, &file, path,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "hair");
|
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) {
|
for (lfs_off_t j = 0; j < startsizes[i]; j += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
}
|
}
|
||||||
@@ -340,21 +366,25 @@ code = '''
|
|||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < COUNT; i++) {
|
for (unsigned i = 0; i < COUNT; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hairyhead%d", i);
|
sprintf(path, "hairyhead%d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDWR) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDWR) => 0;
|
||||||
lfs_file_size(&lfs, &file) => hotsizes[i];
|
lfs_file_size(&lfs, &file) => hotsizes[i];
|
||||||
|
|
||||||
size = strlen("hair");
|
size_t size = strlen("hair");
|
||||||
lfs_off_t j = 0;
|
lfs_off_t j = 0;
|
||||||
for (; j < startsizes[i] && j < hotsizes[i]; j += size) {
|
for (; j < startsizes[i] && j < hotsizes[i]; j += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
memcmp(buffer, "hair", size) => 0;
|
memcmp(buffer, "hair", size) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; j < hotsizes[i]; j += size) {
|
for (; j < hotsizes[i]; j += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
memcmp(buffer, "\0\0\0\0", size) => 0;
|
memcmp(buffer, "\0\0\0\0", size) => 0;
|
||||||
}
|
}
|
||||||
@@ -367,22 +397,26 @@ code = '''
|
|||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < COUNT; i++) {
|
for (unsigned i = 0; i < COUNT; i++) {
|
||||||
|
char path[1024];
|
||||||
sprintf(path, "hairyhead%d", i);
|
sprintf(path, "hairyhead%d", i);
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||||
lfs_file_size(&lfs, &file) => coldsizes[i];
|
lfs_file_size(&lfs, &file) => coldsizes[i];
|
||||||
|
|
||||||
size = strlen("hair");
|
size_t size = strlen("hair");
|
||||||
lfs_off_t j = 0;
|
lfs_off_t j = 0;
|
||||||
for (; j < startsizes[i] && j < hotsizes[i] && j < coldsizes[i];
|
for (; j < startsizes[i] && j < hotsizes[i] && j < coldsizes[i];
|
||||||
j += size) {
|
j += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
memcmp(buffer, "hair", size) => 0;
|
memcmp(buffer, "hair", size) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; j < coldsizes[i]; j += size) {
|
for (; j < coldsizes[i]; j += size) {
|
||||||
|
uint8_t buffer[1024];
|
||||||
lfs_file_read(&lfs, &file, buffer, size) => size;
|
lfs_file_read(&lfs, &file, buffer, size) => size;
|
||||||
memcmp(buffer, "\0\0\0\0", size) => 0;
|
memcmp(buffer, "\0\0\0\0", size) => 0;
|
||||||
}
|
}
|
||||||
@@ -393,16 +427,20 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[[case]] # noop truncate
|
# noop truncate
|
||||||
define.MEDIUMSIZE = [32, 2048]
|
[cases.nop_truncate]
|
||||||
|
defines.MEDIUMSIZE = [32, 2048]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_format(&lfs, &cfg) => 0;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "baldynoop",
|
lfs_file_open(&lfs, &file, "baldynoop",
|
||||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
strcpy((char*)buffer, "hair");
|
strcpy((char*)buffer, "hair");
|
||||||
size = strlen((char*)buffer);
|
size_t size = strlen((char*)buffer);
|
||||||
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
|
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
|
||||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||||
|
|
||||||
@@ -426,7 +464,7 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// still there after reboot?
|
// 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_open(&lfs, &file, "baldynoop", LFS_O_RDWR) => 0;
|
||||||
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
|
||||||
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
|
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
|
||||||
|
|||||||
Reference in New Issue
Block a user