b4da78993b
The above-mentioned few things:
- We weren't cleaning up orphans correctly if lfsr_file_open errored.
I think at some point we relied on having no falible operations after
the orphan creation, but various refactoring since moved buffer
allocation after orphan creation.
We could rearrange things so orphan creation is last, but I think it's
safter to just deduplicate file cleanup into the new lfsr_file_close_
function.
- LFS_O_TRUNC prevented attrs from being fetched.
It's easy to see where this went wrong. LFS_O_TRUNC prevents data from
being fetched, but we should still fetch attrs.
This is a bit annoying to fix, for now just added a trunc flag to
lfsr_file_fetch.
Also added a couple tests to catch this if it regresses in the future.
- We tried to fetch attrs on orphans.
This doesn't really hurt anything, but it's a waste of read cycles.
Moving all this stuff around added some code, but lfsr_file_fetch is a
bit easier to read now, which is a good thing:
code stack
before: 38084 2624
after: 38100 (+0.0%) 2624 (+0.0%)
2852 lines
90 KiB
TOML
2852 lines
90 KiB
TOML
# Custom attribute tests
|
|
after = ['test_files', 'test_fsync', 'test_forphans']
|
|
|
|
|
|
## General setattr/getattr tests
|
|
|
|
# test some simple attr operations
|
|
[cases.test_attrs_setattr]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, path, 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, path, 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, path, 'c', c, strlen(c)) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => strlen(a);
|
|
lfsr_sizeattr(&lfs, path, 'b') => strlen(b);
|
|
lfsr_sizeattr(&lfs, path, 'c') => strlen(c);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test truncated getattr calls still work
|
|
[cases.test_attrs_setattr_trunc]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
defines.BUFSIZE = [1, 4, 7]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, path, 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, path, 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, path, 'c', c, strlen(c)) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => strlen(a);
|
|
lfsr_sizeattr(&lfs, path, 'b') => strlen(b);
|
|
lfsr_sizeattr(&lfs, path, 'c') => strlen(c);
|
|
|
|
// mark rbuf so we can detect overflow
|
|
uint8_t rbuf[256];
|
|
rbuf[BUFSIZE] = '!';
|
|
// try reading truncated attrs
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, BUFSIZE) => BUFSIZE;
|
|
assert(memcmp(rbuf, a, BUFSIZE) == 0);
|
|
assert(rbuf[BUFSIZE] == '!');
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, BUFSIZE) => BUFSIZE;
|
|
assert(memcmp(rbuf, b, BUFSIZE) == 0);
|
|
assert(rbuf[BUFSIZE] == '!');
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, BUFSIZE) => BUFSIZE;
|
|
assert(memcmp(rbuf, c, BUFSIZE) == 0);
|
|
assert(rbuf[BUFSIZE] == '!');
|
|
|
|
// try reading the full attrs
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test ENOATTR works
|
|
[cases.test_attrs_setattr_noattr]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'b') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'c') => LFS_ERR_NOATTR;
|
|
|
|
// try reading attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// make sure setattr didn't quietly create attrs
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'b') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'c') => LFS_ERR_NOATTR;
|
|
// try reading attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that updating attrs works
|
|
[cases.test_attrs_setattr_update]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
# update based on this mask
|
|
defines.MASK = 'range(0x8)'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, path, 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, path, 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, path, 'c', c, strlen(c)) => 0;
|
|
|
|
// rewrite some attrs
|
|
const char *a_ = "Four large eggs. One cup semi-sweet chocolate chips.";
|
|
if (MASK & 0x1) {
|
|
lfsr_setattr(&lfs, path, 'a', a_, strlen(a_)) => 0;
|
|
}
|
|
const char *b_ = "Three slash four cup butter or margarine.";
|
|
if (MASK & 0x2) {
|
|
lfsr_setattr(&lfs, path, 'b', b_, strlen(b_)) => 0;
|
|
}
|
|
const char *c_ = "One and two third cups granulated sugar.";
|
|
if (MASK & 0x4) {
|
|
lfsr_setattr(&lfs, path, 'c', c_, strlen(c_)) => 0;
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
if (MASK & 0x1) {
|
|
lfsr_sizeattr(&lfs, path, 'a') => strlen(a_);
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, 'a') => strlen(a);
|
|
}
|
|
if (MASK & 0x2) {
|
|
lfsr_sizeattr(&lfs, path, 'b') => strlen(b_);
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, 'b') => strlen(b);
|
|
}
|
|
if (MASK & 0x4) {
|
|
lfsr_sizeattr(&lfs, path, 'c') => strlen(c_);
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, 'c') => strlen(c);
|
|
}
|
|
|
|
// try reading attrs
|
|
uint8_t rbuf[256];
|
|
if (MASK & 0x1) {
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => strlen(a_);
|
|
assert(memcmp(rbuf, a_, strlen(a_)) == 0);
|
|
} else {
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
}
|
|
if (MASK & 0x2) {
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => strlen(b_);
|
|
assert(memcmp(rbuf, b_, strlen(b_)) == 0);
|
|
} else {
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
}
|
|
if (MASK & 0x4) {
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => strlen(c_);
|
|
assert(memcmp(rbuf, c_, strlen(c_)) == 0);
|
|
} else {
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test removing attrs
|
|
[cases.test_attrs_removeattr]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
# remove based on this mask
|
|
defines.MASK = 'range(0x8)'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, path, 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, path, 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, path, 'c', c, strlen(c)) => 0;
|
|
|
|
// remove some attrs
|
|
if (MASK & 0x1) {
|
|
lfsr_removeattr(&lfs, path, 'a') => 0;
|
|
}
|
|
if (MASK & 0x2) {
|
|
lfsr_removeattr(&lfs, path, 'b') => 0;
|
|
}
|
|
if (MASK & 0x4) {
|
|
lfsr_removeattr(&lfs, path, 'c') => 0;
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
if (MASK & 0x1) {
|
|
lfsr_sizeattr(&lfs, path, 'a') => LFS_ERR_NOATTR;
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, 'a') => strlen(a);
|
|
}
|
|
if (MASK & 0x2) {
|
|
lfsr_sizeattr(&lfs, path, 'b') => LFS_ERR_NOATTR;
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, 'b') => strlen(b);
|
|
}
|
|
if (MASK & 0x4) {
|
|
lfsr_sizeattr(&lfs, path, 'c') => LFS_ERR_NOATTR;
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, 'c') => strlen(c);
|
|
}
|
|
|
|
// try reading the full attrs
|
|
uint8_t rbuf[256];
|
|
if (MASK & 0x1) {
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf))
|
|
=> LFS_ERR_NOATTR;
|
|
} else {
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf))
|
|
=> strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
}
|
|
if (MASK & 0x2) {
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf))
|
|
=> LFS_ERR_NOATTR;
|
|
} else {
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf))
|
|
=> strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
}
|
|
if (MASK & 0x4) {
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf))
|
|
=> LFS_ERR_NOATTR;
|
|
} else {
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf))
|
|
=> strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
# test the full range of attrs
|
|
[cases.test_attrs_all]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
defines.SIZE = 4
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// try creating every attr, this tests encoding quirks
|
|
uint32_t prng = 42;
|
|
for (uint16_t a = 0; a < 0x100; a++) {
|
|
// create the attr
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t i = 0; i < SIZE; i++) {
|
|
wbuf[i] = 'a' + (TEST_PRNG(&prng) % 26);
|
|
}
|
|
lfsr_setattr(&lfs, path, a, wbuf, SIZE) => 0;
|
|
|
|
// try getting the attr size
|
|
lfsr_sizeattr(&lfs, path, a) => SIZE;
|
|
// try reading the attr
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf)) => SIZE;
|
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
|
|
|
// remove the attr
|
|
lfsr_removeattr(&lfs, path, a) => 0;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test creating a bunch of attrs
|
|
[cases.test_attrs_many]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
defines.M = 40
|
|
defines.SIZE = 4
|
|
defines.COMPACT = [false, true]
|
|
defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// create M attrs
|
|
uint32_t prng = 42;
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t i = 0; i < SIZE; i++) {
|
|
wbuf[i] = 'a' + (TEST_PRNG(&prng) % 26);
|
|
}
|
|
lfsr_setattr(&lfs, path, a, wbuf, SIZE) => 0;
|
|
}
|
|
|
|
// try compacting?
|
|
if (COMPACT) {
|
|
lfsr_fs_gc(&lfs, -1, LFS_GC_COMPACT) => 0;
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
lfsr_sizeattr(&lfs, path, a) => SIZE;
|
|
}
|
|
// try reading the attrs
|
|
prng = 42;
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t i = 0; i < SIZE; i++) {
|
|
wbuf[i] = 'a' + (TEST_PRNG(&prng) % 26);
|
|
}
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf)) => SIZE;
|
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
|
}
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test creating a bunch of attrs on a bunch of files
|
|
[cases.test_attrs_many_many]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
defines.FILETYPE = [0, 1]
|
|
defines.N = 64
|
|
defines.M = 4
|
|
defines.SIZE = 4
|
|
defines.COMPACT = [false, true]
|
|
defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create N files
|
|
uint32_t prng = 42;
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char path[256];
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", i);
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path,
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow"))
|
|
=> strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", i);
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
|
|
// create M attrs
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
|
}
|
|
lfsr_setattr(&lfs, path, a, wbuf, SIZE) => 0;
|
|
}
|
|
}
|
|
|
|
// try compacting?
|
|
if (COMPACT) {
|
|
lfsr_fs_gc(&lfs, -1, LFS_GC_COMPACT) => 0;
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
prng = 42;
|
|
for (lfs_size_t x = 0; x < N; x++) {
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
lfsr_sizeattr(&lfs, path, a) => SIZE;
|
|
}
|
|
// try reading the attrs
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
|
}
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf)) => SIZE;
|
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# fuzz attrs
|
|
[cases.test_attrs_fuzz]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
# FILETYPE=2 => root
|
|
defines.FILETYPE = [0, 1, 2]
|
|
defines.M = 10
|
|
defines.SIZE = 4
|
|
defines.OPS = '4*M'
|
|
defines.SEED = 'range(20)'
|
|
fuzz = 'SEED'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else if (FILETYPE == 1) {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
|
|
// do nothing for root
|
|
} else {
|
|
path = "/";
|
|
}
|
|
|
|
// set up a simulation to compare against
|
|
uint32_t *sim_prngs = malloc(M*sizeof(uint32_t));
|
|
memset(sim_prngs, 0, M*sizeof(uint32_t));
|
|
|
|
uint32_t prng = SEED;
|
|
for (lfs_size_t i = 0; i < OPS; i++) {
|
|
// choose which operation to do
|
|
uint8_t op = TEST_PRNG(&prng) % 2;
|
|
|
|
// create an attr?
|
|
if (op == 0) {
|
|
// choose an attr
|
|
uint8_t a = TEST_PRNG(&prng) % M;
|
|
// choose a prng
|
|
uint32_t wprng = TEST_PRNG(&prng);
|
|
|
|
// create the attr
|
|
uint32_t wprng_ = wprng;
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
|
wbuf[j] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
|
}
|
|
lfsr_setattr(&lfs, path, a, wbuf, SIZE) => 0;
|
|
|
|
// update our sim
|
|
sim_prngs[a] = wprng;
|
|
|
|
// remove an attr?
|
|
} else if (op == 1) {
|
|
// choose an attr
|
|
uint8_t a = TEST_PRNG(&prng) % M;
|
|
|
|
// remove the attr
|
|
if (sim_prngs[a]) {
|
|
lfsr_removeattr(&lfs, path, a) => 0;
|
|
} else {
|
|
lfsr_removeattr(&lfs, path, a) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
// update our sim
|
|
sim_prngs[a] = 0;
|
|
}
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting each attr size
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
if (sim_prngs[a]) {
|
|
lfsr_sizeattr(&lfs, path, a) => SIZE;
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, a) => LFS_ERR_NOATTR;
|
|
}
|
|
}
|
|
// try reading each attr
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
if (sim_prngs[a]) {
|
|
uint32_t wprng_ = sim_prngs[a];
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t i = 0; i < SIZE; i++) {
|
|
wbuf[i] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
|
}
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf)) => SIZE;
|
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
|
} else {
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf))
|
|
=> LFS_ERR_NOATTR;
|
|
}
|
|
}
|
|
}
|
|
|
|
// clean up sim/lfs
|
|
free(sim_prngs);
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# fuzz attrs on multiple files
|
|
[cases.test_attrs_fuzz_fuzz]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
defines.FILETYPE = [0, 1]
|
|
defines.N = 64
|
|
defines.M = 4
|
|
defines.SIZE = 4
|
|
defines.OPS = '4*N*M'
|
|
defines.SEED = 'range(20)'
|
|
fuzz = 'SEED'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create N files
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char path[256];
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", i);
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path,
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow"))
|
|
=> strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", i);
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
}
|
|
|
|
// set up a simulation to compare against
|
|
uint32_t *sim_prngs = malloc(N*M*sizeof(uint32_t));
|
|
memset(sim_prngs, 0, N*M*sizeof(uint32_t));
|
|
|
|
uint32_t prng = SEED;
|
|
for (lfs_size_t i = 0; i < OPS; i++) {
|
|
// choose which operation to do
|
|
uint8_t op = TEST_PRNG(&prng) % 2;
|
|
|
|
// create an attr?
|
|
if (op == 0) {
|
|
// choose a file
|
|
lfs_size_t x = TEST_PRNG(&prng) % N;
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
// choose an attr
|
|
uint8_t a = TEST_PRNG(&prng) % M;
|
|
// choose a prng
|
|
uint32_t wprng = TEST_PRNG(&prng);
|
|
|
|
// create the attr
|
|
uint32_t wprng_ = wprng;
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
|
wbuf[j] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
|
}
|
|
lfsr_setattr(&lfs, path, a, wbuf, SIZE) => 0;
|
|
|
|
// update our sim
|
|
sim_prngs[x*M+a] = wprng;
|
|
|
|
// remove an attr?
|
|
} else if (op == 1) {
|
|
// choose a file
|
|
lfs_size_t x = TEST_PRNG(&prng) % N;
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
// choose an attr
|
|
uint8_t a = TEST_PRNG(&prng) % M;
|
|
|
|
// remove the attr
|
|
if (sim_prngs[x*M+a]) {
|
|
lfsr_removeattr(&lfs, path, a) => 0;
|
|
} else {
|
|
lfsr_removeattr(&lfs, path, a) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
// update our sim
|
|
sim_prngs[x*M+a] = 0;
|
|
}
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
for (lfs_size_t x = 0; x < N; x++) {
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
|
|
// try getting each attr size
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
if (sim_prngs[x*M+a]) {
|
|
lfsr_sizeattr(&lfs, path, a) => SIZE;
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, a) => LFS_ERR_NOATTR;
|
|
}
|
|
}
|
|
// try reading each attr
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
if (sim_prngs[x*M+a]) {
|
|
uint32_t wprng_ = sim_prngs[x*M+a];
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t i = 0; i < SIZE; i++) {
|
|
wbuf[i] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
|
}
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf)) => SIZE;
|
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
|
} else {
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf))
|
|
=> LFS_ERR_NOATTR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// clean up sim/lfs
|
|
free(sim_prngs);
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
# test that removing a file removes all attrs
|
|
[cases.test_attrs_rm]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
defines.FILETYPE = [0, 1]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, path, 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, path, 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, path, 'c', c, strlen(c)) => 0;
|
|
|
|
// remove the file
|
|
lfsr_remove(&lfs, path) => 0;
|
|
|
|
// create the file again
|
|
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// dir?
|
|
} else {
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'b') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'c') => LFS_ERR_NOATTR;
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that moving onto a file removes all attrs
|
|
[cases.test_attrs_mv_dst]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
defines.FILETYPE = [0, 1]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
path = "armadillo";
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, path, 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, path, 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, path, 'c', c, strlen(c)) => 0;
|
|
|
|
// create another file and move it onto our file
|
|
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "beaver", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// dir?
|
|
} else {
|
|
lfsr_mkdir(&lfs, "beaver") => 0;
|
|
}
|
|
|
|
lfsr_rename(&lfs, "beaver", path) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'b') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, path, 'c') => LFS_ERR_NOATTR;
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that moves bring over all attrs
|
|
[cases.test_attrs_mv_src]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
defines.FILETYPE = [0, 1]
|
|
defines.REPLACE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
const char *path;
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
path = "cat";
|
|
// dir?
|
|
} else {
|
|
path = "armadillo";
|
|
}
|
|
|
|
// if replacing create a file to replace
|
|
if (REPLACE) {
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow"))
|
|
=> strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
}
|
|
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "beaver",
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao"))
|
|
=> strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
lfsr_mkdir(&lfs, "beaver") => 0;
|
|
}
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "beaver", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "beaver", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "beaver", 'c', c, strlen(c)) => 0;
|
|
|
|
// move file
|
|
lfsr_rename(&lfs, "beaver", path) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, path, 'a') => strlen(a);
|
|
lfsr_sizeattr(&lfs, path, 'b') => strlen(b);
|
|
lfsr_sizeattr(&lfs, path, 'c') => strlen(c);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
lfsr_getattr(&lfs, path, 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
lfsr_getattr(&lfs, path, 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# fuzz attrs mixed with file moves and removes
|
|
[cases.test_attrs_mvrm_fuzz_fuzz]
|
|
# type of file to attach attrs to
|
|
# FILETYPE=0 => regular file
|
|
# FILETYPE=1 => directory
|
|
defines.FILETYPE = [0, 1]
|
|
defines.N = 64
|
|
defines.M = 4
|
|
defines.SIZE = 4
|
|
defines.OPS = '4*N*M'
|
|
defines.SEED = 'range(20)'
|
|
fuzz = 'SEED'
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create N files
|
|
for (lfs_size_t i = 0; i < N; i++) {
|
|
char path[256];
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", i);
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path,
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow"))
|
|
=> strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", i);
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
}
|
|
|
|
// set up a simulation to compare against
|
|
uint32_t *sim_prngs = malloc(N*M*sizeof(uint32_t));
|
|
memset(sim_prngs, 0, N*M*sizeof(uint32_t));
|
|
|
|
uint32_t prng = SEED;
|
|
for (lfs_size_t i = 0; i < OPS; i++) {
|
|
// choose which operation to do
|
|
uint8_t op = TEST_PRNG(&prng) % 4;
|
|
|
|
// create an attr?
|
|
if (op == 0) {
|
|
// choose a file
|
|
lfs_size_t x = TEST_PRNG(&prng) % N;
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
// choose an attr
|
|
uint8_t a = TEST_PRNG(&prng) % M;
|
|
// choose a prng
|
|
uint32_t wprng = TEST_PRNG(&prng);
|
|
|
|
// create the attr
|
|
uint32_t wprng_ = wprng;
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
|
wbuf[j] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
|
}
|
|
lfsr_setattr(&lfs, path, a, wbuf, SIZE) => 0;
|
|
|
|
// update our sim
|
|
sim_prngs[x*M+a] = wprng;
|
|
|
|
// remove an attr?
|
|
} else if (op == 1) {
|
|
// choose a file
|
|
lfs_size_t x = TEST_PRNG(&prng) % N;
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
// choose an attr
|
|
uint8_t a = TEST_PRNG(&prng) % M;
|
|
|
|
// remove the attr
|
|
if (sim_prngs[x*M+a]) {
|
|
lfsr_removeattr(&lfs, path, a) => 0;
|
|
} else {
|
|
lfsr_removeattr(&lfs, path, a) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
// update our sim
|
|
sim_prngs[x*M+a] = 0;
|
|
|
|
// remove a file?
|
|
} else if (op == 2) {
|
|
// choose a file
|
|
lfs_size_t x = TEST_PRNG(&prng) % N;
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
|
|
// remove the file
|
|
lfsr_remove(&lfs, path) => 0;
|
|
|
|
// but recreate the file so we always have something to
|
|
// attach attrs to
|
|
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path,
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao"))
|
|
=> strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
|
|
// update our sim
|
|
memset(&sim_prngs[x*M], 0, M*sizeof(uint32_t));
|
|
|
|
// rename a file?
|
|
} else if (op == 3) {
|
|
// choose two files
|
|
lfs_size_t x = TEST_PRNG(&prng) % N;
|
|
lfs_size_t y = TEST_PRNG(&prng) % N;
|
|
char path[256];
|
|
char path_[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
sprintf(path_, "cat%03x", y);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
sprintf(path_, "armadillo%03x", y);
|
|
}
|
|
|
|
// rename the file
|
|
lfsr_rename(&lfs, path, path_) => 0;
|
|
|
|
if (x != y) {
|
|
// but recreate the file so we always have something to
|
|
// attach attrs to
|
|
|
|
// create a file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, path,
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "nyan", strlen("nyan"))
|
|
=> strlen("nyan");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create a dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
lfsr_mkdir(&lfs, path) => 0;
|
|
}
|
|
|
|
// update our sim
|
|
memcpy(&sim_prngs[y*M], &sim_prngs[x*M], M*sizeof(uint32_t));
|
|
memset(&sim_prngs[x*M], 0, M*sizeof(uint32_t));
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
for (lfs_size_t x = 0; x < N; x++) {
|
|
char path[256];
|
|
// file?
|
|
if (FILETYPE == 0) {
|
|
sprintf(path, "cat%03x", x);
|
|
// dir?
|
|
} else {
|
|
sprintf(path, "armadillo%03x", x);
|
|
}
|
|
|
|
// try getting each attr size
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
if (sim_prngs[x*M+a]) {
|
|
lfsr_sizeattr(&lfs, path, a) => SIZE;
|
|
} else {
|
|
lfsr_sizeattr(&lfs, path, a) => LFS_ERR_NOATTR;
|
|
}
|
|
}
|
|
// try reading each attr
|
|
for (uint16_t a = 0; a < M; a++) {
|
|
if (sim_prngs[x*M+a]) {
|
|
uint32_t wprng_ = sim_prngs[x*M+a];
|
|
uint8_t wbuf[SIZE];
|
|
for (lfs_size_t i = 0; i < SIZE; i++) {
|
|
wbuf[i] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
|
}
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf)) => SIZE;
|
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
|
} else {
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, path, a, rbuf, sizeof(rbuf))
|
|
=> LFS_ERR_NOATTR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// clean up sim/lfs
|
|
free(sim_prngs);
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
|
|
## Tests involving file-attached attrs
|
|
|
|
# test that file-attached attrs are read correctly
|
|
[cases.test_attrs_fattr_get]
|
|
defines.MODE = ['LFS_A_RDONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with these attrs
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size = -1;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size = -1;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size = -1;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = sizeof(a_buf),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = sizeof(b_buf),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = sizeof(c_buf),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
// did we read the attrs correctly?
|
|
if (MUTSIZE) {
|
|
assert(a_size == strlen(a));
|
|
}
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
if (MUTSIZE) {
|
|
assert(b_size == strlen(b));
|
|
}
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
if (MUTSIZE) {
|
|
assert(c_size == strlen(c));
|
|
}
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that truncate attrs will work
|
|
[cases.test_attrs_fattr_trunc]
|
|
defines.MODE = ['LFS_A_RDONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
defines.BUFSIZE = [1, 4, 7]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with these attrs, marking bufs so we can
|
|
// detect overflow
|
|
uint8_t a_buf[256];
|
|
a_buf[BUFSIZE] = '!';
|
|
lfs_ssize_t a_size = -1;
|
|
uint8_t b_buf[256];
|
|
b_buf[BUFSIZE] = '!';
|
|
lfs_ssize_t b_size = -1;
|
|
uint8_t c_buf[256];
|
|
c_buf[BUFSIZE] = '!';
|
|
lfs_ssize_t c_size = -1;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = BUFSIZE,
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = BUFSIZE,
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = BUFSIZE,
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
// did we read the attrs correctly? no overflow?
|
|
if (MUTSIZE) {
|
|
assert(a_size == BUFSIZE);
|
|
}
|
|
assert(memcmp(a_buf, a, BUFSIZE) == 0);
|
|
assert(a_buf[BUFSIZE] == '!');
|
|
if (MUTSIZE) {
|
|
assert(b_size == BUFSIZE);
|
|
}
|
|
assert(memcmp(b_buf, b, BUFSIZE) == 0);
|
|
assert(a_buf[BUFSIZE] == '!');
|
|
if (MUTSIZE) {
|
|
assert(c_size == BUFSIZE);
|
|
}
|
|
assert(memcmp(c_buf, c, BUFSIZE) == 0);
|
|
assert(a_buf[BUFSIZE] == '!');
|
|
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that missing attrs are read correctly
|
|
[cases.test_attrs_fattr_noattr]
|
|
defines.MODE = ['LFS_A_RDONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// try opening a file with missing attrs
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size = -1;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size = -1;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size = -1;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = sizeof(a_buf),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = sizeof(b_buf),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = sizeof(c_buf),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
// did we read the attrs correctly?
|
|
if (MUTSIZE) {
|
|
assert(a_size == LFS_ERR_NOATTR);
|
|
}
|
|
if (MUTSIZE) {
|
|
assert(b_size == LFS_ERR_NOATTR);
|
|
}
|
|
if (MUTSIZE) {
|
|
assert(c_size == LFS_ERR_NOATTR);
|
|
}
|
|
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# catch LFS_O_TRUNC mistakes, this has created issues before
|
|
[cases.test_attrs_fattr_otrunc]
|
|
defines.MODE = ['LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with these attrs
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size = -1;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size = -1;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size = -1;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = sizeof(a_buf),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = sizeof(b_buf),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = sizeof(c_buf),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat",
|
|
MODE | LFS_O_TRUNC, &filecfg) => 0;
|
|
|
|
// did we read the attrs correctly?
|
|
if (MUTSIZE) {
|
|
assert(a_size == strlen(a));
|
|
}
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
if (MUTSIZE) {
|
|
assert(b_size == strlen(b));
|
|
}
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
if (MUTSIZE) {
|
|
assert(c_size == strlen(c));
|
|
}
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# orphan files should zero attributes
|
|
[cases.test_attrs_fattr_orphan]
|
|
defines.MODE = ['LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// _don't_ create a file
|
|
|
|
// try opening a file with these attrs
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size = -1;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size = -1;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size = -1;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = sizeof(a_buf),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = sizeof(b_buf),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = sizeof(c_buf),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_t file;
|
|
lfsr_file_opencfg(&lfs, &file, "cat",
|
|
MODE | LFS_O_CREAT, &filecfg) => 0;
|
|
|
|
// did we read the attrs correctly?
|
|
if (MUTSIZE) {
|
|
assert(a_size == LFS_ERR_NOATTR);
|
|
}
|
|
if (MUTSIZE) {
|
|
assert(b_size == LFS_ERR_NOATTR);
|
|
}
|
|
if (MUTSIZE) {
|
|
assert(c_size == LFS_ERR_NOATTR);
|
|
}
|
|
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that file-attached attrs are written correctly
|
|
[cases.test_attrs_fattr_set]
|
|
defines.MODE = ['LFS_A_WRONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
|
|
// try opening a file with attrs
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(a_buf) : strlen(a),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(b_buf) : strlen(b),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(c_buf) : strlen(c),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
// set the attrs
|
|
memcpy(a_buf, a, strlen(a));
|
|
memcpy(b_buf, b, strlen(b));
|
|
memcpy(c_buf, c, strlen(c));
|
|
a_size = strlen(a);
|
|
b_size = strlen(b);
|
|
c_size = strlen(c);
|
|
|
|
// write and close our file to write the attrs out to disk
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that we can update existing attrs
|
|
[cases.test_attrs_fattr_update]
|
|
defines.MODE = ['LFS_A_WRONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with attrs
|
|
const char *a_ = "Four large eggs. One cup semi-sweet chocolate chips.";
|
|
const char *b_ = "Three slash four cup butter or margarine.";
|
|
const char *c_ = "One and two third cups granulated sugar.";
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(a_buf) : strlen(a_),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(b_buf) : strlen(b_),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(c_buf) : strlen(c_),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
if (MODE == LFS_A_RDWR && MUTSIZE) {
|
|
// did we read the attrs correctly?
|
|
assert(a_size == strlen(a));
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
assert(b_size == strlen(b));
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
assert(c_size == strlen(c));
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
// update the attrs with new values
|
|
memcpy(a_buf, a_, strlen(a_));
|
|
memcpy(b_buf, b_, strlen(b_));
|
|
memcpy(c_buf, c_, strlen(c_));
|
|
a_size = strlen(a_);
|
|
b_size = strlen(b_);
|
|
c_size = strlen(c_);
|
|
|
|
// write and close our file to write the attrs out to disk
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a_);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b_);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c_);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a_);
|
|
assert(memcmp(rbuf, a_, strlen(a_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b_);
|
|
assert(memcmp(rbuf, b_, strlen(b_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c_);
|
|
assert(memcmp(rbuf, c_, strlen(c_)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that we can remove attrs
|
|
[cases.test_attrs_fattr_remove]
|
|
defines.MODE = ['LFS_A_WRONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with attrs
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE)
|
|
? (lfs_ssize_t)sizeof(a_buf)
|
|
: LFS_ERR_NOATTR,
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE)
|
|
? (lfs_ssize_t)sizeof(b_buf)
|
|
: LFS_ERR_NOATTR,
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE)
|
|
? (lfs_ssize_t)sizeof(c_buf)
|
|
: LFS_ERR_NOATTR,
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
if (MODE == LFS_A_RDWR && MUTSIZE) {
|
|
// did we read the attrs correctly?
|
|
assert(a_size == strlen(a));
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
assert(b_size == strlen(b));
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
assert(c_size == strlen(c));
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
// mark the attrs as removed
|
|
a_size = LFS_ERR_NOATTR;
|
|
b_size = LFS_ERR_NOATTR;
|
|
c_size = LFS_ERR_NOATTR;
|
|
|
|
// write and close our file to write the attrs out to disk
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => LFS_ERR_NOATTR;
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => LFS_ERR_NOATTR;
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => LFS_ERR_NOATTR;
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that wronly attrs are not read from disk
|
|
[cases.test_attrs_fattr_wronly]
|
|
defines.MODE = ['LFS_A_WRONLY']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with new wronly attrs
|
|
const char *a_ = "Four large eggs. One cup semi-sweet chocolate chips.";
|
|
const char *b_ = "Three slash four cup butter or margarine.";
|
|
const char *c_ = "One and two third cups granulated sugar.";
|
|
uint8_t a_buf[256];
|
|
memcpy(a_buf, a_, strlen(a_));
|
|
lfs_ssize_t a_size = strlen(a_);
|
|
uint8_t b_buf[256];
|
|
memcpy(b_buf, b_, strlen(b_));
|
|
lfs_ssize_t b_size = strlen(b_);
|
|
uint8_t c_buf[256];
|
|
memcpy(c_buf, c_, strlen(c_));
|
|
lfs_ssize_t c_size = strlen(c_);
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(a_buf) : strlen(a_),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(b_buf) : strlen(b_),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(c_buf) : strlen(c_),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", LFS_O_RDWR, &filecfg) => 0;
|
|
|
|
// open should have had no effect on our wronly attrs
|
|
assert(a_size == strlen(a_));
|
|
assert(memcmp(a_buf, a_, strlen(a_)) == 0);
|
|
assert(b_size == strlen(b_));
|
|
assert(memcmp(b_buf, b_, strlen(b_)) == 0);
|
|
assert(c_size == strlen(c_));
|
|
assert(memcmp(c_buf, c_, strlen(c_)) == 0);
|
|
|
|
// write and close our file to write the attrs out to disk
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a_);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b_);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c_);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a_);
|
|
assert(memcmp(rbuf, a_, strlen(a_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b_);
|
|
assert(memcmp(rbuf, b_, strlen(b_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c_);
|
|
assert(memcmp(rbuf, c_, strlen(c_)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that rdonly attrs have no effect on disk
|
|
[cases.test_attrs_fattr_rdonly]
|
|
defines.MODE = ['LFS_A_RDONLY']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with rdonly attrs
|
|
const char *a_ = "Four large eggs. One cup semi-sweet chocolate chips.";
|
|
const char *b_ = "Three slash four cup butter or margarine.";
|
|
const char *c_ = "One and two third cups granulated sugar.";
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(a_buf) : strlen(a_),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(b_buf) : strlen(b_),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(c_buf) : strlen(c_),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", LFS_O_RDWR, &filecfg) => 0;
|
|
|
|
if (MUTSIZE) {
|
|
// did we read the attrs correctly?
|
|
assert(a_size == strlen(a));
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
assert(b_size == strlen(b));
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
assert(c_size == strlen(c));
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
// update the attrs with new values
|
|
memcpy(a_buf, a_, strlen(a_));
|
|
memcpy(b_buf, b_, strlen(b_));
|
|
memcpy(c_buf, c_, strlen(c_));
|
|
a_size = strlen(a_);
|
|
b_size = strlen(b_);
|
|
c_size = strlen(c_);
|
|
|
|
// write and close our file, this should have no effect on attrs
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that attrs are written correctly even if there are no file changes
|
|
[cases.test_attrs_fattr_noop]
|
|
defines.MODE = ['LFS_A_WRONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with attrs
|
|
const char *a_ = "Four large eggs. One cup semi-sweet chocolate chips.";
|
|
const char *b_ = "Three slash four cup butter or margarine.";
|
|
const char *c_ = "One and two third cups granulated sugar.";
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(a_buf) : strlen(a_),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(b_buf) : strlen(b_),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(c_buf) : strlen(c_),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
if (MODE == LFS_A_RDWR && MUTSIZE) {
|
|
// did we read the attrs correctly?
|
|
assert(a_size == strlen(a));
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
assert(b_size == strlen(b));
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
assert(c_size == strlen(c));
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
// update the attrs with new values
|
|
memcpy(a_buf, a_, strlen(a_));
|
|
memcpy(b_buf, b_, strlen(b_));
|
|
memcpy(c_buf, c_, strlen(c_));
|
|
a_size = strlen(a_);
|
|
b_size = strlen(b_);
|
|
c_size = strlen(c_);
|
|
|
|
// close our file without any data changes, this should still update
|
|
// our attrs!
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a_);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b_);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c_);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a_);
|
|
assert(memcmp(rbuf, a_, strlen(a_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b_);
|
|
assert(memcmp(rbuf, b_, strlen(b_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c_);
|
|
assert(memcmp(rbuf, c_, strlen(c_)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# test that lazy attrs aren't written _until_ there are file changes
|
|
[cases.test_attrs_fattr_lazy]
|
|
defines.MODE = ['LFS_A_WRONLY', 'LFS_A_RDWR']
|
|
defines.MUTSIZE = [false, true]
|
|
code = '''
|
|
lfs_t lfs;
|
|
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
|
|
// create a file
|
|
lfsr_file_t file;
|
|
lfsr_file_open(&lfs, &file, "cat", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfsr_file_write(&lfs, &file, "meow", strlen("meow")) => strlen("meow");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
// create some attrs
|
|
const char *a = "One 18.25 ounce package chocolate cake mix.";
|
|
lfsr_setattr(&lfs, "cat", 'a', a, strlen(a)) => 0;
|
|
const char *b = "One can prepared coconut pecan frosting.";
|
|
lfsr_setattr(&lfs, "cat", 'b', b, strlen(b)) => 0;
|
|
const char *c = "Three slash four cup vegetable oil.";
|
|
lfsr_setattr(&lfs, "cat", 'c', c, strlen(c)) => 0;
|
|
|
|
// try opening a file with attrs
|
|
const char *a_ = "Four large eggs. One cup semi-sweet chocolate chips.";
|
|
const char *b_ = "Three slash four cup butter or margarine.";
|
|
const char *c_ = "One and two third cups granulated sugar.";
|
|
uint8_t a_buf[256];
|
|
lfs_ssize_t a_size;
|
|
uint8_t b_buf[256];
|
|
lfs_ssize_t b_size;
|
|
uint8_t c_buf[256];
|
|
lfs_ssize_t c_size;
|
|
struct lfs_attr attrs[] = {
|
|
{
|
|
.type = 'a',
|
|
.flags = MODE | LFS_A_LAZY,
|
|
.buffer = a_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(a_buf) : strlen(a_),
|
|
.size = (MUTSIZE) ? &a_size : NULL,
|
|
},
|
|
{
|
|
.type = 'b',
|
|
.flags = MODE | LFS_A_LAZY,
|
|
.buffer = b_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(b_buf) : strlen(b_),
|
|
.size = (MUTSIZE) ? &b_size : NULL,
|
|
},
|
|
{
|
|
.type = 'c',
|
|
.flags = MODE | LFS_A_LAZY,
|
|
.buffer = c_buf,
|
|
.buffer_size = (MUTSIZE) ? sizeof(c_buf) : strlen(c_),
|
|
.size = (MUTSIZE) ? &c_size : NULL,
|
|
}
|
|
};
|
|
struct lfs_file_config filecfg = {
|
|
.attrs = attrs,
|
|
.attr_count = 3,
|
|
};
|
|
lfsr_file_opencfg(&lfs, &file, "cat", MODE, &filecfg) => 0;
|
|
|
|
if (MODE == LFS_A_RDWR && MUTSIZE) {
|
|
// did we read the attrs correctly?
|
|
assert(a_size == strlen(a));
|
|
assert(memcmp(a_buf, a, strlen(a)) == 0);
|
|
assert(b_size == strlen(b));
|
|
assert(memcmp(b_buf, b, strlen(b)) == 0);
|
|
assert(c_size == strlen(c));
|
|
assert(memcmp(c_buf, c, strlen(c)) == 0);
|
|
}
|
|
|
|
// update the attrs with new values
|
|
memcpy(a_buf, a_, strlen(a_));
|
|
memcpy(b_buf, b_, strlen(b_));
|
|
memcpy(c_buf, c_, strlen(c_));
|
|
a_size = strlen(a_);
|
|
b_size = strlen(b_);
|
|
c_size = strlen(c_);
|
|
|
|
// sync our file without any data changes, this should have no
|
|
// effect because our attrs are lazy
|
|
lfsr_file_sync(&lfs, &file) => 0;
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a);
|
|
assert(memcmp(rbuf, a, strlen(a)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b);
|
|
assert(memcmp(rbuf, b, strlen(b)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c);
|
|
assert(memcmp(rbuf, c, strlen(c)) == 0);
|
|
|
|
// now write some data and close our file, this should update
|
|
// the attrs now
|
|
lfsr_file_write(&lfs, &file, "miao", strlen("miao")) => strlen("miao");
|
|
lfsr_file_close(&lfs, &file) => 0;
|
|
|
|
for (int remount = 0; remount < 2; remount++) {
|
|
// remount?
|
|
if (remount) {
|
|
lfsr_unmount(&lfs) => 0;
|
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
|
}
|
|
|
|
// try getting the attr sizes
|
|
lfsr_sizeattr(&lfs, "cat", 'a') => strlen(a_);
|
|
lfsr_sizeattr(&lfs, "cat", 'b') => strlen(b_);
|
|
lfsr_sizeattr(&lfs, "cat", 'c') => strlen(c_);
|
|
// try reading the attrs
|
|
uint8_t rbuf[256];
|
|
lfsr_getattr(&lfs, "cat", 'a', rbuf, sizeof(rbuf)) => strlen(a_);
|
|
assert(memcmp(rbuf, a_, strlen(a_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'b', rbuf, sizeof(rbuf)) => strlen(b_);
|
|
assert(memcmp(rbuf, b_, strlen(b_)) == 0);
|
|
lfsr_getattr(&lfs, "cat", 'c', rbuf, sizeof(rbuf)) => strlen(c_);
|
|
assert(memcmp(rbuf, c_, strlen(c_)) == 0);
|
|
}
|
|
|
|
lfsr_unmount(&lfs) => 0;
|
|
'''
|
|
|
|
# TODO
|
|
#[cases.test_attrs_fattr_all]
|
|
#[cases.test_attrs_fattr_many]
|
|
#[cases.test_attrs_fattr_many_many]
|
|
#[cases.test_attrs_fattr_fuzz]
|
|
#[cases.test_attrs_fattr_fuzz_fuzz]
|
|
|
|
#[cases.test_attrs_fattr_broadcast]
|
|
#[cases.test_attrs_fattr_remove_broadcast]
|
|
#[cases.test_attrs_fattr_setattr_broadcast]
|
|
#[cases.test_attrs_fattr_removeattr_broadcast]
|
|
#[cases.test_attrs_fattr_wronly_broadcast]
|
|
#[cases.test_attrs_fattr_rdonly_broadcast]
|
|
#[cases.test_attrs_fattr_desync_broadcast]
|
|
|
|
#[cases.test_attrs_fattr_resync]
|
|
#[cases.test_attrs_fattr_zombie_resync] TODO do we test file zombie resync?
|
|
|
|
#[cases.test_attrs_fattr_pl] ?
|
|
#[cases.test_attrs_fattr_orphan] ?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cases.test_attrs_get_set]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "hello") => 0;
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
# lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# uint8_t buffer[1024];
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# lfs_setattr(&lfs, "hello", 'A', "aaaa", 4) => 0;
|
|
# lfs_setattr(&lfs, "hello", 'B', "bbbbbb", 6) => 0;
|
|
# lfs_setattr(&lfs, "hello", 'C', "ccccc", 5) => 0;
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 6;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "bbbbbb", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "hello", 'B', "", 0) => 0;
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 0;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_removeattr(&lfs, "hello", 'B') => 0;
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => LFS_ERR_NOATTR;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "hello", 'B', "dddddd", 6) => 0;
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 6;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "dddddd", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "hello", 'B', "eee", 3) => 0;
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 3;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "eee\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "hello", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC;
|
|
# lfs_setattr(&lfs, "hello", 'B', "fffffffff", 9) => 0;
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 9;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
#
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "hello", 'B', buffer+4, 9) => 9;
|
|
# lfs_getattr(&lfs, "hello", 'C', buffer+13, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "fffffffff", 9) => 0;
|
|
# memcmp(buffer+13, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0;
|
|
# lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello");
|
|
# memcmp(buffer, "hello", strlen("hello")) => 0;
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_attrs_get_set_root]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "hello") => 0;
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
# lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# uint8_t buffer[1024];
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# lfs_setattr(&lfs, "/", 'A', "aaaa", 4) => 0;
|
|
# lfs_setattr(&lfs, "/", 'B', "bbbbbb", 6) => 0;
|
|
# lfs_setattr(&lfs, "/", 'C', "ccccc", 5) => 0;
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 6) => 6;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "bbbbbb", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "/", 'B', "", 0) => 0;
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 6) => 0;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_removeattr(&lfs, "/", 'B') => 0;
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 6) => LFS_ERR_NOATTR;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "/", 'B', "dddddd", 6) => 0;
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 6) => 6;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "dddddd", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "/", 'B', "eee", 3) => 0;
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 6) => 3;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "eee\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_setattr(&lfs, "/", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC;
|
|
# lfs_setattr(&lfs, "/", 'B', "fffffffff", 9) => 0;
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 6) => 9;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# lfs_getattr(&lfs, "/", 'A', buffer, 4) => 4;
|
|
# lfs_getattr(&lfs, "/", 'B', buffer+4, 9) => 9;
|
|
# lfs_getattr(&lfs, "/", 'C', buffer+13, 5) => 5;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "fffffffff", 9) => 0;
|
|
# memcmp(buffer+13, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0;
|
|
# lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello");
|
|
# memcmp(buffer, "hello", strlen("hello")) => 0;
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_attrs_get_set_file]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "hello") => 0;
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
# lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# uint8_t buffer[1024];
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# struct lfs_attr attrs1[] = {
|
|
# {'A', buffer, 4},
|
|
# {'B', buffer+4, 6},
|
|
# {'C', buffer+10, 5},
|
|
# };
|
|
# struct lfs_file_config cfg1 = {.attrs=attrs1, .attr_count=3};
|
|
#
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
# memcpy(buffer, "aaaa", 4);
|
|
# memcpy(buffer+4, "bbbbbb", 6);
|
|
# memcpy(buffer+10, "ccccc", 5);
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memset(buffer, 0, 15);
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "bbbbbb", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# attrs1[1].size = 0;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memset(buffer, 0, 15);
|
|
# attrs1[1].size = 6;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# attrs1[1].size = 6;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
# memcpy(buffer+4, "dddddd", 6);
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memset(buffer, 0, 15);
|
|
# attrs1[1].size = 6;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "dddddd", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# attrs1[1].size = 3;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
# memcpy(buffer+4, "eee", 3);
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memset(buffer, 0, 15);
|
|
# attrs1[1].size = 6;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "eee\0\0\0", 6) => 0;
|
|
# memcmp(buffer+10, "ccccc", 5) => 0;
|
|
#
|
|
# attrs1[0].size = LFS_ATTR_MAX+1;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1)
|
|
# => LFS_ERR_NOSPC;
|
|
#
|
|
# struct lfs_attr attrs2[] = {
|
|
# {'A', buffer, 4},
|
|
# {'B', buffer+4, 9},
|
|
# {'C', buffer+13, 5},
|
|
# };
|
|
# struct lfs_file_config cfg2 = {.attrs=attrs2, .attr_count=3};
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDWR, &cfg2) => 0;
|
|
# memcpy(buffer+4, "fffffffff", 9);
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# attrs1[0].size = 4;
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
#
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# struct lfs_attr attrs3[] = {
|
|
# {'A', buffer, 4},
|
|
# {'B', buffer+4, 9},
|
|
# {'C', buffer+13, 5},
|
|
# };
|
|
# struct lfs_file_config cfg3 = {.attrs=attrs3, .attr_count=3};
|
|
#
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg3) => 0;
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# memcmp(buffer, "aaaa", 4) => 0;
|
|
# memcmp(buffer+4, "fffffffff", 9) => 0;
|
|
# memcmp(buffer+13, "ccccc", 5) => 0;
|
|
#
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0;
|
|
# lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello");
|
|
# memcmp(buffer, "hello", strlen("hello")) => 0;
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|
|
#
|
|
#[cases.test_attrs_deferred_file]
|
|
#code = '''
|
|
# lfs_t lfs;
|
|
# lfs_format(&lfs, cfg) => 0;
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_mkdir(&lfs, "hello") => 0;
|
|
# lfs_file_t file;
|
|
# lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
# lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
# lfs_file_close(&lfs, &file);
|
|
# lfs_unmount(&lfs) => 0;
|
|
#
|
|
# lfs_mount(&lfs, cfg) => 0;
|
|
# lfs_setattr(&lfs, "hello/hello", 'B', "fffffffff", 9) => 0;
|
|
# lfs_setattr(&lfs, "hello/hello", 'C', "ccccc", 5) => 0;
|
|
#
|
|
# uint8_t buffer[1024];
|
|
# memset(buffer, 0, sizeof(buffer));
|
|
# struct lfs_attr attrs1[] = {
|
|
# {'B', "gggg", 4},
|
|
# {'C', "", 0},
|
|
# {'D', "hhhh", 4},
|
|
# };
|
|
# struct lfs_file_config cfg1 = {.attrs=attrs1, .attr_count=3};
|
|
#
|
|
# lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
#
|
|
# lfs_getattr(&lfs, "hello/hello", 'B', buffer, 9) => 9;
|
|
# lfs_getattr(&lfs, "hello/hello", 'C', buffer+9, 9) => 5;
|
|
# lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => LFS_ERR_NOATTR;
|
|
# memcmp(buffer, "fffffffff", 9) => 0;
|
|
# memcmp(buffer+9, "ccccc\0\0\0\0", 9) => 0;
|
|
# memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) => 0;
|
|
#
|
|
# lfs_file_sync(&lfs, &file) => 0;
|
|
# lfs_getattr(&lfs, "hello/hello", 'B', buffer, 9) => 4;
|
|
# lfs_getattr(&lfs, "hello/hello", 'C', buffer+9, 9) => 0;
|
|
# lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => 4;
|
|
# memcmp(buffer, "gggg\0\0\0\0\0", 9) => 0;
|
|
# memcmp(buffer+9, "\0\0\0\0\0\0\0\0\0", 9) => 0;
|
|
# memcmp(buffer+18, "hhhh\0\0\0\0\0", 9) => 0;
|
|
#
|
|
# lfs_file_close(&lfs, &file) => 0;
|
|
# lfs_unmount(&lfs) => 0;
|
|
#'''
|