mirror of
https://github.com/micropython/micropython.git
synced 2026-01-07 04:30:24 +01:00
tests/run-tests.py: Add support for board-specific target_wiring config.
There are currently a few "hardware" tests that need external board connections to be made for them to work, such as bridging a pair of pins. For example, all tests in `tests/extmod_hardware` need some kind of connection. Along with the physical connections -- which are different for each board -- there needs to be corresponding Python settings, eg which UART instance to use and which pins for TX/RX. These settings are currently hard-coded in each test file. That has a few problems: - settings are repeated, eg all the UART tests have pretty much the same settings code duplicated across them - changing the settings means changing many files - adding a new board means adding a lot of code - the tests get bigger and bigger with each new board that they support, meaning they may not fit on targets with a small amount of RAM (that's already the case with `tests/extmod_hardware/machine_pwm.py`) - if you have a custom board you have to manually edit the test to add your own settings This commit aims to solve all the above problems by splitting the board- specific settings out into separate files, one for each board (or port). They are placed in the `tests/target_wiring/` directory. The `run-tests.py` test runner then loads the appropriate configuration for the target that is being tested, sends it to the board so it's available as `import target_wiring` (without needing a filesystem), and then executes the test. Note tht only tests that need `target_wiring` have it loaded. This commit adds support for this `target_wiring` scheme. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -216,6 +216,9 @@ platform_tests_to_skip = {
|
||||
),
|
||||
}
|
||||
|
||||
# Tests that require `import target_wiring` to work.
|
||||
tests_requiring_target_wiring = ()
|
||||
|
||||
|
||||
def rm_f(fname):
|
||||
if os.path.exists(fname):
|
||||
@@ -310,6 +313,7 @@ def detect_test_platform(pyb, args):
|
||||
args.float_prec = float_prec
|
||||
args.unicode = unicode
|
||||
|
||||
# Print the detected information about the target.
|
||||
print("platform={}".format(platform), end="")
|
||||
if arch:
|
||||
print(" arch={}".format(arch), end="")
|
||||
@@ -321,7 +325,43 @@ def detect_test_platform(pyb, args):
|
||||
print(" float={}-bit".format(float_prec), end="")
|
||||
if unicode:
|
||||
print(" unicode", end="")
|
||||
print()
|
||||
|
||||
|
||||
def detect_target_wiring_script(pyb, args):
|
||||
tw_data = b""
|
||||
tw_source = None
|
||||
if args.target_wiring:
|
||||
# A target_wiring path is explicitly provided, so use that.
|
||||
tw_source = args.target_wiring
|
||||
with open(tw_source, "rb") as f:
|
||||
tw_data = f.read()
|
||||
elif hasattr(pyb, "exec_raw") and pyb.exec_raw("import target_wiring") == (b"", b""):
|
||||
# The board already has a target_wiring module available, so use that.
|
||||
tw_source = "on-device"
|
||||
else:
|
||||
port = platform_to_port(args.platform)
|
||||
build = args.build
|
||||
tw_board_exact = None
|
||||
tw_board_partial = None
|
||||
tw_port = None
|
||||
for file in os.listdir("target_wiring"):
|
||||
file_base = file.removesuffix(".py")
|
||||
if file_base == build:
|
||||
# A file matching the target's board/build name.
|
||||
tw_board_exact = file
|
||||
elif file_base.endswith("x") and build.startswith(file_base.removesuffix("x")):
|
||||
# A file with a partial match to the target's board/build name.
|
||||
tw_board_partial = file
|
||||
elif file_base == port:
|
||||
# A file matching the target's port.
|
||||
tw_port = file
|
||||
tw_source = tw_board_exact or tw_board_partial or tw_port
|
||||
if tw_source:
|
||||
with open("target_wiring/" + tw_source, "rb") as f:
|
||||
tw_data = f.read()
|
||||
if tw_source:
|
||||
print(" target_wiring={}".format(tw_source), end="")
|
||||
pyb.target_wiring_script = tw_data
|
||||
|
||||
|
||||
def prepare_script_for_target(args, *, script_text=None, force_plain=False):
|
||||
@@ -382,6 +422,12 @@ def run_script_on_remote_target(pyb, args, test_file, is_special):
|
||||
try:
|
||||
had_crash = False
|
||||
pyb.enter_raw_repl()
|
||||
if test_file.endswith(tests_requiring_target_wiring) and pyb.target_wiring_script:
|
||||
pyb.exec_(
|
||||
"import sys;sys.modules['target_wiring']=__build_class__(lambda:exec("
|
||||
+ repr(pyb.target_wiring_script)
|
||||
+ "),'target_wiring')"
|
||||
)
|
||||
output_mupy = pyb.exec_(script, timeout=TEST_TIMEOUT)
|
||||
except pyboard.PyboardError as e:
|
||||
had_crash = True
|
||||
@@ -1285,6 +1331,11 @@ the last matching regex is used:
|
||||
default=None,
|
||||
help="prologue python file to execute before module import",
|
||||
)
|
||||
cmd_parser.add_argument(
|
||||
"--target-wiring",
|
||||
default=None,
|
||||
help="force the given script to be used as target_wiring.py",
|
||||
)
|
||||
args = cmd_parser.parse_args()
|
||||
|
||||
prologue = ""
|
||||
@@ -1381,6 +1432,13 @@ the last matching regex is used:
|
||||
# tests explicitly given
|
||||
tests = args.files
|
||||
|
||||
# If any tests need it, prepare the target_wiring script for the target.
|
||||
if pyb and any(test.endswith(tests_requiring_target_wiring) for test in tests):
|
||||
detect_target_wiring_script(pyb, args)
|
||||
|
||||
# End the target information line.
|
||||
print()
|
||||
|
||||
if not args.keep_path:
|
||||
# Clear search path to make sure tests use only builtin modules, those in
|
||||
# extmod, and a path to unittest in case it's needed.
|
||||
|
||||
Reference in New Issue
Block a user