Refactored a handful of things in tests
- Now test errors have correct line reporting! #line directives
are passed to the compiler that reference the relevant line in
the test case shell script.
--- Multi-block directory ---
./tests/test_dirs.sh:109: assert failed with 0, expected 1
lfs_unmount(&lfs) => 1
- Cleaned up the number of implicit global variables provided to
tests. A lot of these were infrequently used and made it difficult
to remember what was provided. This isn't an MCU, so there's very
little cost to stack allocations when needed.
- Minimized the results.py script (previously stats.py) output to
match minimization of test output.
This commit is contained in:
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import re
|
||||
|
||||
def main():
|
||||
with open('blocks/.config') as file:
|
||||
read_size, prog_size, block_size, block_count = (
|
||||
struct.unpack('<LLLL', file.read()))
|
||||
|
||||
real_size = sum(
|
||||
os.path.getsize(os.path.join('blocks', f))
|
||||
for f in os.listdir('blocks') if re.match('\d+', f))
|
||||
|
||||
with open('blocks/.stats') as file:
|
||||
read_count, prog_count, erase_count = (
|
||||
struct.unpack('<QQQ', file.read()))
|
||||
|
||||
runtime = time.time() - os.stat('blocks').st_ctime
|
||||
|
||||
print 'results: %dB %dB %dB %.3fs' % (
|
||||
read_count, prog_count, erase_count, runtime)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(*sys.argv[1:])
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import re
|
||||
|
||||
def main():
|
||||
with open('blocks/.config') as file:
|
||||
s = struct.unpack('<LLLL', file.read())
|
||||
print 'read_size: %d' % s[0]
|
||||
print 'prog_size: %d' % s[1]
|
||||
print 'block_size: %d' % s[2]
|
||||
print 'block_size: %d' % s[3]
|
||||
|
||||
print 'real_size: %d' % sum(
|
||||
os.path.getsize(os.path.join('blocks', f))
|
||||
for f in os.listdir('blocks') if re.match('\d+', f))
|
||||
|
||||
with open('blocks/.stats') as file:
|
||||
s = struct.unpack('<QQQ', file.read())
|
||||
print 'read_count: %d' % s[0]
|
||||
print 'prog_count: %d' % s[1]
|
||||
print 'erase_count: %d' % s[2]
|
||||
|
||||
print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(*sys.argv[1:])
|
||||
+12
-15
@@ -10,14 +10,18 @@
|
||||
static void test_assert(const char *file, unsigned line,
|
||||
const char *s, uintmax_t v, uintmax_t e) {{
|
||||
if (v != e) {{
|
||||
fprintf(stderr, "\033[31m%s:%u: assert %s failed with %jd, "
|
||||
"expected %jd\033[0m\n", file, line, s, v, e);
|
||||
fprintf(stderr, "\033[97m%s:%u: \033[91m"
|
||||
"assert failed with %jd, expected %jd\033[0m\n"
|
||||
" %s\n\n", file, line, v, e, s);
|
||||
exit(-2);
|
||||
}}
|
||||
}}
|
||||
|
||||
#define test_assert(s, v, e) test_assert(__FILE__, __LINE__, s, v, e)
|
||||
#define test_assert(v, e) \
|
||||
test_assert(__FILE__, __LINE__, #v " => " #e, v, e)
|
||||
|
||||
// implicit variable for asserts
|
||||
uintmax_t test;
|
||||
|
||||
// utility functions for traversals
|
||||
static int __attribute__((used)) test_count(void *p, lfs_block_t b) {{
|
||||
@@ -27,23 +31,17 @@ static int __attribute__((used)) test_count(void *p, lfs_block_t b) {{
|
||||
return 0;
|
||||
}}
|
||||
|
||||
|
||||
// lfs declarations
|
||||
lfs_t lfs;
|
||||
lfs_emubd_t bd;
|
||||
lfs_file_t file[4];
|
||||
lfs_dir_t dir[4];
|
||||
// other declarations for convenience
|
||||
lfs_file_t file;
|
||||
lfs_dir_t dir;
|
||||
struct lfs_info info;
|
||||
|
||||
uint8_t buffer[1024];
|
||||
uint8_t wbuffer[1024];
|
||||
uint8_t rbuffer[1024];
|
||||
lfs_size_t size;
|
||||
lfs_size_t wsize;
|
||||
lfs_size_t rsize;
|
||||
|
||||
uintmax_t test;
|
||||
char path[1024];
|
||||
|
||||
// test configuration options
|
||||
#ifndef LFS_READ_SIZE
|
||||
#define LFS_READ_SIZE 16
|
||||
#endif
|
||||
@@ -94,6 +92,5 @@ int main(void) {{
|
||||
lfs_emubd_create(&cfg, "blocks");
|
||||
|
||||
{tests}
|
||||
|
||||
lfs_emubd_destroy(&cfg);
|
||||
}}
|
||||
|
||||
+36
-16
@@ -5,24 +5,36 @@ import sys
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
||||
def generate(test):
|
||||
with open("scripts/template.fmt") as file:
|
||||
template = file.read()
|
||||
|
||||
haslines = 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ
|
||||
|
||||
lines = []
|
||||
for line in re.split('(?<=(?:.;| [{}]))\n', test.read()):
|
||||
match = re.match('(?: *\n)*( *)(.*)=>(.*);', line, re.DOTALL | re.MULTILINE)
|
||||
for offset, line in enumerate(
|
||||
re.split('(?<=(?:.;| [{}]))\n', test.read())):
|
||||
match = re.match('((?: *\n)*)( *)(.*)=>(.*);',
|
||||
line, re.DOTALL | re.MULTILINE)
|
||||
if match:
|
||||
tab, test, expect = match.groups()
|
||||
lines.append(tab+'test = {test};'.format(test=test.strip()))
|
||||
lines.append(tab+'test_assert("{name}", test, {expect});'.format(
|
||||
name = re.match('\w*', test.strip()).group(),
|
||||
expect = expect.strip()))
|
||||
preface, tab, test, expect = match.groups()
|
||||
lines.extend(['']*preface.count('\n'))
|
||||
lines.append(tab+'test_assert({test}, {expect});'.format(
|
||||
test=test.strip(), expect=expect.strip()))
|
||||
else:
|
||||
lines.append(line)
|
||||
|
||||
# Create test file
|
||||
with open('test.c', 'w') as file:
|
||||
if 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ:
|
||||
lines.insert(0, '#line %d "%s"' % (
|
||||
int(os.environ['TEST_LINE']) + 1,
|
||||
os.environ['TEST_FILE']))
|
||||
lines.append('#line %d "test.c"' % (
|
||||
template[:template.find('{tests}')].count('\n')
|
||||
+ len(lines) + 2))
|
||||
|
||||
file.write(template.format(tests='\n'.join(lines)))
|
||||
|
||||
# Remove build artifacts to force rebuild
|
||||
@@ -44,18 +56,26 @@ def execute():
|
||||
subprocess.check_call(["./lfs"])
|
||||
|
||||
def main(test=None):
|
||||
if test and not test.startswith('-'):
|
||||
with open(test) as file:
|
||||
generate(file)
|
||||
else:
|
||||
generate(sys.stdin)
|
||||
try:
|
||||
if test and not test.startswith('-'):
|
||||
with open(test) as file:
|
||||
generate(file)
|
||||
else:
|
||||
generate(sys.stdin)
|
||||
|
||||
compile()
|
||||
compile()
|
||||
|
||||
if test == '-s':
|
||||
sys.exit(1)
|
||||
if test == '-s':
|
||||
sys.exit(1)
|
||||
|
||||
execute()
|
||||
execute()
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
# Python stack trace is counterproductive, just exit
|
||||
sys.exit(2)
|
||||
except KeyboardInterrupt:
|
||||
# Python stack trace is counterproductive, just exit
|
||||
sys.exit(3)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(*sys.argv[1:])
|
||||
|
||||
Reference in New Issue
Block a user