blob: 1e6dd50538206838de419a0548e08061977dec18 [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
Damien George41f768f2014-05-03 16:43:27 +010030 running_under_travis = os.getenv('TRAVIS') == 'true'
Damien39977a52013-12-29 22:34:42 +000031
Damien George41f768f2014-05-03 16:43:27 +010032 # Set of tests that we shouldn't run under Travis CI
33 skip_travis_tests = set(['basics/memoryerror.py'])
Damien George23093692014-04-03 22:44:51 +010034
Damien George41f768f2014-05-03 16:43:27 +010035 for test_file in tests:
36 if running_under_travis and test_file in skip_travis_tests:
37 print("skip ", test_file)
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +030038 skipped_tests.append(test_name)
Damien George41f768f2014-05-03 16:43:27 +010039 continue
Andrew Scheller1b997d52014-04-16 03:28:40 +010040
Damien George41f768f2014-05-03 16:43:27 +010041 # get expected output
42 test_file_expected = test_file + '.exp'
43 if os.path.isfile(test_file_expected):
44 # expected output given by a file, so read that in
45 with open(test_file_expected, 'rb') as f:
46 output_expected = f.read()
stijna4dbc732014-05-11 12:45:02 +020047 if os.name == 'nt':
48 output_expected = output_expected.replace(b'\n', b'\r\n')
Damien George41f768f2014-05-03 16:43:27 +010049 else:
stijna4dbc732014-05-11 12:45:02 +020050 # run CPython to work out expected output
Damien George41f768f2014-05-03 16:43:27 +010051 try:
52 output_expected = subprocess.check_output([CPYTHON3, '-B', test_file])
53 except subprocess.CalledProcessError:
54 output_expected = b'CPYTHON3 CRASH'
Damien39977a52013-12-29 22:34:42 +000055
Damien George41f768f2014-05-03 16:43:27 +010056 # run Micro Python
57 if pyb is None:
58 # run on PC
59 try:
60 output_mupy = subprocess.check_output([MICROPYTHON, '-X', 'emit=bytecode', test_file])
61 except subprocess.CalledProcessError:
62 output_mupy = b'CRASH'
63 else:
64 # run on pyboard
65 pyb.enter_raw_repl()
66 try:
67 output_mupy = pyb.execfile(test_file).replace(b'\r\n', b'\n')
68 except pyboard.PyboardError:
69 output_mupy = b'CRASH'
Damien George4b34c762014-04-03 23:51:16 +010070
Damien George41f768f2014-05-03 16:43:27 +010071 test_basename = os.path.basename(test_file)
72 test_name = os.path.splitext(test_basename)[0]
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +030073
74 if output_mupy == b'SKIP\n':
75 print("skip ", test_file)
76 skipped_tests.append(test_name)
77 continue
78
79 testcase_count += len(output_expected.splitlines())
80
Damien George41f768f2014-05-03 16:43:27 +010081 filename_expected = test_basename + ".exp"
82 filename_mupy = test_basename + ".out"
83
84 if output_expected == output_mupy:
85 print("pass ", test_file)
86 passed_count += 1
87 rm_f(filename_expected)
88 rm_f(filename_mupy)
89 else:
90 with open(filename_expected, "w") as f:
91 f.write(str(output_expected, "ascii"))
92 with open(filename_mupy, "w") as f:
93 f.write(str(output_mupy, "ascii"))
94 print("FAIL ", test_file)
95 failed_tests.append(test_name)
96
97 test_count += 1
98
99 print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
100 print("{} tests passed".format(passed_count))
101
Paul Sokolovsky43d4a6f2014-05-10 16:52:58 +0300102 if len(skipped_tests) > 0:
103 print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests)))
Damien George41f768f2014-05-03 16:43:27 +0100104 if len(failed_tests) > 0:
105 print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
106 return False
107
108 # all tests succeeded
109 return True
110
111def main():
112 cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.')
113 cmd_parser.add_argument('--pyboard', action='store_true', help='run the tests on the pyboard')
Damien Georgea053e372014-05-31 18:11:01 +0100114 cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)')
Damien George41f768f2014-05-03 16:43:27 +0100115 cmd_parser.add_argument('files', nargs='*', help='input test files')
116 args = cmd_parser.parse_args()
117
118 if args.pyboard:
119 import pyboard
120 pyb = pyboard.Pyboard('/dev/ttyACM0')
Damien Georgeb636d022014-04-13 13:48:33 +0100121 pyb.enter_raw_repl()
Damien Georgeb636d022014-04-13 13:48:33 +0100122 else:
Damien George41f768f2014-05-03 16:43:27 +0100123 pyb = None
Damien39977a52013-12-29 22:34:42 +0000124
Damien George41f768f2014-05-03 16:43:27 +0100125 if len(args.files) == 0:
stijn8ac3b572014-05-28 14:27:54 +0200126 if args.test_dirs is None:
127 if pyb is None:
128 # run PC tests
129 test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc')
130 else:
131 # run pyboard tests
132 test_dirs = ('basics', 'float', 'pyb', 'pybnative', 'inlineasm')
Damien George41f768f2014-05-03 16:43:27 +0100133 else:
stijn8ac3b572014-05-28 14:27:54 +0200134 # run tests from these directories
135 test_dirs = args.test_dirs
Damien George41f768f2014-05-03 16:43:27 +0100136 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 +0100137 else:
Damien George41f768f2014-05-03 16:43:27 +0100138 # tests explicitly given
139 tests = args.files
Markus Siemens19ccc6b2014-01-27 22:53:28 +0100140
Damien George41f768f2014-05-03 16:43:27 +0100141 if not run_tests(pyb, tests):
142 sys.exit(1)
Markus Siemens19ccc6b2014-01-27 22:53:28 +0100143
Damien George41f768f2014-05-03 16:43:27 +0100144if __name__ == "__main__":
145 main()