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>
This commit is contained in:
committed by
Damien George
parent
4bdf2a2dc0
commit
fdbd23268d
@@ -132,6 +132,11 @@ def get_host_ip(_ip_cache=[]):
|
|||||||
return _ip_cache[0]
|
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:
|
class PyInstance:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
@@ -190,7 +195,7 @@ class PyInstanceSubProcess(PyInstance):
|
|||||||
output = p.stdout
|
output = p.stdout
|
||||||
except subprocess.CalledProcessError as er:
|
except subprocess.CalledProcessError as er:
|
||||||
err = er
|
err = er
|
||||||
return str(output.strip(), "ascii"), err
|
return decode(output.strip()), err
|
||||||
|
|
||||||
def start_script(self, script):
|
def start_script(self, script):
|
||||||
self.popen = subprocess.Popen(
|
self.popen = subprocess.Popen(
|
||||||
@@ -217,7 +222,7 @@ class PyInstanceSubProcess(PyInstance):
|
|||||||
self.finished = self.popen.poll() is not None
|
self.finished = self.popen.poll() is not None
|
||||||
return None, None
|
return None, None
|
||||||
else:
|
else:
|
||||||
return str(out.rstrip(), "ascii"), None
|
return decode(out.rstrip()), None
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
self.popen.stdin.write(data)
|
self.popen.stdin.write(data)
|
||||||
@@ -229,7 +234,7 @@ class PyInstanceSubProcess(PyInstance):
|
|||||||
def wait_finished(self):
|
def wait_finished(self):
|
||||||
self.popen.wait()
|
self.popen.wait()
|
||||||
out = self.popen.stdout.read()
|
out = self.popen.stdout.read()
|
||||||
return str(out, "ascii"), ""
|
return decode(out), ""
|
||||||
|
|
||||||
|
|
||||||
class PyInstancePyboard(PyInstance):
|
class PyInstancePyboard(PyInstance):
|
||||||
@@ -264,7 +269,7 @@ class PyInstancePyboard(PyInstance):
|
|||||||
output = self.pyb.exec_(script)
|
output = self.pyb.exec_(script)
|
||||||
except pyboard.PyboardError as er:
|
except pyboard.PyboardError as er:
|
||||||
err = er
|
err = er
|
||||||
return str(output.strip(), "ascii"), err
|
return decode(output.strip()), err
|
||||||
|
|
||||||
def start_script(self, script):
|
def start_script(self, script):
|
||||||
self.pyb.enter_raw_repl()
|
self.pyb.enter_raw_repl()
|
||||||
@@ -283,13 +288,13 @@ class PyInstancePyboard(PyInstance):
|
|||||||
if out.endswith(b"\x04"):
|
if out.endswith(b"\x04"):
|
||||||
self.finished = True
|
self.finished = True
|
||||||
out = out[:-1]
|
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]
|
err = err[:-1]
|
||||||
if not out and not err:
|
if not out and not err:
|
||||||
return None, None
|
return None, None
|
||||||
else:
|
else:
|
||||||
err = None
|
err = None
|
||||||
return str(out.rstrip(), "ascii"), err
|
return decode(out.rstrip()), err
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
self.pyb.serial.write(data)
|
self.pyb.serial.write(data)
|
||||||
@@ -299,7 +304,7 @@ class PyInstancePyboard(PyInstance):
|
|||||||
|
|
||||||
def wait_finished(self):
|
def wait_finished(self):
|
||||||
out, err = self.pyb.follow(10, None)
|
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):
|
def prepare_test_file_list(test_files):
|
||||||
|
|||||||
Reference in New Issue
Block a user