Files
littlefs/tests/test_compat.toml
T
Christopher Haster 7b330d67eb Renamed config -> cfg
Note this includes both the lfs3_config -> lfs3_cfg structs as well as
the LFS3_CONFIG -> LFS3_CFG include define:

- LFS3_CONFIG -> LFS3_CFG
- struct lfs3_config -> struct lfs3_cfg
- struct lfs3_file_config -> struct lfs3_file_cfg
- struct lfs3_*bd_config -> struct lfs3_*bd_cfg
- cfg -> cfg

We were already using cfg as the variable name everywhere. The fact that
these names were different was an inconsistency that should be fixed
since we're committing to an API break.

LFS3_CFG is already out-of-date from upstream, and there's plans for a
config rework, but I figured I'd go ahead and change it as well to lower
the chances it gets overlooked.

---

Note this does _not_ affect LFS3_TAG_CONFIG. Having the on-disk vs
driver-level config take slightly different names is not a bad thing.
2025-07-18 18:29:41 -05:00

1341 lines
40 KiB
TOML

# Test compatibility between different littlefs versions
after = [
'test_dirs',
'test_files',
'test_fwrite',
'test_stickynotes',
'test_mount',
]
# Note, these tests are a bit special. They can run as-is to test various
# compatbility corner-cases, but if you link a previous version of littlefs
# as "lfsp" and define LFSP, they will also test migrating from lfsp -> lfs3.
#
# If LFSP is not defined, these tests will alias lfsp = lfs3 so things will
# still compile and run, but the value of many of these tests is to test
# against a previous version linked in with the help of
# scripts/changeprefix.py
#
# Though we are also limited by API changes... so by default these tests
# won't run if LFS3_VERSION changes. This can be bypassed with the test
# runner's -a/--all flag.
#
# alias littlefs symbols as needed
#
# there may be a better way to do this but oh well, explicit aliases works
code = '''
#ifdef LFSP
#define STRINGIZE(x) STRINGIZE_(x)
#define STRINGIZE_(x) #x
#include STRINGIZE(LFSP)
#else
#define LFSP_VERSION LFS3_VERSION
#define LFSP_VERSION_MAJOR LFS3_VERSION_MAJOR
#define LFSP_VERSION_MINOR LFS3_VERSION_MINOR
#define LFSP_DISK_VERSION LFS3_DISK_VERSION
#define LFSP_DISK_VERSION_MAJOR LFS3_DISK_VERSION_MAJOR
#define LFSP_DISK_VERSION_MINOR LFS3_DISK_VERSION_MINOR
#define lfsp_t lfs3_t
#define lfsp_cfg lfs3_cfg
#define LFSP_ERR_NOENT LFS3_ERR_NOENT
#define lfsp_format lfs3_format
#define LFSP_M_RDWR LFS3_M_RDWR
#define lfsp_mount lfs3_mount
#define lfsp_unmount lfs3_unmount
#define lfsp_fsinfo lfs3_fsinfo
#define lfsp_fs_stat lfs3_fs_stat
#define lfsp_dir_t lfs3_dir_t
#define lfsp_info lfs3_info
#define LFSP_TYPE_REG LFS3_TYPE_REG
#define LFSP_TYPE_DIR LFS3_TYPE_DIR
#define lfsp_mkdir lfs3_mkdir
#define lfsp_dir_open lfs3_dir_open
#define lfsp_dir_read lfs3_dir_read
#define lfsp_dir_close lfs3_dir_close
#define lfsp_file_t lfs3_file_t
#define LFSP_O_RDONLY LFS3_O_RDONLY
#define LFSP_O_WRONLY LFS3_O_WRONLY
#define LFSP_O_CREAT LFS3_O_CREAT
#define LFSP_O_EXCL LFS3_O_EXCL
#define LFSP_SEEK_SET LFS3_SEEK_SET
#define lfsp_file_open lfs3_file_open
#define lfsp_file_write lfs3_file_write
#define lfsp_file_read lfs3_file_read
#define lfsp_file_seek lfs3_file_seek
#define lfsp_file_close lfs3_file_close
#endif
'''
## forward-compatibility tests ##
# test we can mount in a new version
[cases.test_compat_forward_mount]
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
// confirm the previous mount works
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
lfsp_unmount(&lfsp) => 0;
//////
// now mount with new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
'''
# test we can read dirs in a new version
[cases.test_compat_forward_read_dirs]
defines.COUNT = 5
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
// write COUNT dirs
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfsp_mkdir(&lfsp, name) => 0;
}
lfsp_unmount(&lfsp) => 0;
//////
// now mount with new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// can we list the directories?
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_dir_read(&lfs3, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
lfs3_unmount(&lfs3) => 0;
'''
# test we can read files in a new version
[cases.test_compat_forward_read_files]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 4
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
// write COUNT files
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfsp_file_open(&lfsp, &file, name,
LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
}
lfsp_file_close(&lfsp, &file) => 0;
}
lfsp_unmount(&lfsp) => 0;
//////
// now mount with new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// can we list the files?
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_dir_read(&lfs3, &dir, &info) => 0;
char name[8];
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
}
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfs3_file_read(&lfs3, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs3_file_close(&lfs3, &file) => 0;
}
lfs3_unmount(&lfs3) => 0;
'''
# test we can read files in dirs in a new version
[cases.test_compat_forward_read_files_in_dirs]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 4
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
// write COUNT files+dirs
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[16];
sprintf(name, "dir%03d", i);
lfsp_mkdir(&lfsp, name) => 0;
lfsp_file_t file;
sprintf(name, "dir%03d/file%03d", i, i);
lfsp_file_open(&lfsp, &file, name,
LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
}
lfsp_file_close(&lfsp, &file) => 0;
}
lfsp_unmount(&lfsp) => 0;
//////
// now mount with new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// can we list the directories?
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_dir_read(&lfs3, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
// can we list the files?
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, name) => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
}
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_file_t file;
char name[16];
sprintf(name, "dir%03d/file%03d", i, i);
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfs3_file_read(&lfs3, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs3_file_close(&lfs3, &file) => 0;
}
lfs3_unmount(&lfs3) => 0;
'''
# test we can write dirs in a new version
[cases.test_compat_forward_write_dirs]
defines.COUNT = 10
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
// write COUNT/2 dirs
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
for (lfs3_size_t i = 0; i < COUNT/2; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfsp_mkdir(&lfsp, name) => 0;
}
lfsp_unmount(&lfsp) => 0;
//////
// now mount with new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// write another COUNT/2 dirs
for (lfs3_size_t i = COUNT/2; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfs3_mkdir(&lfs3, name) => 0;
}
// can we list the directories?
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_dir_read(&lfs3, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
lfs3_unmount(&lfs3) => 0;
'''
# test we can write files in a new version
[cases.test_compat_forward_write_files]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 2
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
// write half COUNT files
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
// write half
lfsp_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfsp_file_open(&lfsp, &file, name,
LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE/2; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
}
lfsp_file_close(&lfsp, &file) => 0;
// skip the other half but keep our prng reproducible
for (lfs3_size_t j = SIZE/2; j < SIZE; j++) {
TEST_PRNG(&prng);
}
}
lfsp_unmount(&lfsp) => 0;
//////
// now mount with new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// write half COUNT files
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
// skip half but keep our prng reproducible
for (lfs3_size_t j = 0; j < SIZE/2; j++) {
TEST_PRNG(&prng);
}
// write the other half
lfs3_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfs3_file_open(&lfs3, &file, name, LFS3_O_WRONLY) => 0;
lfs3_file_seek(&lfs3, &file, SIZE/2, LFS3_SEEK_SET) => SIZE/2;
for (lfs3_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfs3_file_write(&lfs3, &file, chunk, CHUNK) => CHUNK;
}
lfs3_file_close(&lfs3, &file) => 0;
}
// can we list the files?
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_dir_read(&lfs3, &dir, &info) => 0;
char name[8];
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
}
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfs3_file_read(&lfs3, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs3_file_close(&lfs3, &file) => 0;
}
lfs3_unmount(&lfs3) => 0;
'''
# test we can write files in dirs in a new version
[cases.test_compat_forward_write_files_in_dirs]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 2
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR',
]
code = '''
// create the previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfs3_format(&lfsp, LFS3_F_RDWR, &cfgp) => 0;
//////
// now mount with new version
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[16];
sprintf(name, "dir%03d", i);
lfsp_mkdir(&lfsp, name) => 0;
// write half
lfsp_file_t file;
sprintf(name, "dir%03d/file%03d", i, i);
lfsp_file_open(&lfsp, &file, name,
LFSP_O_WRONLY | LFSP_O_CREAT | LFSP_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE/2; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
}
lfsp_file_close(&lfsp, &file) => 0;
// skip the other half but keep our prng reproducible
for (lfs3_size_t j = SIZE/2; j < SIZE; j++) {
TEST_PRNG(&prng);
}
}
lfsp_unmount(&lfsp) => 0;
// mount the new version
lfs3_t lfs3;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// write half COUNT files
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
// skip half but keep our prng reproducible
for (lfs3_size_t j = 0; j < SIZE/2; j++) {
TEST_PRNG(&prng);
}
// write the other half
lfs3_file_t file;
char name[16];
sprintf(name, "dir%03d/file%03d", i, i);
lfs3_file_open(&lfs3, &file, name, LFS3_O_WRONLY) => 0;
lfs3_file_seek(&lfs3, &file, SIZE/2, LFS3_SEEK_SET) => SIZE/2;
for (lfs3_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfs3_file_write(&lfs3, &file, chunk, CHUNK) => CHUNK;
}
lfs3_file_close(&lfs3, &file) => 0;
}
// can we list the directories?
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_dir_read(&lfs3, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
// can we list the files?
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, name) => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfs3_dir_read(&lfs3, &dir, &info) => 0;
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
}
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_file_t file;
char name[16];
sprintf(name, "dir%03d/file%03d", i, i);
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfs3_file_read(&lfs3, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfs3_file_close(&lfs3, &file) => 0;
}
lfs3_unmount(&lfs3) => 0;
'''
## backwards-compatibility tests ##
# test we can mount in an old version
[cases.test_compat_backward_mount]
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the new version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// confirm the new mount works
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
lfsp_unmount(&lfsp) => 0;
'''
# test we can read dirs in an old version
[cases.test_compat_backward_read_dirs]
defines.COUNT = 5
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the new version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// write COUNT dirs
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfs3_mkdir(&lfs3, name) => 0;
}
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
// can we list the directories?
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, "/") => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_dir_read(&lfsp, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
}
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
lfsp_unmount(&lfsp) => 0;
'''
# test we can read files in an old version
[cases.test_compat_backward_read_files]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 4
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the new version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// write COUNT files
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfs3_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfs3_file_open(&lfs3, &file, name,
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfs3_file_write(&lfs3, &file, chunk, CHUNK) => CHUNK;
}
lfs3_file_close(&lfs3, &file) => 0;
}
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
// can we list the files?
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, "/") => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_dir_read(&lfsp, &dir, &info) => 0;
char name[8];
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_REG);
assert(info.size == SIZE);
}
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfsp_file_close(&lfsp, &file) => 0;
}
lfsp_unmount(&lfsp) => 0;
'''
# test we can read files in dirs in an old version
[cases.test_compat_backward_read_files_in_dirs]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 4
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the new version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// write COUNT files+dirs
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[16];
sprintf(name, "dir%03d", i);
lfs3_mkdir(&lfs3, name) => 0;
lfs3_file_t file;
sprintf(name, "dir%03d/file%03d", i, i);
lfs3_file_open(&lfs3, &file, name,
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfs3_file_write(&lfs3, &file, chunk, CHUNK) => CHUNK;
}
lfs3_file_close(&lfs3, &file) => 0;
}
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
// can we list the directories?
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, "/") => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_dir_read(&lfsp, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
}
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
// can we list the files?
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, name) => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_REG);
assert(info.size == SIZE);
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
}
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_file_t file;
char name[16];
sprintf(name, "dir%03d/file%03d", i, i);
lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfsp_file_close(&lfsp, &file) => 0;
}
lfsp_unmount(&lfsp) => 0;
'''
# test we can write dirs in an old version
[cases.test_compat_backward_write_dirs]
defines.COUNT = 10
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the new version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// write COUNT/2 dirs
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
for (lfs3_size_t i = 0; i < COUNT/2; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfs3_mkdir(&lfs3, name) => 0;
}
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
// write another COUNT/2 dirs
for (lfs3_size_t i = COUNT/2; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfsp_mkdir(&lfsp, name) => 0;
}
// can we list the directories?
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, "/") => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_dir_read(&lfsp, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
}
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
lfsp_unmount(&lfsp) => 0;
'''
# test we can write files in an old version
[cases.test_compat_backward_write_files]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 2
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the previous version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// write half COUNT files
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
// write half
lfs3_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfs3_file_open(&lfs3, &file, name,
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE/2; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfs3_file_write(&lfs3, &file, chunk, CHUNK) => CHUNK;
}
lfs3_file_close(&lfs3, &file) => 0;
// skip the other half but keep our prng reproducible
for (lfs3_size_t j = SIZE/2; j < SIZE; j++) {
TEST_PRNG(&prng);
}
}
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
// write half COUNT files
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
// skip half but keep our prng reproducible
for (lfs3_size_t j = 0; j < SIZE/2; j++) {
TEST_PRNG(&prng);
}
// write the other half
lfsp_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfsp_file_open(&lfsp, &file, name, LFSP_O_WRONLY) => 0;
lfsp_file_seek(&lfsp, &file, SIZE/2, LFSP_SEEK_SET) => SIZE/2;
for (lfs3_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
}
lfsp_file_close(&lfsp, &file) => 0;
}
// can we list the files?
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, "/") => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_dir_read(&lfsp, &dir, &info) => 0;
char name[8];
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_REG);
assert(info.size == SIZE);
}
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_file_t file;
char name[8];
sprintf(name, "file%03d", i);
lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfsp_file_close(&lfsp, &file) => 0;
}
lfsp_unmount(&lfsp) => 0;
'''
# test we can write files in dirs in an old version
[cases.test_compat_backward_write_files_in_dirs]
defines.COUNT = 5
defines.SIZE = [4, 32, 512, 8192]
defines.CHUNK = 2
if = [
'LFS3_VERSION == LFSP_VERSION',
'LFS3_DISK_VERSION == LFSP_DISK_VERSION',
]
code = '''
// create the previous version
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
// write half COUNT files
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
uint32_t prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[16];
sprintf(name, "dir%03d", i);
lfs3_mkdir(&lfs3, name) => 0;
// write half
lfs3_file_t file;
sprintf(name, "dir%03d/file%03d", i, i);
lfs3_file_open(&lfs3, &file, name,
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
for (lfs3_size_t j = 0; j < SIZE/2; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfs3_file_write(&lfs3, &file, chunk, CHUNK) => CHUNK;
}
lfs3_file_close(&lfs3, &file) => 0;
// skip the other half but keep our prng reproducible
for (lfs3_size_t j = SIZE/2; j < SIZE; j++) {
TEST_PRNG(&prng);
}
}
lfs3_unmount(&lfs3) => 0;
//////
// now mount with previous version
struct lfsp_cfg cfgp;
assert(sizeof(struct lfsp_cfg) == sizeof(struct lfs3_cfg));
memcpy(&cfgp, CFG, sizeof(cfgp));
lfsp_t lfsp;
lfsp_mount(&lfsp, LFSP_M_RDWR, &cfgp) => 0;
// write half COUNT files
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
// skip half but keep our prng reproducible
for (lfs3_size_t j = 0; j < SIZE/2; j++) {
TEST_PRNG(&prng);
}
// write the other half
lfsp_file_t file;
char name[16];
sprintf(name, "dir%03d/file%03d", i, i);
lfsp_file_open(&lfsp, &file, name, LFSP_O_WRONLY) => 0;
lfsp_file_seek(&lfsp, &file, SIZE/2, LFSP_SEEK_SET) => SIZE/2;
for (lfs3_size_t j = SIZE/2; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
for (lfs3_size_t k = 0; k < CHUNK; k++) {
chunk[k] = TEST_PRNG(&prng) & 0xff;
}
lfsp_file_write(&lfsp, &file, chunk, CHUNK) => CHUNK;
}
lfsp_file_close(&lfsp, &file) => 0;
}
// can we list the directories?
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, "/") => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_dir_read(&lfsp, &dir, &info) => 0;
char name[8];
sprintf(name, "dir%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
}
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
// can we list the files?
for (lfs3_size_t i = 0; i < COUNT; i++) {
char name[8];
sprintf(name, "dir%03d", i);
lfsp_dir_t dir;
lfsp_dir_open(&lfsp, &dir, name) => 0;
struct lfsp_info info;
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFSP_TYPE_DIR);
assert(info.size == 0);
lfsp_dir_read(&lfsp, &dir, &info) => 0;
sprintf(name, "file%03d", i);
assert(strcmp(info.name, name) == 0);
assert(info.type == LFSP_TYPE_REG);
assert(info.size == SIZE);
lfsp_dir_read(&lfsp, &dir, &info) => LFSP_ERR_NOENT;
lfsp_dir_close(&lfsp, &dir) => 0;
}
// now can we read the files?
prng = 42;
for (lfs3_size_t i = 0; i < COUNT; i++) {
lfsp_file_t file;
char name[16];
sprintf(name, "dir%03d/file%03d", i, i);
lfsp_file_open(&lfsp, &file, name, LFSP_O_RDONLY) => 0;
for (lfs3_size_t j = 0; j < SIZE; j += CHUNK) {
uint8_t chunk[CHUNK];
lfsp_file_read(&lfsp, &file, chunk, CHUNK) => CHUNK;
for (lfs3_size_t k = 0; k < CHUNK; k++) {
assert(chunk[k] == (TEST_PRNG(&prng) & 0xff));
}
}
lfsp_file_close(&lfsp, &file) => 0;
}
lfsp_unmount(&lfsp) => 0;
'''