Damien George | 929a675 | 2014-04-02 15:31:39 +0100 | [diff] [blame] | 1 | #! /usr/bin/env python3 |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 2 | |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 3 | import os |
| 4 | import subprocess |
| 5 | import sys |
Damien George | 612045f | 2014-09-17 22:56:34 +0100 | [diff] [blame] | 6 | import platform |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 7 | import argparse |
Damien George | 1004535 | 2015-03-20 17:25:25 +0000 | [diff] [blame] | 8 | import re |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 9 | from glob import glob |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 10 | |
Paul Sokolovsky | a7752a4 | 2014-04-04 17:28:34 +0300 | [diff] [blame] | 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. |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 14 | if os.name == 'nt': |
Paul Sokolovsky | a7752a4 | 2014-04-04 17:28:34 +0300 | [diff] [blame] | 15 | CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe') |
Andrew Scheller | 5709453 | 2014-04-17 01:22:45 +0100 | [diff] [blame] | 16 | MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../windows/micropython.exe') |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 17 | else: |
Paul Sokolovsky | 34e1199 | 2014-04-03 22:06:35 +0300 | [diff] [blame] | 18 | CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3') |
Andrew Scheller | 5709453 | 2014-04-17 01:22:45 +0100 | [diff] [blame] | 19 | MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython') |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 20 | |
blmorris | 9d1ca65 | 2014-11-19 10:44:31 -0500 | [diff] [blame] | 21 | # Set PYTHONIOENCODING so that CPython will use utf-8 on systems which set another encoding in the locale |
Paul Sokolovsky | dbc7854 | 2014-12-12 00:51:39 +0200 | [diff] [blame] | 22 | os.environ['PYTHONIOENCODING'] = 'utf-8' |
Paul Sokolovsky | 1ca28bd | 2014-12-12 00:57:03 +0200 | [diff] [blame] | 23 | os.environ['MICROPYPATH'] = '' |
blmorris | 9d1ca65 | 2014-11-19 10:44:31 -0500 | [diff] [blame] | 24 | |
Paul Sokolovsky | fd232c3 | 2014-03-23 01:07:30 +0200 | [diff] [blame] | 25 | def rm_f(fname): |
| 26 | if os.path.exists(fname): |
| 27 | os.remove(fname) |
| 28 | |
Damien George | 5a04e2c | 2014-10-05 22:27:12 +0100 | [diff] [blame] | 29 | def run_micropython(pyb, args, test_file): |
| 30 | if pyb is None: |
| 31 | # run on PC |
Damien George | 143c341 | 2015-03-13 10:58:34 +0000 | [diff] [blame] | 32 | if test_file.startswith('cmdline/'): |
| 33 | # special handling for tests of the unix cmdline program |
| 34 | |
| 35 | # check for any cmdline options needed for this test |
| 36 | args = [MICROPYTHON] |
| 37 | with open(test_file, 'rb') as f: |
| 38 | line = f.readline() |
| 39 | if line.startswith(b'# cmdline:'): |
| 40 | args += line[10:].strip().split() |
| 41 | |
| 42 | # run the test, possibly with redirected input |
| 43 | try: |
| 44 | if test_file.startswith('cmdline/repl_'): |
| 45 | f = open(test_file, 'rb') |
| 46 | output_mupy = subprocess.check_output(args, stdin=f) |
| 47 | f.close() |
| 48 | else: |
| 49 | output_mupy = subprocess.check_output(args + [test_file]) |
| 50 | except subprocess.CalledProcessError: |
| 51 | output_mupy = b'CRASH' |
| 52 | |
Damien George | 1004535 | 2015-03-20 17:25:25 +0000 | [diff] [blame] | 53 | # unescape wanted regex chars and escape unwanted ones |
| 54 | def convert_regex_escapes(line): |
| 55 | cs = [] |
| 56 | escape = False |
| 57 | for c in str(line, 'utf8'): |
| 58 | if escape: |
| 59 | escape = False |
| 60 | cs.append(c) |
| 61 | elif c == '\\': |
| 62 | escape = True |
| 63 | elif c in ('(', ')', '[', ']', '{', '}', '.', '*', '+', '^', '$'): |
| 64 | cs.append('\\' + c) |
| 65 | else: |
| 66 | cs.append(c) |
| 67 | return bytes(''.join(cs), 'utf8') |
| 68 | |
| 69 | # convert parts of the output that are not stable across runs |
Damien George | 143c341 | 2015-03-13 10:58:34 +0000 | [diff] [blame] | 70 | with open(test_file + '.exp', 'rb') as f: |
Damien George | 1004535 | 2015-03-20 17:25:25 +0000 | [diff] [blame] | 71 | lines_exp = [] |
| 72 | for line in f.readlines(): |
| 73 | if line == b'########\n': |
| 74 | line = (line,) |
| 75 | else: |
| 76 | line = (line, re.compile(convert_regex_escapes(line))) |
| 77 | lines_exp.append(line) |
Damien George | 143c341 | 2015-03-13 10:58:34 +0000 | [diff] [blame] | 78 | lines_mupy = [line + b'\n' for line in output_mupy.split(b'\n')] |
| 79 | if output_mupy.endswith(b'\n'): |
| 80 | lines_mupy = lines_mupy[:-1] # remove erroneous last empty line |
Damien George | 1004535 | 2015-03-20 17:25:25 +0000 | [diff] [blame] | 81 | i_mupy = 0 |
| 82 | for i in range(len(lines_exp)): |
| 83 | if lines_exp[i][0] == b'########\n': |
| 84 | # 8x #'s means match 0 or more whole lines |
| 85 | line_exp = lines_exp[i + 1] |
| 86 | skip = 0 |
| 87 | while i_mupy + skip < len(lines_mupy) and not line_exp[1].match(lines_mupy[i_mupy + skip]): |
| 88 | skip += 1 |
| 89 | if i_mupy + skip >= len(lines_mupy): |
| 90 | lines_mupy[i_mupy] = b'######## FAIL\n' |
| 91 | break |
| 92 | del lines_mupy[i_mupy:i_mupy + skip] |
| 93 | lines_mupy.insert(i_mupy, b'########\n') |
| 94 | i_mupy += 1 |
| 95 | else: |
| 96 | # a regex |
| 97 | if lines_exp[i][1].match(lines_mupy[i_mupy]): |
| 98 | lines_mupy[i_mupy] = lines_exp[i][0] |
| 99 | i_mupy += 1 |
| 100 | if i_mupy >= len(lines_mupy): |
| 101 | break |
| 102 | output_mupy = b''.join(lines_mupy) |
Damien George | 143c341 | 2015-03-13 10:58:34 +0000 | [diff] [blame] | 103 | |
| 104 | else: |
| 105 | # a standard test |
| 106 | try: |
| 107 | output_mupy = subprocess.check_output([MICROPYTHON, '-X', 'emit=' + args.emit, test_file]) |
| 108 | except subprocess.CalledProcessError: |
| 109 | output_mupy = b'CRASH' |
Damien George | 5a04e2c | 2014-10-05 22:27:12 +0100 | [diff] [blame] | 110 | else: |
| 111 | # run on pyboard |
| 112 | import pyboard |
| 113 | pyb.enter_raw_repl() |
| 114 | try: |
| 115 | output_mupy = pyb.execfile(test_file).replace(b'\r\n', b'\n') |
| 116 | except pyboard.PyboardError: |
| 117 | output_mupy = b'CRASH' |
| 118 | |
| 119 | return output_mupy |
| 120 | |
Paul Sokolovsky | 2cf3810 | 2014-07-12 16:34:51 +0300 | [diff] [blame] | 121 | def run_tests(pyb, tests, args): |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 122 | test_count = 0 |
| 123 | testcase_count = 0 |
| 124 | passed_count = 0 |
| 125 | failed_tests = [] |
Paul Sokolovsky | 43d4a6f | 2014-05-10 16:52:58 +0300 | [diff] [blame] | 126 | skipped_tests = [] |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 127 | |
Chris Angelico | 047db22 | 2014-06-06 07:45:55 +1000 | [diff] [blame] | 128 | skip_tests = set() |
Paul Sokolovsky | 138562c | 2014-12-13 00:50:54 +0200 | [diff] [blame] | 129 | skip_native = False |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 130 | |
Damien George | 5a04e2c | 2014-10-05 22:27:12 +0100 | [diff] [blame] | 131 | # Check if micropython.native is supported, and skip such tests if it's not |
| 132 | native = run_micropython(pyb, args, 'micropython/native_check.py') |
| 133 | if native == b'CRASH': |
Paul Sokolovsky | 138562c | 2014-12-13 00:50:54 +0200 | [diff] [blame] | 134 | skip_native = True |
Damien George | 5a04e2c | 2014-10-05 22:27:12 +0100 | [diff] [blame] | 135 | |
Chris Angelico | 047db22 | 2014-06-06 07:45:55 +1000 | [diff] [blame] | 136 | # Some tests shouldn't be run under Travis CI |
| 137 | if os.getenv('TRAVIS') == 'true': |
| 138 | skip_tests.add('basics/memoryerror.py') |
Damien George | 2309369 | 2014-04-03 22:44:51 +0100 | [diff] [blame] | 139 | |
Damien George | 8594ce2 | 2014-09-13 18:43:09 +0100 | [diff] [blame] | 140 | # Some tests shouldn't be run on pyboard |
| 141 | if pyb is not None: |
| 142 | skip_tests.add('float/float_divmod.py') # tested by float/float_divmod_relaxed.py instead |
Damien George | ad2307c | 2015-01-07 12:10:47 +0000 | [diff] [blame] | 143 | skip_tests.add('float/float2int_doubleprec.py') # requires double precision floating point to work |
Damien George | 8594ce2 | 2014-09-13 18:43:09 +0100 | [diff] [blame] | 144 | |
Damien George | 612045f | 2014-09-17 22:56:34 +0100 | [diff] [blame] | 145 | # Some tests are known to fail on 64-bit machines |
| 146 | if pyb is None and platform.architecture()[0] == '64bit': |
Damien George | 96e20c6 | 2014-09-23 12:09:26 +0000 | [diff] [blame] | 147 | pass |
Damien George | 612045f | 2014-09-17 22:56:34 +0100 | [diff] [blame] | 148 | |
stijn | dc1ea11 | 2014-10-04 08:39:15 +0200 | [diff] [blame] | 149 | # Some tests use unsupported features on Windows |
| 150 | if os.name == 'nt': |
stijn | dc1ea11 | 2014-10-04 08:39:15 +0200 | [diff] [blame] | 151 | skip_tests.add('import\\import_file.py') #works but CPython prints forward slashes |
stijn | dc1ea11 | 2014-10-04 08:39:15 +0200 | [diff] [blame] | 152 | |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 153 | # Some tests are known to fail with native emitter |
| 154 | # Remove them from the below when they work |
| 155 | if args.emit == 'native': |
Damien George | 4cd9ced | 2015-01-15 14:41:41 +0000 | [diff] [blame^] | 156 | skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class closure_defargs del_deref del_local fun3 fun_calldblstar fun_callstar fun_callstardblstar fun_defargs fun_defargs2 fun_kwargs fun_kwonly fun_kwonlydef fun_kwvarargs fun_varargs gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_throw generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send globals_del string_format string_join subclass_native2_list subclass_native2_tuple try_finally_loops try_finally_return try_reraise try_reraise2 unboundlocal with1 with_break with_continue with_return'.split()}) |
Damien George | 23d7fd5 | 2015-03-25 23:33:48 +0000 | [diff] [blame] | 157 | skip_tests.add('basics/array_construct2.py') # requires generators |
| 158 | skip_tests.add('basics/bool1.py') # seems to randomly fail |
Damien George | 72ddcfd | 2015-03-03 18:06:45 +0000 | [diff] [blame] | 159 | skip_tests.add('basics/boundmeth1.py') # requires support for many args |
Damien George | 23d7fd5 | 2015-03-25 23:33:48 +0000 | [diff] [blame] | 160 | skip_tests.add('basics/closure_manyvars.py') # requires closures |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 161 | skip_tests.add('float/string_format.py') |
Damien George | e8b877b | 2015-02-02 20:01:51 +0000 | [diff] [blame] | 162 | skip_tests.add('float/cmath_fun.py') # requires f(*args) support |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 163 | skip_tests.add('import/gen_context.py') |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 164 | skip_tests.add('io/file_with.py') |
| 165 | skip_tests.add('micropython/heapalloc.py') |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 166 | skip_tests.add('misc/features.py') |
| 167 | skip_tests.add('misc/recursion.py') |
| 168 | skip_tests.add('misc/rge_sm.py') |
Damien George | f905145 | 2014-12-11 17:34:55 +0000 | [diff] [blame] | 169 | skip_tests.add('misc/print_exception.py') # because native doesn't have proper traceback info |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 170 | |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 171 | for test_file in tests: |
Chris Angelico | 88b11b5 | 2014-06-06 07:41:30 +1000 | [diff] [blame] | 172 | test_basename = os.path.basename(test_file) |
| 173 | test_name = os.path.splitext(test_basename)[0] |
Paul Sokolovsky | 138562c | 2014-12-13 00:50:54 +0200 | [diff] [blame] | 174 | is_native = test_name.startswith("native_") or test_name.startswith("viper_") |
Chris Angelico | 88b11b5 | 2014-06-06 07:41:30 +1000 | [diff] [blame] | 175 | |
Paul Sokolovsky | 138562c | 2014-12-13 00:50:54 +0200 | [diff] [blame] | 176 | if test_file in skip_tests or (skip_native and is_native): |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 177 | print("skip ", test_file) |
Paul Sokolovsky | 43d4a6f | 2014-05-10 16:52:58 +0300 | [diff] [blame] | 178 | skipped_tests.append(test_name) |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 179 | continue |
Andrew Scheller | 1b997d5 | 2014-04-16 03:28:40 +0100 | [diff] [blame] | 180 | |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 181 | # get expected output |
| 182 | test_file_expected = test_file + '.exp' |
| 183 | if os.path.isfile(test_file_expected): |
| 184 | # expected output given by a file, so read that in |
| 185 | with open(test_file_expected, 'rb') as f: |
| 186 | output_expected = f.read() |
stijn | a4dbc73 | 2014-05-11 12:45:02 +0200 | [diff] [blame] | 187 | if os.name == 'nt': |
| 188 | output_expected = output_expected.replace(b'\n', b'\r\n') |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 189 | else: |
stijn | a4dbc73 | 2014-05-11 12:45:02 +0200 | [diff] [blame] | 190 | # run CPython to work out expected output |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 191 | try: |
| 192 | output_expected = subprocess.check_output([CPYTHON3, '-B', test_file]) |
Paul Sokolovsky | 2cf3810 | 2014-07-12 16:34:51 +0300 | [diff] [blame] | 193 | if args.write_exp: |
| 194 | with open(test_file_expected, 'wb') as f: |
| 195 | f.write(output_expected) |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 196 | except subprocess.CalledProcessError: |
| 197 | output_expected = b'CPYTHON3 CRASH' |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 198 | |
Paul Sokolovsky | 2cf3810 | 2014-07-12 16:34:51 +0300 | [diff] [blame] | 199 | if args.write_exp: |
| 200 | continue |
| 201 | |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 202 | # run Micro Python |
Damien George | 5a04e2c | 2014-10-05 22:27:12 +0100 | [diff] [blame] | 203 | output_mupy = run_micropython(pyb, args, test_file) |
Paul Sokolovsky | 978f4ca | 2014-12-20 16:53:06 +0200 | [diff] [blame] | 204 | if os.name != 'nt': |
| 205 | # It may be the case that we run Windows build under Linux |
| 206 | # (using Wine). |
| 207 | output_mupy = output_mupy.replace(b'\r\n', b'\n') |
Damien George | 4b34c76 | 2014-04-03 23:51:16 +0100 | [diff] [blame] | 208 | |
stijn | f5efefd | 2014-12-18 16:53:46 +0100 | [diff] [blame] | 209 | if output_mupy == b'SKIP\n' or output_mupy == b'SKIP\r\n': |
Paul Sokolovsky | 43d4a6f | 2014-05-10 16:52:58 +0300 | [diff] [blame] | 210 | print("skip ", test_file) |
| 211 | skipped_tests.append(test_name) |
| 212 | continue |
| 213 | |
| 214 | testcase_count += len(output_expected.splitlines()) |
| 215 | |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 216 | filename_expected = test_basename + ".exp" |
| 217 | filename_mupy = test_basename + ".out" |
| 218 | |
| 219 | if output_expected == output_mupy: |
| 220 | print("pass ", test_file) |
| 221 | passed_count += 1 |
| 222 | rm_f(filename_expected) |
| 223 | rm_f(filename_mupy) |
| 224 | else: |
Damien George | 41736f8 | 2014-06-28 10:29:12 +0100 | [diff] [blame] | 225 | with open(filename_expected, "wb") as f: |
| 226 | f.write(output_expected) |
| 227 | with open(filename_mupy, "wb") as f: |
| 228 | f.write(output_mupy) |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 229 | print("FAIL ", test_file) |
| 230 | failed_tests.append(test_name) |
| 231 | |
| 232 | test_count += 1 |
| 233 | |
| 234 | print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) |
| 235 | print("{} tests passed".format(passed_count)) |
| 236 | |
Paul Sokolovsky | 43d4a6f | 2014-05-10 16:52:58 +0300 | [diff] [blame] | 237 | if len(skipped_tests) > 0: |
| 238 | print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests))) |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 239 | if len(failed_tests) > 0: |
| 240 | print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests))) |
| 241 | return False |
| 242 | |
| 243 | # all tests succeeded |
| 244 | return True |
| 245 | |
| 246 | def main(): |
| 247 | cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.') |
| 248 | cmd_parser.add_argument('--pyboard', action='store_true', help='run the tests on the pyboard') |
blmorris | 3b06437 | 2014-10-01 13:53:50 -0400 | [diff] [blame] | 249 | cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device of the pyboard') |
Damien George | a053e37 | 2014-05-31 18:11:01 +0100 | [diff] [blame] | 250 | cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)') |
Paul Sokolovsky | 2cf3810 | 2014-07-12 16:34:51 +0300 | [diff] [blame] | 251 | cmd_parser.add_argument('--write-exp', action='store_true', help='save .exp files to run tests w/o CPython') |
Damien George | 15d2fe8 | 2014-08-29 19:47:10 +0100 | [diff] [blame] | 252 | cmd_parser.add_argument('--emit', default='bytecode', help='Micro Python emitter to use (bytecode or native)') |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 253 | cmd_parser.add_argument('files', nargs='*', help='input test files') |
| 254 | args = cmd_parser.parse_args() |
| 255 | |
| 256 | if args.pyboard: |
| 257 | import pyboard |
blmorris | 3b06437 | 2014-10-01 13:53:50 -0400 | [diff] [blame] | 258 | pyb = pyboard.Pyboard(args.device) |
Damien George | b636d02 | 2014-04-13 13:48:33 +0100 | [diff] [blame] | 259 | pyb.enter_raw_repl() |
Damien George | b636d02 | 2014-04-13 13:48:33 +0100 | [diff] [blame] | 260 | else: |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 261 | pyb = None |
Damien | 39977a5 | 2013-12-29 22:34:42 +0000 | [diff] [blame] | 262 | |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 263 | if len(args.files) == 0: |
stijn | 8ac3b57 | 2014-05-28 14:27:54 +0200 | [diff] [blame] | 264 | if args.test_dirs is None: |
| 265 | if pyb is None: |
| 266 | # run PC tests |
Damien George | 143c341 | 2015-03-13 10:58:34 +0000 | [diff] [blame] | 267 | test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc', 'unicode', 'extmod', 'unix', 'cmdline') |
stijn | 8ac3b57 | 2014-05-28 14:27:54 +0200 | [diff] [blame] | 268 | else: |
| 269 | # run pyboard tests |
Damien George | 612045f | 2014-09-17 22:56:34 +0100 | [diff] [blame] | 270 | test_dirs = ('basics', 'micropython', 'float', 'misc', 'extmod', 'pyb', 'pybnative', 'inlineasm') |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 271 | else: |
stijn | 8ac3b57 | 2014-05-28 14:27:54 +0200 | [diff] [blame] | 272 | # run tests from these directories |
| 273 | test_dirs = args.test_dirs |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 274 | tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files) |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 275 | else: |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 276 | # tests explicitly given |
| 277 | tests = args.files |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 278 | |
Paul Sokolovsky | 2cf3810 | 2014-07-12 16:34:51 +0300 | [diff] [blame] | 279 | if not run_tests(pyb, tests, args): |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 280 | sys.exit(1) |
Markus Siemens | 19ccc6b | 2014-01-27 22:53:28 +0100 | [diff] [blame] | 281 | |
Damien George | 41f768f | 2014-05-03 16:43:27 +0100 | [diff] [blame] | 282 | if __name__ == "__main__": |
| 283 | main() |