7
7
import argparse
8
8
import inspect
9
9
import re
10
- import threading
10
+ from glob import glob
11
11
import multiprocessing
12
12
from multiprocessing .pool import ThreadPool
13
- from glob import glob
13
+ import threading
14
+ import tempfile
14
15
15
16
# See stackoverflow.com/questions/2632199: __file__ nor sys.argv[0]
16
17
# are guaranteed to always work, this one should though.
@@ -169,26 +170,27 @@ def send_get(what):
169
170
170
171
# if running via .mpy, first compile the .py file
171
172
if args .via_mpy :
173
+ mpy_modname = tempfile .mktemp (dir = "" )
174
+ mpy_filename = mpy_modname + ".mpy"
172
175
subprocess .check_output (
173
176
[MPYCROSS ]
174
177
+ args .mpy_cross_flags .split ()
175
- + ["-o" , "mpytest.mpy" , "-X" , "emit=" + args .emit , test_file ]
178
+ + ["-o" , mpy_filename , "-X" , "emit=" + args .emit , test_file ]
176
179
)
177
- cmdlist .extend (["-m" , "mpytest" ])
180
+ cmdlist .extend (["-m" , mpy_modname ])
178
181
else :
179
182
cmdlist .append (test_file )
180
183
181
184
# run the actual test
182
- e = {"LANG" : "en_US.UTF-8" , "MICROPYPATH" : os .environ ["MICROPYPATH" ]}
183
185
try :
184
- output_mupy = subprocess .check_output (cmdlist , env = e , stderr = subprocess .STDOUT )
185
- except subprocess .CalledProcessError as error :
186
+ output_mupy = subprocess .check_output (cmdlist , stderr = subprocess .STDOUT )
187
+ except subprocess .CalledProcessError as er :
186
188
had_crash = True
187
- output_mupy = error .output + b"CRASH"
189
+ output_mupy = er .output + b"CRASH"
188
190
189
191
# clean up if we had an intermediate .mpy file
190
192
if args .via_mpy :
191
- rm_f ("mpytest.mpy" )
193
+ rm_f (mpy_filename )
192
194
193
195
else :
194
196
# run on pyboard
@@ -200,7 +202,7 @@ def send_get(what):
200
202
if not is_special and e .args [0 ] == "exception" :
201
203
output_mupy = e .args [1 ] + e .args [2 ] + b"CRASH"
202
204
else :
203
- output_mupy = b"CRASH "
205
+ output_mupy = bytes ( e . args [ 0 ], "ascii" ) + b" \n CRASH "
204
206
205
207
# canonical form for all ports/platforms is to use \n for end-of-line
206
208
output_mupy = output_mupy .replace (b"\r \n " , b"\n " )
@@ -241,10 +243,9 @@ def send_get(what):
241
243
else :
242
244
# a regex
243
245
if lines_exp [i ][1 ].match (lines_mupy [i_mupy ]):
244
- # print("match", lines_exp[i][0], lines_mupy[i_mupy])
245
246
lines_mupy [i_mupy ] = lines_exp [i ][0 ]
246
247
else :
247
- # print("don't match: %r %s" % (lines_exp[i][0 ], lines_mupy[i_mupy])) # DEBUG
248
+ # print("don't match: %r %s" % (lines_exp[i][1 ], lines_mupy[i_mupy])) # DEBUG
248
249
pass
249
250
i_mupy += 1
250
251
if i_mupy >= len (lines_mupy ):
@@ -266,6 +267,9 @@ def __init__(self, start=0):
266
267
self ._value = start
267
268
self ._lock = threading .Lock ()
268
269
270
+ def increment (self ):
271
+ self .add (1 )
272
+
269
273
def add (self , to_add ):
270
274
with self ._lock :
271
275
self ._value += to_add
@@ -306,11 +310,11 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
306
310
if not (args .list_tests or args .write_exp ):
307
311
# Even if we run completely different tests in a different directory,
308
312
# we need to access feature_checks from the same directory as the
309
- # run-tests script itself so use base_path.
313
+ # run-tests.py script itself so use base_path.
310
314
311
315
# Check if micropython.native is supported, and skip such tests if it's not
312
316
output = run_feature_check (pyb , args , base_path , "native_check.py" )
313
- if output . endswith ( b"CRASH" ) :
317
+ if output != b"native \n " :
314
318
skip_native = True
315
319
316
320
# Check if arbitrary-precision integers are supported, and skip such tests if it's not
@@ -325,7 +329,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
325
329
326
330
# Check if set type (and set literals) is supported, and skip such tests if it's not
327
331
output = run_feature_check (pyb , args , base_path , "set_check.py" )
328
- if output . endswith ( b"CRASH" ) :
332
+ if output != b"{1} \n " :
329
333
skip_set_type = True
330
334
331
335
# Check if slice is supported, and skip such tests if it's not
@@ -335,12 +339,12 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
335
339
336
340
# Check if async/await keywords are supported, and skip such tests if it's not
337
341
output = run_feature_check (pyb , args , base_path , "async_check.py" )
338
- if output . endswith ( b"CRASH" ) :
342
+ if output != b"async \n " :
339
343
skip_async = True
340
344
341
345
# Check if const keyword (MicroPython extension) is supported, and skip such tests if it's not
342
346
output = run_feature_check (pyb , args , base_path , "const.py" )
343
- if output . endswith ( b"CRASH" ) :
347
+ if output != b"1 \n " :
344
348
skip_const = True
345
349
346
350
# Check if __rOP__ special methods are supported, and skip such tests if it's not
@@ -365,10 +369,10 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
365
369
366
370
upy_byteorder = run_feature_check (pyb , args , base_path , "byteorder.py" )
367
371
upy_float_precision = run_feature_check (pyb , args , base_path , "float.py" )
368
- if upy_float_precision .endswith (b"CRASH" ):
369
- upy_float_precision = 0
370
- else :
372
+ try :
371
373
upy_float_precision = int (upy_float_precision )
374
+ except ValueError :
375
+ upy_float_precision = 0
372
376
has_complex = run_feature_check (pyb , args , base_path , "complex.py" ) == b"complex\n "
373
377
has_coverage = run_feature_check (pyb , args , base_path , "coverage.py" ) == b"coverage\n "
374
378
cpy_byteorder = subprocess .check_output (
@@ -545,7 +549,7 @@ def run_one_test(test_file):
545
549
is_bytearray = test_name .startswith ("bytearray" ) or test_name .endswith ("_bytearray" )
546
550
is_set_type = test_name .startswith ("set_" ) or test_name .startswith ("frozenset" )
547
551
is_slice = test_name .find ("slice" ) != - 1 or test_name in misc_slice_tests
548
- is_async = test_name .startswith ("async_" )
552
+ is_async = test_name .startswith (( "async_" , "uasyncio_" ) )
549
553
is_const = test_name .startswith ("const" )
550
554
is_io_module = test_name .startswith ("io_" )
551
555
@@ -610,26 +614,22 @@ def run_one_test(test_file):
610
614
filename_mupy = os .path .join (result_dir , test_basename + ".out" )
611
615
612
616
if output_expected == output_mupy :
613
- # print("pass ", test_file)
614
- passed_count .add ( 1 )
617
+ print ("pass " , test_file )
618
+ passed_count .increment ( )
615
619
rm_f (filename_expected )
616
620
rm_f (filename_mupy )
617
621
else :
618
622
with open (filename_expected , "wb" ) as f :
619
623
f .write (output_expected )
620
624
with open (filename_mupy , "wb" ) as f :
621
625
f .write (output_mupy )
622
- print ("### Expected" )
623
- print (output_expected )
624
- print ("### Actual" )
625
- print (output_mupy )
626
626
print ("FAIL " , test_file )
627
- failed_tests .append (test_file )
627
+ failed_tests .append (test_name )
628
628
629
- test_count .add ( 1 )
629
+ test_count .increment ( )
630
630
631
- if args .list_tests :
632
- return True
631
+ if pyb or args .list_tests :
632
+ num_threads = 1
633
633
634
634
if num_threads > 1 :
635
635
pool = ThreadPool (num_threads )
@@ -638,25 +638,22 @@ def run_one_test(test_file):
638
638
for test in tests :
639
639
run_one_test (test )
640
640
641
+ if args .list_tests :
642
+ return True
643
+
641
644
print (
642
645
"{} tests performed ({} individual testcases)" .format (
643
646
test_count .value , testcase_count .value
644
647
)
645
648
)
646
649
print ("{} tests passed" .format (passed_count .value ))
647
650
648
- if len (skipped_tests .value ) > 0 :
649
- print (
650
- "{} tests skipped: {}" .format (
651
- len (skipped_tests .value ), " " .join (sorted (skipped_tests .value ))
652
- )
653
- )
654
- if len (failed_tests .value ) > 0 :
655
- print (
656
- "{} tests failed: {}" .format (
657
- len (failed_tests .value ), " " .join (sorted (failed_tests .value ))
658
- )
659
- )
651
+ skipped_tests = sorted (skipped_tests .value )
652
+ if len (skipped_tests ) > 0 :
653
+ print ("{} tests skipped: {}" .format (len (skipped_tests ), " " .join (skipped_tests )))
654
+ failed_tests = sorted (failed_tests .value )
655
+ if len (failed_tests ) > 0 :
656
+ print ("{} tests failed: {}" .format (len (failed_tests ), " " .join (failed_tests )))
660
657
return False
661
658
662
659
# all tests succeeded
@@ -758,18 +755,11 @@ def main():
758
755
cmd_parser .add_argument (
759
756
"-j" ,
760
757
"--jobs" ,
761
- default = 1 ,
758
+ default = multiprocessing . cpu_count () ,
762
759
metavar = "N" ,
763
760
type = int ,
764
761
help = "Number of tests to run simultaneously" ,
765
762
)
766
- cmd_parser .add_argument (
767
- "--auto-jobs" ,
768
- action = "store_const" ,
769
- dest = "jobs" ,
770
- const = multiprocessing .cpu_count (),
771
- help = "Set the -j values to the CPU (thread) count" ,
772
- )
773
763
cmd_parser .add_argument ("files" , nargs = "*" , help = "input test files" )
774
764
cmd_parser .add_argument (
775
765
"--print-failures" ,
@@ -869,9 +859,7 @@ def main():
869
859
870
860
if not args .keep_path :
871
861
# clear search path to make sure tests use only builtin modules and those in extmod
872
- os .environ ["MICROPYPATH" ] = (
873
- os .pathsep + base_path ("../extmod" ) + os .pathsep + base_path ("." )
874
- )
862
+ os .environ ["MICROPYPATH" ] = os .pathsep + base_path ("../extmod" )
875
863
876
864
try :
877
865
os .makedirs (args .result_dir , exist_ok = True )
0 commit comments