Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2020-01-03 03:36:53 +0300
committerChristopher Haster <chaster@utexas.edu>2020-01-03 03:36:53 +0300
commiteeaf536ecabbc9a3813d068e367dbe7897e60bcf (patch)
treed856ea9ba7b0cae5b0601462a225e961a77e466f /scripts
parent53d2b02f2a113326611b24c069d6098e9cdf53c4 (diff)
Replaced emubd with rambd and filebd
The idea behind emubd (file per block), was neat, but doesn't add much value over a block device that just operates on a single linear file (other than adding a significant amount of overhead). Initially it helped with debugging, but when the metadata format became more complex in v2, most debugging ends up going through the debug.py script anyways. Aside from being simpler, moving to filebd means it is also possible to mount disk images directly. Also introduced rambd, which keeps the disk contents in RAM. This is very useful for testing where it increases the speed _significantly_. - test_dirs w/ filebd - 0m7.170s - test_dirs w/ rambd - 0m0.966s These follow the emubd model of using the lfs_config for geometry. I'm not convinced this is the best approach, but it gets the job done. I've also added lfs_ramdb_createcfg to add additional config similar to lfs_file_opencfg. This is useful for specifying erase_value, which tells the block device to simulate erases similar to flash devices. Note that the default (-1) meets the minimum block device requirements and is the most performant.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/test_.py101
1 files changed, 67 insertions, 34 deletions
diff --git a/scripts/test_.py b/scripts/test_.py
index 5a481e4..27002d9 100755
--- a/scripts/test_.py
+++ b/scripts/test_.py
@@ -15,7 +15,6 @@ import subprocess as sp
import base64
import sys
import copy
-import shutil
import shlex
TESTDIR = 'tests_'
@@ -40,8 +39,10 @@ $(foreach target,$(SRC),$(eval $(FLATTEN)))
GLOBALS = """
//////////////// AUTOGENERATED TEST ////////////////
#include "lfs.h"
-#include "emubd/lfs_emubd.h"
+#include "filebd/lfs_filebd.h"
+#include "rambd/lfs_rambd.h"
#include <stdio.h>
+const char *LFS_DISK = NULL;
"""
DEFINES = {
"LFS_READ_SIZE": 16,
@@ -51,23 +52,25 @@ DEFINES = {
"LFS_BLOCK_CYCLES": 1024,
"LFS_CACHE_SIZE": "(64 % LFS_PROG_SIZE == 0 ? 64 : LFS_PROG_SIZE)",
"LFS_LOOKAHEAD_SIZE": 16,
+ "LFS_ERASE_VALUE": 0xff,
}
PROLOGUE = """
// prologue
__attribute__((unused)) lfs_t lfs;
- __attribute__((unused)) lfs_emubd_t bd;
+ __attribute__((unused)) lfs_filebd_t filebd;
+ __attribute__((unused)) lfs_rambd_t rambd;
__attribute__((unused)) lfs_file_t file;
__attribute__((unused)) lfs_dir_t dir;
__attribute__((unused)) struct lfs_info info;
__attribute__((unused)) uint8_t buffer[1024];
__attribute__((unused)) char path[1024];
-
+
__attribute__((unused)) const struct lfs_config cfg = {
- .context = &bd,
- .read = &lfs_emubd_read,
- .prog = &lfs_emubd_prog,
- .erase = &lfs_emubd_erase,
- .sync = &lfs_emubd_sync,
+ .context = LFS_DISK ? (void*)&filebd : (void*)&rambd,
+ .read = LFS_DISK ? &lfs_filebd_read : &lfs_rambd_read,
+ .prog = LFS_DISK ? &lfs_filebd_prog : &lfs_rambd_prog,
+ .erase = LFS_DISK ? &lfs_filebd_erase : &lfs_rambd_erase,
+ .sync = LFS_DISK ? &lfs_filebd_sync : &lfs_rambd_sync,
.read_size = LFS_READ_SIZE,
.prog_size = LFS_PROG_SIZE,
@@ -78,11 +81,26 @@ PROLOGUE = """
.lookahead_size = LFS_LOOKAHEAD_SIZE,
};
- lfs_emubd_create(&cfg, "blocks");
+ __attribute__((unused)) const struct lfs_filebd_config filecfg = {
+ .erase_value = LFS_ERASE_VALUE,
+ };
+ __attribute__((unused)) const struct lfs_rambd_config ramcfg = {
+ .erase_value = LFS_ERASE_VALUE,
+ };
+
+ if (LFS_DISK) {
+ lfs_filebd_createcfg(&cfg, LFS_DISK, &filecfg);
+ } else {
+ lfs_rambd_createcfg(&cfg, &ramcfg);
+ }
"""
EPILOGUE = """
// epilogue
- lfs_emubd_destroy(&cfg);
+ if (LFS_DISK) {
+ lfs_filebd_destroy(&cfg);
+ } else {
+ lfs_rambd_destroy(&cfg);
+ }
"""
PASS = '\033[32m✓\033[0m'
FAIL = '\033[31m✗\033[0m'
@@ -133,7 +151,8 @@ class TestCase:
f.write(') {\n')
for k, v in sorted(self.defines.items()):
- f.write(4*' '+'#define %s %s\n' % (k, v))
+ if k not in self.suite.defines:
+ f.write(4*' '+'#define %s %s\n' % (k, v))
f.write(PROLOGUE)
f.write('\n')
@@ -148,27 +167,34 @@ class TestCase:
f.write('\n')
for k, v in sorted(self.defines.items()):
- f.write(4*' '+'#undef %s\n' % k)
+ if k not in self.suite.defines:
+ f.write(4*' '+'#undef %s\n' % k)
f.write('}\n')
def test(self, exec=[], persist=False, gdb=False, failure=None, **args):
- # clear disk first
- if not persist:
- shutil.rmtree('blocks', True)
-
# build command
cmd = exec + ['./%s.test' % self.suite.path,
repr(self.caseno), repr(self.permno)]
+ if persist:
+ cmd.append(self.suite.path + '.test.disk')
# failed? drop into debugger?
if gdb and failure:
- cmd = (['gdb', '-ex', 'r'
- ] + (['-ex', 'up'] if failure.assert_ else []) + [
- '--args'] + cmd)
+ ncmd = ['gdb']
+ if gdb == 'assert':
+ ncmd.extend(['-ex', 'r'])
+ if failure.assert_:
+ ncmd.extend(['-ex', 'up'])
+ elif gdb == 'start':
+ ncmd.extend([
+ '-ex', 'b %s:%d' % (self.suite.path, self.lineno),
+ '-ex', 'r'])
+ ncmd.extend(['--args'] + cmd)
+
if args.get('verbose', False):
- print(' '.join(shlex.quote(c) for c in cmd))
- sys.exit(sp.call(cmd))
+ print(' '.join(shlex.quote(c) for c in ncmd))
+ sys.exit(sp.call(ncmd))
# run test case!
stdout = []
@@ -231,22 +257,27 @@ class ReentrantTestCase(TestCase):
if not self.reentrant:
return
- for cycles in it.count(1):
- npersist = persist or cycles > 1
+ # clear disk first?
+ if not persist:
+ try:
+ os.remove(self.suite.path + '.test.disk')
+ except FileNotFoundError:
+ pass
+ for cycles in it.count(1):
# exact cycle we should drop into debugger?
if gdb and failure and failure.cycleno == cycles:
- return super().test(exec=exec, persist=npersist,
+ return super().test(exec=exec, persist=True,
gdb=gdb, failure=failure, **args)
- # run tests, but kill the program after lfs_emubd_prog/erase has
+ # run tests, but kill the program after prog/erase has
# been hit n cycles. We exit with a special return code if the
# program has not finished, since this isn't a test failure.
nexec = exec + [
'gdb', '-batch-silent',
'-ex', 'handle all nostop',
- '-ex', 'b lfs_emubd_prog',
- '-ex', 'b lfs_emubd_erase',
+ '-ex', 'b lfs_filebd_prog',
+ '-ex', 'b lfs_filebd_erase',
'-ex', 'r',
] + cycles*['-ex', 'c'] + [
'-ex', 'q '
@@ -255,7 +286,7 @@ class ReentrantTestCase(TestCase):
'33',
'--args']
try:
- return super().test(exec=nexec, persist=npersist, **args)
+ return super().test(exec=nexec, persist=True, **args)
except TestFailure as nfailure:
if nfailure.returncode == 33:
continue
@@ -370,10 +401,11 @@ class TestSuite:
f.write('\n')
f.write('int main(int argc, char **argv) {\n')
- f.write(4*' '+'int case_ = (argc == 3) ? atoi(argv[1]) : 0;\n')
- f.write(4*' '+'int perm = (argc == 3) ? atoi(argv[2]) : 0;\n')
+ f.write(4*' '+'int case_ = (argc >= 3) ? atoi(argv[1]) : 0;\n')
+ f.write(4*' '+'int perm = (argc >= 3) ? atoi(argv[2]) : 0;\n')
+ f.write(4*' '+'LFS_DISK = (argc >= 4) ? argv[3] : NULL;\n')
for perm in self.perms:
- f.write(4*' '+'if (argc != 3 || '
+ f.write(4*' '+'if (argc < 3 || '
'(case_ == %d && perm == %d)) { ' % (
perm.caseno, perm.permno))
f.write('test_case%d(' % perm.caseno)
@@ -590,8 +622,9 @@ if __name__ == "__main__":
help="Run all tests instead of stopping on first error. Useful for CI.")
parser.add_argument('-p', '--persist', action='store_true',
help="Don't reset the tests disk before each test.")
- parser.add_argument('-g', '--gdb', action='store_true',
- help="Drop into gdb on failure.")
+ parser.add_argument('-g', '--gdb', choices=['init', 'start', 'assert'],
+ nargs='?', const='assert',
+ help="Drop into gdb on test failure.")
parser.add_argument('--valgrind', action='store_true',
help="Run non-leaky tests under valgrind to check for memory leaks.")
parser.add_argument('--reentrant', action='store_true',