blob: c6bc4020d41d68e97c0420034874774e996946d2 [file] [log] [blame]
Damien George929a6752014-04-02 15:31:39 +01001#! /usr/bin/env python3
Damien39977a52013-12-29 22:34:42 +00002
Markus Siemens19ccc6b2014-01-27 22:53:28 +01003import os
4import subprocess
5import sys
Damien George41f768f2014-05-03 16:43:27 +01006import argparse
Markus Siemens19ccc6b2014-01-27 22:53:28 +01007from glob import glob
Damien39977a52013-12-29 22:34:42 +00008
Paul Sokolovskya7752a42014-04-04 17:28:34 +03009# Tests require at least CPython 3.3. If your default python3 executable
10# is of lower version, you can point MICROPY_CPYTHON3 environment var
11# to the correct executable.
Markus Siemens19ccc6b2014-01-27 22:53:28 +010012if os.name == 'nt':
Paul Sokolovskya7752a42014-04-04 17:28:34 +030013 CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe')
Andrew Scheller57094532014-04-17 01:22:45 +010014 MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../windows/micropython.exe')
Markus Siemens19ccc6b2014-01-27 22:53:28 +010015else:
Paul Sokolovsky34e11992014-04-03 22:06:35 +030016 CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3')
Andrew Scheller57094532014-04-17 01:22:45 +010017 MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython')
Damien39977a52013-12-29 22:34:42 +000018
Paul Sokolovskyfd232c32014-03-23 01:07:30 +020019def rm_f(fname):
20 if os.path.exists(fname):
21 os.remove(fname)
22
Damien George41f768f2014-05-03 16:43:27 +010023def run_tests(pyb, tests):
24 test_count = 0
25 testcase_count = 0
26 passed_count = 0
27 failed_tests = []
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +030028 skipped_tests = []
Damien39977a52013-12-29 22:34:42 +000029
Chris Angelico047db222014-06-06 07:45:55 +100030 skip_tests = set()
Damien39977a52013-12-29 22:34:42 +000031
Chris Angelico047db222014-06-06 07:45:55 +100032 # Some tests shouldn't be run under Travis CI
33 if os.getenv('TRAVIS') == 'true':
34 skip_tests.add('basics/memoryerror.py')
Damien George23093692014-04-03 22:44:51 +010035
Damien George41f768f2014-05-03 16:43:27 +010036 for test_file in tests:
Chris Angelico88b11b52014-06-06 07:41:30 +100037 test_basename = os.path.basename(test_file)
38 test_name = os.path.splitext(test_basename)[0]
39
Chris Angelico047db222014-06-06 07:45:55 +100040 if test_file in skip_tests:
Damien George41f768f2014-05-03 16:43:27 +010041 print("skip ", test_file)
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +030042 skipped_tests.append(test_name)
Damien George41f768f2014-05-03 16:43:27 +010043 continue
Andrew Scheller1b997d52014-04-16 03:28:40 +010044
Damien George41f768f2014-05-03 16:43:27 +010045 # get expected output
46 test_file_expected = test_file + '.exp'
47 if os.path.isfile(test_file_expected):
48 # expected output given by a file, so read that in
49 with open(test_file_expected, 'rb') as f:
50 output_expected = f.read()
stijna4dbc732014-05-11 12:45:02 +020051 if os.name == 'nt':
52 output_expected = output_expected.replace(b'\n', b'\r\n')
Damien George41f768f2014-05-03 16:43:27 +010053 else:
stijna4dbc732014-05-11 12:45:02 +020054 # run CPython to work out expected output
Damien George41f768f2014-05-03 16:43:27 +010055 try:
56 output_expected = subprocess.check_output([CPYTHON3, '-B', test_file])
57 except subprocess.CalledProcessError:
58 output_expected = b'CPYTHON3 CRASH'
Damien39977a52013-12-29 22:34:42 +000059
Damien George41f768f2014-05-03 16:43:27 +010060 # run Micro Python
61 if pyb is None:
62 # run on PC
63 try:
64 output_mupy = subprocess.check_output([MICROPYTHON, '-X', 'emit=bytecode', test_file])
65 except subprocess.CalledProcessError:
66 output_mupy = b'CRASH'
67 else:
68 # run on pyboard
69 pyb.enter_raw_repl()
70 try:
71 output_mupy = pyb.execfile(test_file).replace(b'\r\n', b'\n')
72 except pyboard.PyboardError:
73 output_mupy = b'CRASH'
Damien George4b34c762014-04-03 23:51:16 +010074
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +030075 if output_mupy == b'SKIP\n':
76 print("skip ", test_file)
77 skipped_tests.append(test_name)
78 continue
79
80 testcase_count += len(output_expected.splitlines())
81
Damien George41f768f2014-05-03 16:43:27 +010082 filename_expected = test_basename + ".exp"
83 filename_mupy = test_basename + ".out"
84
85 if output_expected == output_mupy:
86 print("pass ", test_file)
87 passed_count += 1
88 rm_f(filename_expected)
89 rm_f(filename_mupy)
90 else:
Damien George41736f82014-06-28 10:29:12 +010091 with open(filename_expected, "wb") as f:
92 f.write(output_expected)
93 with open(filename_mupy, "wb") as f:
94 f.write(output_mupy)
Damien George41f768f2014-05-03 16:43:27 +010095 print("FAIL ", test_file)
96 failed_tests.append(test_name)
97
98 test_count += 1
99
100 print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
101 print("{} tests passed".format(passed_count))
102
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +0300103 if len(skipped_tests) > 0:
104 print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests)))
Damien George41f768f2014-05-03 16:43:27 +0100105 if len(failed_tests) > 0:
106 print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
107 return False
108
109 # all tests succeeded
110 return True
111
112def main():
113 cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.')
114 cmd_parser.add_argument('--pyboard', action='store_true', help='run the tests on the pyboard')
Damien Georgea053e372014-05-31 18:11:01 +0100115 cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)')
Damien George41f768f2014-05-03 16:43:27 +0100116 cmd_parser.add_argument('files', nargs='*', help='input test files')
117 args = cmd_parser.parse_args()
118
119 if args.pyboard:
120 import pyboard
121 pyb = pyboard.Pyboard('/dev/ttyACM0')
Damien Georgeb636d022014-04-13 13:48:33 +0100122 pyb.enter_raw_repl()
Damien Georgeb636d022014-04-13 13:48:33 +0100123 else:
Damien George41f768f2014-05-03 16:43:27 +0100124 pyb = None
Damien39977a52013-12-29 22:34:42 +0000125
Damien George41f768f2014-05-03 16:43:27 +0100126 if len(args.files) == 0:
stijn8ac3b572014-05-28 14:27:54 +0200127 if args.test_dirs is None:
128 if pyb is None:
129 # run PC tests
130 test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc')
131 else:
132 # run pyboard tests
Damien George4297fed2014-06-08 13:46:03 +0100133 test_dirs = ('basics', 'micropython', 'float', 'pyb', 'pybnative', 'inlineasm')
Damien George41f768f2014-05-03 16:43:27 +0100134 else:
stijn8ac3b572014-05-28 14:27:54 +0200135 # run tests from these directories
136 test_dirs = args.test_dirs
Damien George41f768f2014-05-03 16:43:27 +0100137 tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files)
Markus Siemens19ccc6b2014-01-27 22:53:28 +0100138 else:
Damien George41f768f2014-05-03 16:43:27 +0100139 # tests explicitly given
140 tests = args.files
Markus Siemens19ccc6b2014-01-27 22:53:28 +0100141
Damien George41f768f2014-05-03 16:43:27 +0100142 if not run_tests(pyb, tests):
143 sys.exit(1)
Markus Siemens19ccc6b2014-01-27 22:53:28 +0100144
Damien George41f768f2014-05-03 16:43:27 +0100145if __name__ == "__main__":
146 main()