Added tests over shared scratch files
One downside of scratch files is that there are a lot of corner cases to consider.
This commit is contained in:
@@ -5081,22 +5081,29 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
static int lfsr_mdir_lookupnext(lfs_t *lfs, const lfsr_mdir_t *mdir,
|
||||
lfsr_smid_t mid, lfsr_tag_t tag,
|
||||
lfsr_tag_t *tag_, lfsr_data_t *data_) {
|
||||
lfsr_smid_t mid_;
|
||||
lfsr_srid_t rid__;
|
||||
lfsr_tag_t tag__;
|
||||
int err = lfsr_rbyd_lookupnext(lfs, &mdir->rbyd,
|
||||
lfsr_mid_rid(lfs, mid), tag,
|
||||
&mid_, &tag__, NULL, data_);
|
||||
&rid__, &tag__, NULL, data_);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// this is very similar to lfsr_rbyd_lookupnext, but we error if
|
||||
// lookupnext would change mids
|
||||
if (mid_ != lfsr_mid_rid(lfs, mid)) {
|
||||
if (rid__ != lfsr_mid_rid(lfs, mid)) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
if (tag_) {
|
||||
// intercept pending grms here and pretend they're scratch files
|
||||
//
|
||||
// fortunately pending gmrs/scratch files have roughly the same
|
||||
// semantics, and it's easier to manage the implied mid gap in
|
||||
// higher-levels
|
||||
// TODO
|
||||
|
||||
*tag_ = tag__;
|
||||
}
|
||||
return 0;
|
||||
@@ -6940,11 +6947,6 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// pretend scratch files don't exist
|
||||
if (tag == LFSR_TAG_SCRATCH) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// go on to next name
|
||||
name += name_size;
|
||||
next:;
|
||||
@@ -8691,6 +8693,11 @@ int lfsr_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// pretend scratch files don't exist
|
||||
if (tag == LFSR_TAG_SCRATCH) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// special case for root
|
||||
if (lfsr_mdir_isroot(&mdir)) {
|
||||
strcpy(info->name, "/");
|
||||
@@ -8717,7 +8724,11 @@ int lfsr_dir_open(lfs_t *lfs, lfsr_dir_t *dir, const char *path) {
|
||||
|
||||
// are we a directory?
|
||||
if (tag != LFSR_TAG_DIR) {
|
||||
return LFS_ERR_NOTDIR;
|
||||
if (tag == LFSR_TAG_SCRATCH) {
|
||||
return LFS_ERR_NOENT;
|
||||
} else {
|
||||
return LFS_ERR_NOTDIR;
|
||||
}
|
||||
}
|
||||
|
||||
// setup dir state
|
||||
@@ -9052,7 +9063,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||
}
|
||||
|
||||
// creating a new entry?
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
if (err == LFS_ERR_NOENT || tag == LFSR_TAG_SCRATCH) {
|
||||
if (!lfsr_o_iscreat(flags)) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
@@ -9063,15 +9074,24 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||
return LFS_ERR_NAMETOOLONG;
|
||||
}
|
||||
|
||||
// create a scratch entry, this reserves the mid until first sync
|
||||
err = lfsr_mdir_commit(lfs, &file->mdir, LFSR_ATTRS(
|
||||
LFSR_ATTR(file->mdir.mid,
|
||||
SCRATCH, +1, CAT(
|
||||
LFSR_DATA_LEB128(did),
|
||||
LFSR_DATA_BUF(name, name_size)))));
|
||||
if (err) {
|
||||
return err;
|
||||
// create a scratch entry if we don't have one, this reserves the
|
||||
// mid until first sync
|
||||
//
|
||||
// note because of the preparemutation call above, there can be
|
||||
// no orphaned scratch files at this point
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
err = lfsr_mdir_commit(lfs, &file->mdir, LFSR_ATTRS(
|
||||
LFSR_ATTR(file->mdir.mid,
|
||||
SCRATCH, +1, CAT(
|
||||
LFSR_DATA_LEB128(did),
|
||||
LFSR_DATA_BUF(name, name_size)))));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// mark as unsync and uncreat, we need to convert to reg file
|
||||
// first sync
|
||||
file->flags |= LFS_F_UNSYNC | LFS_F_UNCREAT;
|
||||
|
||||
} else {
|
||||
|
||||
+678
-30
@@ -1,5 +1,5 @@
|
||||
# Test scratch files and their various use cases
|
||||
after = 'test_fwrite'
|
||||
after = ['test_fwrite', 'test_fsync']
|
||||
|
||||
|
||||
# Some specific tests
|
||||
@@ -24,16 +24,16 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs_, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_t dir_;
|
||||
lfsr_dir_open(&lfs_, &dir_, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs_, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir_) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs_, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
@@ -53,15 +53,15 @@ code = '''
|
||||
// via stat
|
||||
lfsr_stat(&lfs_, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs_, &dir_, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_open(&lfs_, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir_) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs_, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
lfsr_unmount(&lfs_) => 0;
|
||||
@@ -79,19 +79,19 @@ code = '''
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs_, &dir_, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_open(&lfs_, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir_) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs_, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42;
|
||||
@@ -119,19 +119,19 @@ code = '''
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs_, &dir_, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_open(&lfs_, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir_) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs_, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42;
|
||||
@@ -157,19 +157,19 @@ code = '''
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs_, &dir_, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_open(&lfs_, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs_, &dir_, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir_) => 0;
|
||||
lfsr_dir_read(&lfs_, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs_, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs_, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
prng_ = 42;
|
||||
@@ -339,3 +339,651 @@ code = '''
|
||||
|
||||
lfsr_unmount(&lfs) => 0;
|
||||
'''
|
||||
|
||||
[cases.test_fscratch_create_sync_wr]
|
||||
defines.SIZE = '4*BLOCK_SIZE'
|
||||
defines.CHUNK = 64
|
||||
defines.SYNC = [false, true]
|
||||
code = '''
|
||||
lfs_t lfs;
|
||||
lfsr_format(&lfs, CFG) => 0;
|
||||
lfsr_mount(&lfs, CFG) => 0;
|
||||
|
||||
// create a file
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, "gello",
|
||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||
|
||||
// as far as the filesystem is concerned, the file does not exist yet
|
||||
// via stat
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// rdonly rejected
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
// non-create rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDWR) => LFS_ERR_NOENT;
|
||||
|
||||
// write to the file
|
||||
uint32_t prng = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK;
|
||||
|
||||
// as far as the filesystem is concerned, the file does not exist yet
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// rdonly rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
// non-create rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDWR) => LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// but we should still recieve sync broadcasts on sync/close
|
||||
lfsr_file_t file__;
|
||||
lfsr_file_open(&lfs, &file__, "gello",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||
|
||||
if (SYNC) {
|
||||
// sync the file
|
||||
lfsr_file_sync(&lfs, &file) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file__) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file__, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// close the file
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file__) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file__, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
|
||||
lfsr_unmount(&lfs) => 0;
|
||||
'''
|
||||
|
||||
[cases.test_fscratch_create_sync_rw]
|
||||
defines.SIZE = '4*BLOCK_SIZE'
|
||||
defines.CHUNK = 64
|
||||
defines.SYNC = [false, true]
|
||||
code = '''
|
||||
lfs_t lfs;
|
||||
lfsr_format(&lfs, CFG) => 0;
|
||||
lfsr_mount(&lfs, CFG) => 0;
|
||||
|
||||
// create a file
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, "gello",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||
// open a second reference
|
||||
lfsr_file_t file__;
|
||||
lfsr_file_open(&lfs, &file__, "gello",
|
||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||
|
||||
// as far as the filesystem is concerned, the file does not exist yet
|
||||
// via stat
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// rdonly rejected
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
// non-create rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDWR) => LFS_ERR_NOENT;
|
||||
|
||||
// write to the second file
|
||||
uint32_t prng = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK;
|
||||
|
||||
// as far as the filesystem is concerned, the file does not exist yet
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// rdonly rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
// non-create rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDWR) => LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
if (SYNC) {
|
||||
// sync the second file
|
||||
lfsr_file_sync(&lfs, &file__) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// close the second file
|
||||
lfsr_file_close(&lfs, &file__) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
|
||||
lfsr_unmount(&lfs) => 0;
|
||||
'''
|
||||
|
||||
[cases.test_fscratch_create_desync_wdwr]
|
||||
defines.SIZE = '4*BLOCK_SIZE'
|
||||
defines.CHUNK = 64
|
||||
defines.SYNC = [false, true]
|
||||
code = '''
|
||||
lfs_t lfs;
|
||||
lfsr_format(&lfs, CFG) => 0;
|
||||
lfsr_mount(&lfs, CFG) => 0;
|
||||
|
||||
// create a desync file
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, "gello",
|
||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL | LFS_O_DESYNC) => 0;
|
||||
// open a second reference
|
||||
lfsr_file_t file__;
|
||||
lfsr_file_open(&lfs, &file__, "gello",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||
// and a third for checking sync broadcasts
|
||||
lfsr_file_t file___;
|
||||
lfsr_file_open(&lfs, &file___, "gello",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||
|
||||
// write to the first file
|
||||
uint32_t prng = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK;
|
||||
|
||||
// as far as the filesystem is concerned, the file does not exist yet
|
||||
// via stat
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// rdonly rejected
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
// non-create rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDWR) => LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// write to the second file
|
||||
prng = 42+1;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK;
|
||||
|
||||
// as far as the filesystem is concerned, the file does not exist yet
|
||||
// via stat
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, "gello", &info) => LFS_ERR_NOENT;
|
||||
// via readdir
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// rdonly rejected
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||
// non-create rejected
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_WRONLY) => LFS_ERR_NOENT;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDWR) => LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
if (SYNC) {
|
||||
// sync the second file
|
||||
lfsr_file_sync(&lfs, &file__) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42+1;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file___) => 0;
|
||||
prng_ = 42+1;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file___, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// close the second file
|
||||
lfsr_file_close(&lfs, &file__) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_t dir;
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_t file_;
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
uint32_t prng_ = 42+1;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file___) => 0;
|
||||
prng_ = 42+1;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file___, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
|
||||
// now sync the first file, this should overwrite what is written
|
||||
lfsr_file_sync(&lfs, &file) => 0;
|
||||
|
||||
// now it should show up
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file___) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file___, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
|
||||
// and close, this shouldn't change anything
|
||||
//
|
||||
// note we must sync to clear the desync flag
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
|
||||
// via stat
|
||||
lfsr_stat(&lfs, "gello", &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
// via readdir
|
||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, ".") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "..") == 0);
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, "gello") == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
// via open
|
||||
lfsr_file_open(&lfs, &file_, "gello", LFS_O_RDONLY) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file_, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file_) => 0;
|
||||
|
||||
// recieved sync broadcast?
|
||||
lfsr_file_rewind(&lfs, &file___) => 0;
|
||||
prng_ = 42;
|
||||
for (lfs_off_t i = 0; i < SIZE; i += CHUNK) {
|
||||
uint8_t wbuf[CHUNK];
|
||||
for (lfs_size_t j = 0; j < CHUNK; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng_) % 26);
|
||||
}
|
||||
uint8_t rbuf[CHUNK];
|
||||
lfsr_file_read(&lfs, &file___, rbuf, CHUNK) => CHUNK;
|
||||
assert(memcmp(wbuf, rbuf, CHUNK) == 0);
|
||||
}
|
||||
|
||||
lfsr_file_close(&lfs, &file___) => 0;
|
||||
lfsr_unmount(&lfs) => 0;
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user