9980323e3f
After running into issues with LFS_A_CREAT/EXCL in file-attached custom
attributes, we're left in a really weird place:
- None of lfs_setattr's flags are valid in lfs_attr
- None of lfs_attr's flags are valid in lfs_setattr
I also started thinking about the actual use case for LFS_A_CREAT/EXCL,
and it's really not clear.
littlefs really doesn't care about interprocess communication the same
way POSIX/other filesystem APIs do. We can always rely on integration
layers wrapping up multiple operations in a single mutex, so offering
flexible creation semantics has diminished value. LFS_A_CREAT and
LFS_A_EXCL can both be emulated by calling lfsr_getattr first and
checking its return value.
Thinking ahead to the hypothetical lfsr_set API. The main purpose of
lfsr_set is to provide an API that's easier to use but less powerful
than lfsr_file_open. And adding a flags argument seems to run counter to
that.
For example, if you saw this code with no knowledge of littlefs:
lfsr_setattr(&lfs, "cat", 'a', "meow", 4, 0);
You would probably be surprised that it returns LFS_ERR_NOENT without
additional flags.
I realize Linux sidesteps this with XATTR_CREATE/REPLACE by making 0
default to implicitly creating, but I didn't want to introduce
inconsistent flag behavior like this unless I had to.
---
So for now dropping LFS_A_CREAT/EXCL and flags argument to lfsr_setattr.
Code savings minimal, this was mostly for API ergonomics:
code stack
before: 38104 2624
after: 38084 (-0.1%) 2624 (+0.0%)
2709 lines
86 KiB
TOML
2709 lines
86 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;
|
|
'''
|
|
|
|
# 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_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;
|
|
#'''
|