2020-01-13 04:21:09 +00:00
|
|
|
[[case]] # set/get attribute
|
|
|
|
code = '''
|
|
|
|
lfs_format(&lfs, &cfg) => 0;
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
lfs_mkdir(&lfs, "hello") => 0;
|
|
|
|
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
|
|
lfs_file_close(&lfs, &file);
|
|
|
|
lfs_unmount(&lfs) => 0;
|
|
|
|
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
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;
|
|
|
|
'''
|
|
|
|
|
|
|
|
[[case]] # set/get root attribute
|
|
|
|
code = '''
|
|
|
|
lfs_format(&lfs, &cfg) => 0;
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
lfs_mkdir(&lfs, "hello") => 0;
|
|
|
|
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
|
|
lfs_file_close(&lfs, &file);
|
|
|
|
lfs_unmount(&lfs) => 0;
|
|
|
|
|
Restructured block devices again for better test exploitation
Also finished migrating tests with test_relocations and test_exhaustion.
The issue I was running into when migrating these tests was a lack of
flexibility with what you could do with the block devices. It was
possible to hack in some hooks for things like bad blocks and power
loss, but it wasn't clean or easily extendable.
The solution here was to just put all of these test extensions into a
third block device, testbd, that uses the other two example block
devices internally.
testbd has several useful features for testing. Note this makes it a
pretty terrible block device _example_ since these hooks look more
complicated than a block device needs to be.
- testbd can simulate different erase values, supporting 1s, 0s, other byte
patterns, or no erases at all (which can cause surprising bugs). This
actually depends on the simulated erase values in ramdb and filebd.
I did try to move this out of rambd/filebd, but it's not possible to
simulate erases in testbd without buffering entire blocks and creating
an excessive amount of extra write operations.
- testbd also helps simulate power-loss by containing a "power cycles"
counter that is decremented every write operation until it calls exit.
This is notably faster than the previous gdb approach, which is
valuable since the reentrant tests tend to take a while to resolve.
- testbd also tracks wear, which can be manually set and read. This is
very useful for testing things like bad block handling, wear leveling,
or even changing the effective size of the block device at runtime.
2020-01-16 12:30:40 +00:00
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
2020-01-13 04:21:09 +00:00
|
|
|
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;
|
|
|
|
'''
|
|
|
|
|
|
|
|
[[case]] # set/get file attribute
|
|
|
|
code = '''
|
|
|
|
lfs_format(&lfs, &cfg) => 0;
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
lfs_mkdir(&lfs, "hello") => 0;
|
|
|
|
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
|
|
lfs_file_close(&lfs, &file);
|
|
|
|
lfs_unmount(&lfs) => 0;
|
|
|
|
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
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;
|
|
|
|
'''
|
|
|
|
|
|
|
|
[[case]] # deferred file attributes
|
|
|
|
code = '''
|
|
|
|
lfs_format(&lfs, &cfg) => 0;
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
lfs_mkdir(&lfs, "hello") => 0;
|
|
|
|
lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
|
|
|
|
lfs_file_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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
'''
|