From d67c4625daf4aabc8f8b23bfa103bfb4af4e282b Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Mon, 28 Feb 2022 10:17:33 +0100 Subject: [PATCH] [chiptest] Fix UTF-8 decoding error in stdout/err Previous implementation was pron to decoding errors when test output was a byte-string instead of correct UTF-8 text. This commit also simplifies PIPE creation for the purpose of collecting logs asynchronously. The PIPE object is created by the Popen function itself, so we will hot have to worry about bare file descriptors any more. --- scripts/tests/chiptest/runner.py | 47 ++++++++++++-------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/scripts/tests/chiptest/runner.py b/scripts/tests/chiptest/runner.py index 03af6af0e32c22..56660c0b5258be 100644 --- a/scripts/tests/chiptest/runner.py +++ b/scripts/tests/chiptest/runner.py @@ -13,17 +13,14 @@ # limitations under the License. import logging -import os -import pty import re import subprocess -import sys import threading class LogPipe(threading.Thread): - def __init__(self, level, capture_delegate=None, name=None): + def __init__(self, level, pipe, capture_delegate=None, name=None): """ Setup the object with a logger and a loglevel and start the thread. """ @@ -31,12 +28,7 @@ def __init__(self, level, capture_delegate=None, name=None): self.daemon = False self.level = level - if sys.platform == 'darwin': - self.fd_read, self.fd_write = pty.openpty() - else: - self.fd_read, self.fd_write = os.pipe() - - self.pipeReader = os.fdopen(self.fd_read) + self.pipe = pipe self.captured_logs = [] self.capture_delegate = capture_delegate self.name = name @@ -56,43 +48,38 @@ def FindLastMatchingLine(self, matcher): return match return None - def fileno(self): - """Return the write file descriptor of the pipe.""" - return self.fd_write - def run(self): """Run the thread, logging everything.""" - for line in iter(self.pipeReader.readline, ''): + for line in iter(self.pipe.readline, b''): + line = line.decode('utf-8', 'ignore') logging.log(self.level, line.strip('\n')) self.captured_logs.append(line) if self.capture_delegate: self.capture_delegate.Log(self.name, line) - self.pipeReader.close() - - def close(self): - """Close the write end of the pipe.""" - os.close(self.fd_write) - class Runner: + def __init__(self, capture_delegate=None): self.capture_delegate = capture_delegate def RunSubprocess(self, cmd, name, wait=True, dependencies=[]): - outpipe = LogPipe( - logging.DEBUG, capture_delegate=self.capture_delegate, - name=name + ' OUT') - errpipe = LogPipe( - logging.INFO, capture_delegate=self.capture_delegate, - name=name + ' ERR') if self.capture_delegate: self.capture_delegate.Log(name, 'EXECUTING %r' % cmd) - s = subprocess.Popen(cmd, stdout=outpipe, stderr=errpipe) - outpipe.close() - errpipe.close() + s = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + outpipe = LogPipe( + logging.DEBUG, s.stdout, + capture_delegate=self.capture_delegate, + name=name + ' OUT') + + errpipe = LogPipe( + logging.INFO, s.stderr, + capture_delegate=self.capture_delegate, + name=name + ' ERR') if not wait: return s, outpipe, errpipe