Skip to content

Commit

Permalink
Fix UTF-8 decoding error in stdout/err
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
arkq committed Mar 4, 2022
1 parent cc6243d commit 808e070
Showing 1 changed file with 17 additions and 30 deletions.
47 changes: 17 additions & 30 deletions scripts/tests/chiptest/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,22 @@
# 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.
"""
threading.Thread.__init__(self)

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
Expand All @@ -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
Expand Down

0 comments on commit 808e070

Please sign in to comment.