Skip to content

Commit

Permalink
[chiptest] 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 authored and woody-apple committed Mar 2, 2022
1 parent 84f5dab commit d67c462
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 d67c462

Please sign in to comment.