summaryrefslogtreecommitdiff
path: root/tests/run-multitests.py
diff options
context:
space:
mode:
authorAngus Gratton <angus@redyak.com.au>2025-07-29 10:45:58 +1000
committerDamien George <damien@micropython.org>2025-07-31 11:17:13 +1000
commitfdbd23268d69d77a411aa5c2d792eaf5e77d454a (patch)
tree1b08d7a8ce760fda98b4d505f97d7ee1bc4d11a4 /tests/run-multitests.py
parent4bdf2a2dc0b418aa014ef1c28b55a563f0c9f7e2 (diff)
tests/run-multitests.py: Escape encoding errors instead of crashing.
It's possible for a test to output non-ASCII characters (for example, due to a hard fault or serial noise or memory corruption). Rather than crashing the test runner, backslash escape those characters and treat them as program output. Refactors the string encoding step to a single helper to avoid copy-paste. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Diffstat (limited to 'tests/run-multitests.py')
-rwxr-xr-xtests/run-multitests.py19
1 files changed, 12 insertions, 7 deletions
diff --git a/tests/run-multitests.py b/tests/run-multitests.py
index 92bd64193..4412d0fde 100755
--- a/tests/run-multitests.py
+++ b/tests/run-multitests.py
@@ -132,6 +132,11 @@ def get_host_ip(_ip_cache=[]):
return _ip_cache[0]
+def decode(output):
+ # Convenience function to convert raw process or serial output to ASCII
+ return str(output, "ascii", "backslashreplace")
+
+
class PyInstance:
def __init__(self):
pass
@@ -190,7 +195,7 @@ class PyInstanceSubProcess(PyInstance):
output = p.stdout
except subprocess.CalledProcessError as er:
err = er
- return str(output.strip(), "ascii"), err
+ return decode(output.strip()), err
def start_script(self, script):
self.popen = subprocess.Popen(
@@ -217,7 +222,7 @@ class PyInstanceSubProcess(PyInstance):
self.finished = self.popen.poll() is not None
return None, None
else:
- return str(out.rstrip(), "ascii"), None
+ return decode(out.rstrip()), None
def write(self, data):
self.popen.stdin.write(data)
@@ -229,7 +234,7 @@ class PyInstanceSubProcess(PyInstance):
def wait_finished(self):
self.popen.wait()
out = self.popen.stdout.read()
- return str(out, "ascii"), ""
+ return decode(out), ""
class PyInstancePyboard(PyInstance):
@@ -264,7 +269,7 @@ class PyInstancePyboard(PyInstance):
output = self.pyb.exec_(script)
except pyboard.PyboardError as er:
err = er
- return str(output.strip(), "ascii"), err
+ return decode(output.strip()), err
def start_script(self, script):
self.pyb.enter_raw_repl()
@@ -283,13 +288,13 @@ class PyInstancePyboard(PyInstance):
if out.endswith(b"\x04"):
self.finished = True
out = out[:-1]
- err = str(self.pyb.read_until(1, b"\x04"), "ascii")
+ err = decode(self.pyb.read_until(1, b"\x04"))
err = err[:-1]
if not out and not err:
return None, None
else:
err = None
- return str(out.rstrip(), "ascii"), err
+ return decode(out.rstrip()), err
def write(self, data):
self.pyb.serial.write(data)
@@ -299,7 +304,7 @@ class PyInstancePyboard(PyInstance):
def wait_finished(self):
out, err = self.pyb.follow(10, None)
- return str(out, "ascii"), str(err, "ascii")
+ return decode(out), decode(err)
def prepare_test_file_list(test_files):