1#! /usr/bin/env python3 2 3import os 4import subprocess 5import sys 6import argparse 7import re 8from glob import glob 9from collections import defaultdict 10 11# Tests require at least CPython 3.3. If your default python3 executable 12# is of lower version, you can point MICROPY_CPYTHON3 environment var 13# to the correct executable. 14if os.name == "nt": 15 CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3.exe") 16 MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") 17else: 18 CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") 19 MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython") 20 21 22def run_tests(pyb, test_dict): 23 test_count = 0 24 testcase_count = 0 25 26 for base_test, tests in sorted(test_dict.items()): 27 print(base_test + ":") 28 for test_file in tests: 29 30 # run MicroPython 31 if pyb is None: 32 # run on PC 33 try: 34 output_mupy = subprocess.check_output( 35 [MICROPYTHON, "-X", "emit=bytecode", test_file[0]] 36 ) 37 except subprocess.CalledProcessError: 38 output_mupy = b"CRASH" 39 else: 40 # run on pyboard 41 pyb.enter_raw_repl() 42 try: 43 output_mupy = pyb.execfile(test_file).replace(b"\r\n", b"\n") 44 except pyboard.PyboardError: 45 output_mupy = b"CRASH" 46 47 output_mupy = float(output_mupy.strip()) 48 test_file[1] = output_mupy 49 testcase_count += 1 50 51 test_count += 1 52 baseline = None 53 for t in tests: 54 if baseline is None: 55 baseline = t[1] 56 print(" %.3fs (%+06.2f%%) %s" % (t[1], (t[1] * 100 / baseline) - 100, t[0])) 57 58 print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) 59 60 # all tests succeeded 61 return True 62 63 64def main(): 65 cmd_parser = argparse.ArgumentParser(description="Run tests for MicroPython.") 66 cmd_parser.add_argument("--pyboard", action="store_true", help="run the tests on the pyboard") 67 cmd_parser.add_argument("files", nargs="*", help="input test files") 68 args = cmd_parser.parse_args() 69 70 # Note pyboard support is copied over from run-tests, not testes, and likely needs revamping 71 if args.pyboard: 72 import pyboard 73 74 pyb = pyboard.Pyboard("/dev/ttyACM0") 75 pyb.enter_raw_repl() 76 else: 77 pyb = None 78 79 if len(args.files) == 0: 80 if pyb is None: 81 # run PC tests 82 test_dirs = ("internal_bench",) 83 else: 84 # run pyboard tests 85 test_dirs = ("basics", "float", "pyb") 86 tests = sorted( 87 test_file 88 for test_files in (glob("{}/*.py".format(dir)) for dir in test_dirs) 89 for test_file in test_files 90 ) 91 else: 92 # tests explicitly given 93 tests = sorted(args.files) 94 95 test_dict = defaultdict(lambda: []) 96 for t in tests: 97 m = re.match(r"(.+?)-(.+)\.py", t) 98 if not m: 99 continue 100 test_dict[m.group(1)].append([t, None]) 101 102 if not run_tests(pyb, test_dict): 103 sys.exit(1) 104 105 106if __name__ == "__main__": 107 main() 108