Skip to content

Commit e41b571

Browse files
committed
tests/run-tests.py: Support running webassembly tests via node.
This allows running tests with a .js/.mjs suffix, and also .py tests using node and the webassembly port. Signed-off-by: Damien George <[email protected]>
1 parent c2cf58b commit e41b571

File tree

1 file changed

+75
-2
lines changed

1 file changed

+75
-2
lines changed

tests/run-tests.py

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,9 @@ def send_get(what):
308308

309309
else:
310310
# run via pyboard interface
311-
had_crash, output_mupy = run_script_on_remote_target(pyb, args, test_file, is_special)
311+
had_crash, output_mupy = pyb.run_script_on_remote_target(
312+
args, test_file_abspath, is_special
313+
)
312314

313315
# canonical form for all ports/platforms is to use \n for end-of-line
314316
output_mupy = output_mupy.replace(b"\r\n", b"\n")
@@ -393,6 +395,51 @@ def value(self):
393395
return self._value
394396

395397

398+
class PyboardNodeRunner:
399+
def __init__(self):
400+
mjs = os.getenv("MICROPY_MICROPYTHON_MJS")
401+
if mjs is None:
402+
mjs = base_path("../ports/webassembly/build-standard/micropython.mjs")
403+
else:
404+
mjs = os.path.abspath(mjs)
405+
self.micropython_mjs = mjs
406+
407+
def close(self):
408+
pass
409+
410+
def run_script_on_remote_target(self, args, test_file, is_special):
411+
cwd = os.path.dirname(test_file)
412+
413+
# Create system command list.
414+
cmdlist = ["node"]
415+
if test_file.endswith(".py"):
416+
# Run a Python script indirectly via "node micropython.mjs <script.py>".
417+
cmdlist.append(self.micropython_mjs)
418+
if args.heapsize is not None:
419+
cmdlist.extend(["-X", "heapsize=" + args.heapsize])
420+
cmdlist.append(test_file)
421+
else:
422+
# Run a js/mjs script directly with Node, passing in the path to micropython.mjs.
423+
cmdlist.append(test_file)
424+
cmdlist.append(self.micropython_mjs)
425+
426+
# Run the script.
427+
try:
428+
had_crash = False
429+
output_mupy = subprocess.check_output(
430+
cmdlist, stderr=subprocess.STDOUT, timeout=TEST_TIMEOUT, cwd=cwd
431+
)
432+
except subprocess.CalledProcessError as er:
433+
had_crash = True
434+
output_mupy = er.output + b"CRASH"
435+
except subprocess.TimeoutExpired as er:
436+
had_crash = True
437+
output_mupy = (er.output or b"") + b"TIMEOUT"
438+
439+
# Return the results.
440+
return had_crash, output_mupy
441+
442+
396443
def run_tests(pyb, tests, args, result_dir, num_threads=1):
397444
test_count = ThreadSafeCounter()
398445
testcase_count = ThreadSafeCounter()
@@ -631,6 +678,20 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
631678
) # RA fsp rtc function doesn't support nano sec info
632679
elif args.target == "qemu-arm":
633680
skip_tests.add("misc/print_exception.py") # requires sys stdfiles
681+
elif args.target == "webassembly":
682+
skip_tests.add("basics/string_format_modulo.py") # can't print nulls to stdout
683+
skip_tests.add("basics/string_strip.py") # can't print nulls to stdout
684+
skip_tests.add("extmod/binascii_a2b_base64.py")
685+
skip_tests.add("extmod/re_stack_overflow.py")
686+
skip_tests.add("extmod/time_res.py")
687+
skip_tests.add("extmod/vfs_posix.py")
688+
skip_tests.add("extmod/vfs_posix_enoent.py")
689+
skip_tests.add("extmod/vfs_posix_paths.py")
690+
skip_tests.add("extmod/vfs_userfs.py")
691+
skip_tests.add("micropython/emg_exc.py")
692+
skip_tests.add("micropython/extreme_exc.py")
693+
skip_tests.add("micropython/heapalloc_exc_compressed_emg_exc.py")
694+
skip_tests.add("micropython/import_mpy_invalid.py")
634695

635696
# Some tests are known to fail on 64-bit machines
636697
if pyb is None and platform.architecture()[0] == "64bit":
@@ -977,6 +1038,7 @@ def main():
9771038
LOCAL_TARGETS = (
9781039
"unix",
9791040
"qemu-arm",
1041+
"webassembly",
9801042
)
9811043
EXTERNAL_TARGETS = (
9821044
"pyboard",
@@ -997,6 +1059,8 @@ def main():
9971059
args.mpy_cross_flags = "-march=host"
9981060
elif args.target == "qemu-arm":
9991061
args.mpy_cross_flags = "-march=armv7m"
1062+
if args.target == "webassembly":
1063+
pyb = PyboardNodeRunner()
10001064
elif args.target in EXTERNAL_TARGETS:
10011065
global pyboard
10021066
sys.path.append(base_path("../tools"))
@@ -1015,6 +1079,7 @@ def main():
10151079
args.mpy_cross_flags = "-march=armv7m"
10161080

10171081
pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password)
1082+
pyboard.Pyboard.run_script_on_remote_target = run_script_on_remote_target
10181083
pyb.enter_raw_repl()
10191084
else:
10201085
raise ValueError("target must be one of %s" % ", ".join(LOCAL_TARGETS + EXTERNAL_TARGETS))
@@ -1032,6 +1097,10 @@ def main():
10321097
else:
10331098
tests = []
10341099
elif len(args.files) == 0:
1100+
test_extensions = ("*.py",)
1101+
if args.target == "webassembly":
1102+
test_extensions += ("*.js", "*.mjs")
1103+
10351104
if args.test_dirs is None:
10361105
test_dirs = (
10371106
"basics",
@@ -1072,12 +1141,16 @@ def main():
10721141
"inlineasm",
10731142
"ports/qemu-arm",
10741143
)
1144+
elif args.target == "webassembly":
1145+
test_dirs += ("float",)
10751146
else:
10761147
# run tests from these directories
10771148
test_dirs = args.test_dirs
10781149
tests = sorted(
10791150
test_file
1080-
for test_files in (glob("{}/*.py".format(dir)) for dir in test_dirs)
1151+
for test_files in (
1152+
glob(os.path.join(dir, ext)) for dir in test_dirs for ext in test_extensions
1153+
)
10811154
for test_file in test_files
10821155
)
10831156
else:

0 commit comments

Comments
 (0)