@@ -89,9 +89,12 @@ def open(self, path, mode):
89
89
__import__('__injected_test')
90
90
"""
91
91
92
+ # Platforms associated with the unix port, values of `sys.platform`.
93
+ PC_PLATFORMS = ("darwin" , "linux" , "win32" )
94
+
92
95
# Tests to skip on specific targets.
93
96
# These are tests that are difficult to detect that they should not be run on the given target.
94
- target_tests_to_skip = {
97
+ platform_tests_to_skip = {
95
98
"esp8266" : (
96
99
"micropython/viper_args.py" , # too large
97
100
"micropython/viper_binop_arith.py" , # too large
@@ -161,7 +164,7 @@ def open(self, path, mode):
161
164
"micropython/extreme_exc.py" ,
162
165
"micropython/heapalloc_exc_compressed_emg_exc.py" ,
163
166
),
164
- "wipy " : (
167
+ "WiPy " : (
165
168
"misc/print_exception.py" , # requires error reporting full
166
169
),
167
170
"zephyr" : (
@@ -197,6 +200,53 @@ def convert_regex_escapes(line):
197
200
return bytes ("" .join (cs ), "utf8" )
198
201
199
202
203
+ def get_test_instance (test_instance , baudrate , user , password ):
204
+ if test_instance .startswith ("port:" ):
205
+ _ , port = test_instance .split (":" , 1 )
206
+ elif test_instance == "unix" :
207
+ return None
208
+ elif test_instance == "webassembly" :
209
+ return PyboardNodeRunner ()
210
+ elif test_instance .startswith ("a" ) and test_instance [1 :].isdigit ():
211
+ port = "/dev/ttyACM" + test_instance [1 :]
212
+ elif test_instance .startswith ("u" ) and test_instance [1 :].isdigit ():
213
+ port = "/dev/ttyUSB" + test_instance [1 :]
214
+ elif test_instance .startswith ("c" ) and test_instance [1 :].isdigit ():
215
+ port = "COM" + test_instance [1 :]
216
+ else :
217
+ # Assume it's a device path.
218
+ port = test_instance
219
+
220
+ global pyboard
221
+ sys .path .append (base_path ("../tools" ))
222
+ import pyboard
223
+
224
+ pyb = pyboard .Pyboard (port , baudrate , user , password )
225
+ pyboard .Pyboard .run_script_on_remote_target = run_script_on_remote_target
226
+ pyb .enter_raw_repl ()
227
+ return pyb
228
+
229
+
230
+ def detect_test_platform (pyb , args ):
231
+ # Run a script to detect various bits of information about the target test instance.
232
+ output = run_feature_check (pyb , args , "target_info.py" )
233
+ if output .endswith (b"CRASH" ):
234
+ raise ValueError ("cannot detect platform: {}" .format (output ))
235
+ platform , arch = str (output , "ascii" ).strip ().split ()
236
+ if arch == "None" :
237
+ arch = None
238
+
239
+ args .platform = platform
240
+ args .arch = arch
241
+ if arch and not args .mpy_cross_flags :
242
+ args .mpy_cross_flags = "-march=" + arch
243
+
244
+ print ("platform={}" .format (platform ), end = "" )
245
+ if arch :
246
+ print (" arch={}" .format (arch ), end = "" )
247
+ print ()
248
+
249
+
200
250
def prepare_script_for_target (args , * , script_filename = None , script_text = None , force_plain = False ):
201
251
if force_plain or (not args .via_mpy and args .emit == "bytecode" ):
202
252
if script_filename is not None :
@@ -706,18 +756,18 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
706
756
skip_tests .add ("extmod/ssl_poll.py" )
707
757
708
758
# Skip thread mutation tests on targets that don't have the GIL.
709
- if args .target in ("rp2" , "unix" ):
759
+ if args .platform in PC_PLATFORMS + ("rp2" ,):
710
760
for t in tests :
711
761
if t .startswith ("thread/mutate_" ):
712
762
skip_tests .add (t )
713
763
714
764
# Some tests shouldn't be run on pyboard
715
- if args .target != "unix" :
765
+ if args .platform not in PC_PLATFORMS :
716
766
skip_tests .add ("basics/exception_chain.py" ) # warning is not printed
717
767
skip_tests .add ("micropython/meminfo.py" ) # output is very different to PC output
718
768
719
- # Skip target -specific tests.
720
- skip_tests .update (target_tests_to_skip .get (args .target , ()))
769
+ # Skip platform -specific tests.
770
+ skip_tests .update (platform_tests_to_skip .get (args .platform , ()))
721
771
722
772
# Some tests are known to fail on 64-bit machines
723
773
if pyb is None and platform .architecture ()[0 ] == "64bit" :
@@ -932,17 +982,38 @@ def main():
932
982
formatter_class = argparse .RawDescriptionHelpFormatter ,
933
983
description = """Run and manage tests for MicroPython.
934
984
985
+ By default the tests are run against the unix port of MicroPython. To run it
986
+ against something else, use the -t option. See below for details.
987
+
935
988
Tests are discovered by scanning test directories for .py files or using the
936
989
specified test files. If test files nor directories are specified, the script
937
990
expects to be ran in the tests directory (where this file is located) and the
938
991
builtin tests suitable for the target platform are ran.
992
+
939
993
When running tests, run-tests.py compares the MicroPython output of the test with the output
940
994
produced by running the test through CPython unless a <test>.exp file is found, in which
941
995
case it is used as comparison.
996
+
942
997
If a test fails, run-tests.py produces a pair of <test>.out and <test>.exp files in the result
943
998
directory with the MicroPython output and the expectations, respectively.
944
999
""" ,
945
1000
epilog = """\
1001
+ The -t option accepts the following for the test instance:
1002
+ - unix - use the unix port of MicroPython, specified by the MICROPY_MICROPYTHON
1003
+ environment variable (which defaults to the standard variant of either the unix
1004
+ or windows ports, depending on the host platform)
1005
+ - webassembly - use the webassembly port of MicroPython, specified by the
1006
+ MICROPY_MICROPYTHON_MJS environment variable (which defaults to the standard
1007
+ variant of the webassembly port)
1008
+ - port:<device> - connect to and use the given serial port device
1009
+ - a<n> - connect to and use /dev/ttyACM<n>
1010
+ - u<n> - connect to and use /dev/ttyUSB<n>
1011
+ - c<n> - connect to and use COM<n>
1012
+ - exec:<command> - execute a command and attach to its stdin/stdout
1013
+ - execpty:<command> - execute a command and attach to the printed /dev/pts/<n> device
1014
+ - <a>.<b>.<c>.<d> - connect to the given IPv4 address
1015
+ - anything else specifies a serial port
1016
+
946
1017
Options -i and -e can be multiple and processed in the order given. Regex
947
1018
"search" (vs "match") operation is used. An action (include/exclude) of
948
1019
the last matching regex is used:
@@ -951,11 +1022,8 @@ def main():
951
1022
run-tests.py -e async -i async_foo - include all, exclude async, yet still include async_foo
952
1023
""" ,
953
1024
)
954
- cmd_parser .add_argument ("--target" , default = "unix" , help = "the target platform" )
955
1025
cmd_parser .add_argument (
956
- "--device" ,
957
- default = "/dev/ttyACM0" ,
958
- help = "the serial device or the IP address of the pyboard" ,
1026
+ "-t" , "--test-instance" , default = "unix" , help = "the MicroPython instance to test"
959
1027
)
960
1028
cmd_parser .add_argument (
961
1029
"-b" , "--baudrate" , default = 115200 , help = "the baud rate of the serial device"
@@ -1039,43 +1107,11 @@ def main():
1039
1107
1040
1108
sys .exit (0 )
1041
1109
1042
- LOCAL_TARGETS = (
1043
- "unix" ,
1044
- "webassembly" ,
1045
- )
1046
- EXTERNAL_TARGETS = (
1047
- "pyboard" ,
1048
- "wipy" ,
1049
- "esp8266" ,
1050
- "esp32" ,
1051
- "minimal" ,
1052
- "nrf" ,
1053
- "qemu" ,
1054
- "renesas-ra" ,
1055
- "rp2" ,
1056
- "zephyr" ,
1057
- )
1058
- if args .target in LOCAL_TARGETS :
1059
- pyb = None
1060
- if args .target == "webassembly" :
1061
- pyb = PyboardNodeRunner ()
1062
- elif args .target in EXTERNAL_TARGETS :
1063
- global pyboard
1064
- sys .path .append (base_path ("../tools" ))
1065
- import pyboard
1066
-
1067
- pyb = pyboard .Pyboard (args .device , args .baudrate , args .user , args .password )
1068
- pyboard .Pyboard .run_script_on_remote_target = run_script_on_remote_target
1069
- pyb .enter_raw_repl ()
1070
- else :
1071
- raise ValueError ("target must be one of %s" % ", " .join (LOCAL_TARGETS + EXTERNAL_TARGETS ))
1110
+ # Get the test instance to run on.
1111
+ pyb = get_test_instance (args .test_instance , args .baudrate , args .user , args .password )
1072
1112
1073
- # Automatically detect the native architecture for mpy-cross if not given.
1074
- if not args .mpy_cross_flags :
1075
- output = run_feature_check (pyb , args , "target_info.py" )
1076
- arch = str (output , "ascii" ).strip ()
1077
- if arch != "None" :
1078
- args .mpy_cross_flags = "-march=" + arch
1113
+ # Automatically detect the platform.
1114
+ detect_test_platform (pyb , args )
1079
1115
1080
1116
if args .run_failures and (any (args .files ) or args .test_dirs is not None ):
1081
1117
raise ValueError (
@@ -1091,7 +1127,7 @@ def main():
1091
1127
tests = []
1092
1128
elif len (args .files ) == 0 :
1093
1129
test_extensions = ("*.py" ,)
1094
- if args .target == "webassembly" :
1130
+ if args .platform == "webassembly" :
1095
1131
test_extensions += ("*.js" , "*.mjs" )
1096
1132
1097
1133
if args .test_dirs is None :
@@ -1101,23 +1137,23 @@ def main():
1101
1137
"misc" ,
1102
1138
"extmod" ,
1103
1139
)
1104
- if args .target == "pyboard" :
1140
+ if args .platform == "pyboard" :
1105
1141
# run pyboard tests
1106
1142
test_dirs += ("float" , "stress" , "inlineasm" , "ports/stm32" )
1107
- elif args .target in ( "renesas-ra" ) :
1143
+ elif args .platform == "renesas-ra" :
1108
1144
test_dirs += ("float" , "inlineasm" , "ports/renesas-ra" )
1109
- elif args .target == "rp2" :
1145
+ elif args .platform == "rp2" :
1110
1146
test_dirs += ("float" , "stress" , "thread" , "ports/rp2" )
1111
1147
if "arm" in args .mpy_cross_flags :
1112
1148
test_dirs += ("inlineasm" ,)
1113
- elif args .target == "esp32" :
1149
+ elif args .platform == "esp32" :
1114
1150
test_dirs += ("float" , "stress" , "thread" )
1115
- elif args .target in ("esp8266" , "minimal" , "nrf" ):
1151
+ elif args .platform in ("esp8266" , "minimal" , "nrf" ):
1116
1152
test_dirs += ("float" ,)
1117
- elif args .target == "wipy " :
1153
+ elif args .platform == "WiPy " :
1118
1154
# run WiPy tests
1119
1155
test_dirs += ("ports/cc3200" ,)
1120
- elif args .target == "unix" :
1156
+ elif args .platform in PC_PLATFORMS :
1121
1157
# run PC tests
1122
1158
test_dirs += (
1123
1159
"float" ,
@@ -1128,13 +1164,13 @@ def main():
1128
1164
"cmdline" ,
1129
1165
"ports/unix" ,
1130
1166
)
1131
- elif args .target == "qemu" :
1167
+ elif args .platform == "qemu" :
1132
1168
test_dirs += (
1133
1169
"float" ,
1134
1170
"inlineasm" ,
1135
1171
"ports/qemu" ,
1136
1172
)
1137
- elif args .target == "webassembly" :
1173
+ elif args .platform == "webassembly" :
1138
1174
test_dirs += ("float" , "ports/webassembly" )
1139
1175
else :
1140
1176
# run tests from these directories
0 commit comments