1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#! /usr/bin/env python3
import os
import subprocess
import sys
import argparse
import re
from glob import glob
from collections import defaultdict
run_tests_module = __import__("run-tests")
sys.path.append(run_tests_module.base_path("../tools"))
import pyboard
if os.name == "nt":
MICROPYTHON = os.getenv(
"MICROPY_MICROPYTHON", "../ports/windows/build-standard/micropython.exe"
)
else:
MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython")
injected_bench_code = b"""
import time
class bench_class:
ITERS = 20000000
@staticmethod
def run(test):
t = time.ticks_us()
test(bench_class.ITERS)
t = time.ticks_diff(time.ticks_us(), t)
s, us = divmod(t, 1_000_000)
print("{}.{:06}".format(s, us))
import sys
sys.modules['bench'] = bench_class
"""
def execbench(pyb, filename, iters):
with open(filename, "rb") as f:
pyfile = f.read()
code = (injected_bench_code + pyfile).replace(b"20000000", str(iters).encode("utf-8"))
return pyb.exec(code).replace(b"\r\n", b"\n")
def run_tests(pyb, test_dict, iters):
test_count = 0
testcase_count = 0
for base_test, tests in sorted(test_dict.items()):
print(base_test + ":")
baseline = None
for test_file in tests:
# run MicroPython
if pyb is None:
# run on PC
try:
output_mupy = subprocess.check_output(
[MICROPYTHON, "-X", "emit=bytecode", test_file[0]]
)
except subprocess.CalledProcessError:
output_mupy = b"CRASH"
else:
# run on pyboard
pyb.enter_raw_repl()
try:
output_mupy = execbench(pyb, test_file[0], iters)
except pyboard.PyboardError:
output_mupy = b"CRASH"
try:
output_mupy = float(output_mupy.strip())
except ValueError:
output_mupy = -1
test_file[1] = output_mupy
testcase_count += 1
if baseline is None:
baseline = test_file[1]
print(
" %.3fs (%+06.2f%%) %s"
% (test_file[1], (test_file[1] * 100 / baseline) - 100, test_file[0])
)
test_count += 1
print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
# all tests succeeded
return True
def main():
cmd_parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=f"""Run and manage tests for MicroPython.
{run_tests_module.test_instance_description}
{run_tests_module.test_directory_description}
""",
epilog=run_tests_module.test_instance_epilog,
)
cmd_parser.add_argument(
"-t", "--test-instance", default="unix", help="the MicroPython instance to test"
)
cmd_parser.add_argument(
"-b", "--baudrate", default=115200, help="the baud rate of the serial device"
)
cmd_parser.add_argument("-u", "--user", default="micro", help="the telnet login username")
cmd_parser.add_argument("-p", "--password", default="python", help="the telnet login password")
cmd_parser.add_argument(
"-d", "--test-dirs", nargs="*", help="input test directories (if no files given)"
)
cmd_parser.add_argument(
"-I",
"--iters",
type=int,
default=200_000,
help="number of test iterations, only for remote instances (default 200,000)",
)
cmd_parser.add_argument("files", nargs="*", help="input test files")
args = cmd_parser.parse_args()
# Note pyboard support is copied over from run-tests.py, not tests, and likely needs revamping
pyb = run_tests_module.get_test_instance(
args.test_instance, args.baudrate, args.user, args.password
)
if len(args.files) == 0:
if args.test_dirs:
test_dirs = tuple(args.test_dirs)
else:
test_dirs = ("internal_bench",)
tests = sorted(
test_file
for test_files in (glob("{}/*.py".format(dir)) for dir in test_dirs)
for test_file in test_files
)
else:
# tests explicitly given
tests = sorted(args.files)
test_dict = defaultdict(lambda: [])
for t in tests:
m = re.match(r"(.+?)-(.+)\.py", t)
if not m:
continue
test_dict[m.group(1)].append([t, None])
if not run_tests(pyb, test_dict, args.iters):
sys.exit(1)
if __name__ == "__main__":
main()
|