2017-12-11 12:52:06 -05:00
|
|
|
#!/usr/bin/env python3
|
2014-05-05 11:49:52 -04:00
|
|
|
|
|
|
|
import os, sys
|
|
|
|
from glob import glob
|
|
|
|
from re import sub
|
2017-12-13 11:32:25 -05:00
|
|
|
import argparse
|
|
|
|
|
2014-05-05 11:49:52 -04:00
|
|
|
|
|
|
|
def escape(s):
|
2017-12-11 12:52:06 -05:00
|
|
|
s = s.decode()
|
|
|
|
lookup = {
|
|
|
|
'\0': '\\0',
|
|
|
|
'\t': '\\t',
|
|
|
|
'\n': '\\n\"\n\"',
|
|
|
|
'\r': '\\r',
|
|
|
|
'\\': '\\\\',
|
|
|
|
'\"': '\\\"',
|
|
|
|
}
|
|
|
|
return "\"\"\n\"{}\"".format(''.join([lookup[x] if x in lookup else x for x in s]))
|
2014-05-05 11:49:52 -04:00
|
|
|
|
|
|
|
def chew_filename(t):
|
2017-12-13 11:32:25 -05:00
|
|
|
return { 'func': "test_{}_fn".format(sub(r'/|\.|-', '_', t)), 'desc': t }
|
2014-05-05 11:49:52 -04:00
|
|
|
|
2017-12-11 12:52:06 -05:00
|
|
|
def script_to_map(test_file):
|
|
|
|
r = {"name": chew_filename(test_file)["func"]}
|
2018-12-20 19:44:39 -05:00
|
|
|
with open(test_file, "rb") as test:
|
2018-07-11 16:45:30 -04:00
|
|
|
script = test.readlines()
|
2017-07-03 18:05:08 -04:00
|
|
|
|
|
|
|
# Test for import skip_if and inject it into the test as needed.
|
|
|
|
if "import skip_if\n" in script:
|
|
|
|
index = script.index("import skip_if\n")
|
|
|
|
script.pop(index)
|
|
|
|
script.insert(index, "class skip_if:\n")
|
|
|
|
with open("../tests/skip_if.py") as skip_if:
|
|
|
|
total_lines = 1
|
|
|
|
for line in skip_if:
|
|
|
|
stripped = line.strip()
|
|
|
|
if not stripped or stripped.startswith(("#", "\"\"\"")):
|
|
|
|
continue
|
|
|
|
script.insert(index + total_lines, "\t" + line)
|
|
|
|
total_lines += 1
|
2018-12-20 19:44:39 -05:00
|
|
|
r['script'] = escape(b''.join(script))
|
|
|
|
|
|
|
|
with open(test_file + ".exp", "rb") as f:
|
|
|
|
r["output"] = escape(f.read())
|
|
|
|
|
2017-12-11 12:52:06 -05:00
|
|
|
return r
|
2014-05-05 11:49:52 -04:00
|
|
|
|
|
|
|
test_function = (
|
|
|
|
"void {name}(void* data) {{\n"
|
2017-12-11 12:52:06 -05:00
|
|
|
" static const char pystr[] = {script};\n"
|
|
|
|
" static const char exp[] = {output};\n"
|
|
|
|
" upytest_set_expected_output(exp, sizeof(exp) - 1);\n"
|
|
|
|
" upytest_execute_test(pystr);\n"
|
2014-05-05 11:49:52 -04:00
|
|
|
"}}"
|
|
|
|
)
|
|
|
|
|
|
|
|
testcase_struct = (
|
|
|
|
"struct testcase_t {name}_tests[] = {{\n{body}\n END_OF_TESTCASES\n}};"
|
|
|
|
)
|
|
|
|
testcase_member = (
|
|
|
|
" {{ \"{desc}\", {func}, TT_ENABLED_, 0, 0 }},"
|
|
|
|
)
|
|
|
|
|
|
|
|
testgroup_struct = (
|
|
|
|
"struct testgroup_t groups[] = {{\n{body}\n END_OF_GROUPS\n}};"
|
|
|
|
)
|
|
|
|
testgroup_member = (
|
2017-12-13 11:32:25 -05:00
|
|
|
" {{ \"{name}\", {name}_tests }},"
|
2014-05-05 11:49:52 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
## XXX: may be we could have `--without <groups>` argument...
|
2015-01-08 19:03:21 -05:00
|
|
|
# currently these tests are selected because they pass on qemu-arm
|
2016-11-02 21:28:31 -04:00
|
|
|
test_dirs = ('basics', 'micropython', 'float', 'extmod', 'inlineasm') # 'import', 'io', 'misc')
|
2016-10-13 09:08:19 -04:00
|
|
|
exclude_tests = (
|
2017-12-11 13:00:25 -05:00
|
|
|
# pattern matching in .exp
|
|
|
|
'basics/bytes_compare3.py',
|
2017-12-11 12:59:11 -05:00
|
|
|
'extmod/ticks_diff.py',
|
|
|
|
'extmod/time_ms_us.py',
|
|
|
|
'extmod/uheapq_timeq.py',
|
2017-12-11 13:00:25 -05:00
|
|
|
# unicode char issue
|
|
|
|
'extmod/ujson_loads.py',
|
|
|
|
# doesn't output to python stdout
|
|
|
|
'extmod/ure_debug.py',
|
|
|
|
'extmod/vfs_basic.py',
|
2017-12-11 12:59:11 -05:00
|
|
|
'extmod/vfs_fat_ramdisk.py', 'extmod/vfs_fat_fileio.py',
|
|
|
|
'extmod/vfs_fat_fsusermount.py', 'extmod/vfs_fat_oldproto.py',
|
2017-12-11 13:00:25 -05:00
|
|
|
# rounding issues
|
|
|
|
'float/float_divmod.py',
|
2017-12-11 12:59:11 -05:00
|
|
|
# requires double precision floating point to work
|
|
|
|
'float/float2int_doubleprec_intbig.py',
|
2017-12-11 13:00:25 -05:00
|
|
|
'float/float_parse_doubleprec.py',
|
|
|
|
# inline asm FP tests (require Cortex-M4)
|
2017-12-11 12:59:11 -05:00
|
|
|
'inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py',
|
|
|
|
'inlineasm/asmfpmuldiv.py','inlineasm/asmfpsqrt.py',
|
2017-12-11 13:00:25 -05:00
|
|
|
# different filename in output
|
|
|
|
'micropython/emg_exc.py',
|
|
|
|
'micropython/heapalloc_traceback.py',
|
|
|
|
# pattern matching in .exp
|
|
|
|
'micropython/meminfo.py',
|
2016-10-13 09:08:19 -04:00
|
|
|
)
|
2014-05-05 11:49:52 -04:00
|
|
|
|
|
|
|
output = []
|
2017-12-13 11:32:25 -05:00
|
|
|
tests = []
|
|
|
|
|
|
|
|
argparser = argparse.ArgumentParser(description='Convert native MicroPython tests to tinytest/upytesthelper C code')
|
2017-12-14 05:26:59 -05:00
|
|
|
argparser.add_argument('--stdin', action="store_true", help='read list of tests from stdin')
|
2017-12-13 11:32:25 -05:00
|
|
|
args = argparser.parse_args()
|
|
|
|
|
2017-12-14 05:26:59 -05:00
|
|
|
if not args.stdin:
|
2017-12-13 11:32:25 -05:00
|
|
|
for group in test_dirs:
|
|
|
|
tests += [test for test in glob('{}/*.py'.format(group)) if test not in exclude_tests]
|
|
|
|
else:
|
2017-12-14 05:26:59 -05:00
|
|
|
for l in sys.stdin:
|
2017-12-13 11:32:25 -05:00
|
|
|
tests.append(l.rstrip())
|
2014-05-05 11:49:52 -04:00
|
|
|
|
2017-12-13 11:32:25 -05:00
|
|
|
output.extend([test_function.format(**script_to_map(test)) for test in tests])
|
|
|
|
testcase_members = [testcase_member.format(**chew_filename(test)) for test in tests]
|
|
|
|
output.append(testcase_struct.format(name="", body='\n'.join(testcase_members)))
|
2014-05-05 11:49:52 -04:00
|
|
|
|
2017-12-13 11:32:25 -05:00
|
|
|
testgroup_members = [testgroup_member.format(name=group) for group in [""]]
|
2014-05-05 11:49:52 -04:00
|
|
|
|
|
|
|
output.append(testgroup_struct.format(body='\n'.join(testgroup_members)))
|
|
|
|
|
|
|
|
## XXX: may be we could have `--output <filename>` argument...
|
2017-12-15 04:37:32 -05:00
|
|
|
# Don't depend on what system locale is set, use utf8 encoding.
|
|
|
|
sys.stdout.buffer.write('\n\n'.join(output).encode('utf8'))
|