Added a rudimentary test framework

Tests can be found in 'tests/test_blah.sh'
Tests can be run with 'make test'
This commit is contained in:
Christopher Haster
2017-03-25 17:02:16 -05:00
parent 84a57642e5
commit afa4ad8254
12 changed files with 260 additions and 294 deletions

30
tests/stats.py Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python
import struct
import sys
import time
import os
import re
def main():
with open('blocks/info') as file:
s = struct.unpack('<LLL4xQ', file.read())
print 'read_size: %d' % s[0]
print 'prog_size: %d' % s[1]
print 'erase_size: %d' % s[2]
print 'total_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))
print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime)
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]
if __name__ == "__main__":
main(*sys.argv[1:])

45
tests/template.fmt Normal file
View File

@@ -0,0 +1,45 @@
/// AUTOGENERATED TEST ///
#include "lfs.h"
#include "emubd/lfs_emubd.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// test stuff
void test_log(const char *s, uintmax_t v) {{
printf("%s: %jd\n", s, v);
}}
void test_assert(const char *s, uintmax_t v, uintmax_t e) {{
test_log(s, v);
if (v != e) {{
printf("\033[31massert %s failed, expected %jd\033[0m\n", s, e);
exit(-2);
}}
}}
// lfs declarations
lfs_t lfs;
lfs_emubd_t bd;
lfs_file_t file[4];
lfs_dir_t dir[4];
struct lfs_bd_info info;
struct lfs_bd_stats stats;
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 res;
int main() {{
lfs_emubd_create(&bd, "blocks");
{tests}
lfs_emubd_destroy(&bd);
}}

46
tests/test.py Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env python
import re
import sys
import subprocess
import os
def generate(test):
with open("tests/template.fmt") as file:
template = file.read()
lines = []
for line in test:
if '=>' in line:
test, expect = line.strip().strip(';').split('=>')
lines.append('res = {test};'.format(test=test.strip()))
lines.append('test_assert("{name}", res, {expect});'.format(
name = re.match('\w*', test.strip()).group(),
expect = expect.strip()))
else:
lines.append(line.strip())
with open('test.c', 'w') as file:
file.write(template.format(tests='\n'.join(4*' ' + l for l in lines)))
def compile():
os.environ['DEBUG'] = '1'
os.environ['CFLAGS'] = '-Werror'
subprocess.check_call(['make', '--no-print-directory', '-s'], env=os.environ)
def execute():
subprocess.check_call(["./lfs"])
def main(test=None):
if test:
with open(test) as file:
generate(file)
else:
generate(sys.stdin)
compile()
execute()
if __name__ == "__main__":
main(*sys.argv[1:])

45
tests/test_format.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
set -eu
echo "=== Formatting tests ==="
rm -rf blocks
echo "--- Basic formatting ---"
./tests/test.py << TEST
lfs_format(&lfs, &bd, &lfs_emubd_ops) => 0;
TEST
echo "--- Invalid superblocks ---"
ln -f -s /dev/null blocks/0
./tests/test.py << TEST
lfs_format(&lfs, &bd, &lfs_emubd_ops) => LFS_ERROR_CORRUPT;
TEST
rm blocks/0
echo "--- Basic mounting ---"
./tests/test.py << TEST
lfs_mount(&lfs, &bd, &lfs_emubd_ops) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Invalid mount ---"
./tests/test.py << TEST
lfs_format(&lfs, &bd, &lfs_emubd_ops) => 0;
TEST
rm blocks/0 blocks/1
./tests/test.py << TEST
lfs_mount(&lfs, &bd, &lfs_emubd_ops) => LFS_ERROR_CORRUPT;
TEST
echo "--- Valid corrupt mount ---"
./tests/test.py << TEST
lfs_format(&lfs, &bd, &lfs_emubd_ops) => 0;
TEST
rm blocks/0
./tests/test.py << TEST
lfs_mount(&lfs, &bd, &lfs_emubd_ops) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"
./tests/stats.py