diff --git a/test/runner/importer.py b/test/runner/importer.py index 8f9f91ad74..8554436d00 100755 --- a/test/runner/importer.py +++ b/test/runner/importer.py @@ -3,12 +3,18 @@ from __future__ import absolute_import, print_function +import contextlib import imp import os import re import sys import traceback +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + def main(): """Main program function.""" @@ -16,10 +22,16 @@ def main(): messages = set() for path in sys.argv[1:]: + capture = Capture() try: with open(path, 'r') as module_fd: - imp.load_module('module_import_test', module_fd, os.path.abspath(path), ('.py', 'r', imp.PY_SOURCE)) - except Exception as ex: # pylint: disable=locally-disabled, broad-except + with capture_output(capture): + imp.load_module('module_import_test', module_fd, os.path.abspath(path), ('.py', 'r', imp.PY_SOURCE)) + + capture_report(path, capture, messages) + except BaseException as ex: # pylint: disable=locally-disabled, broad-except + capture_report(path, capture, messages) + exc_type, _, exc_tb = sys.exc_info() message = str(ex) results = list(reversed(traceback.extract_tb(exc_tb))) @@ -61,5 +73,48 @@ def main(): if messages: exit(10) + +class Capture(object): + """Captured output and/or exception.""" + def __init__(self): + self.stdout = StringIO() + self.stderr = StringIO() + + +def capture_report(path, capture, messages): + """Report on captured output. + :type path: str + :type capture: Capture + :type messages: set[str] + """ + if capture.stdout.getvalue(): + message = '%s:%d:%d: %s: %s' % (path, 0, 0, 'Output', 'Import resulted in output to stdout.') + messages.add(message) + print(message) + + if capture.stderr.getvalue(): + message = '%s:%d:%d: %s: %s' % (path, 0, 0, 'Output', 'Import resulted in output to stderr.') + messages.add(message) + print(message) + + +@contextlib.contextmanager +def capture_output(capture): + """Capture sys.stdout and sys.stderr. + :type capture: Capture + """ + old_stdout = sys.stdout + old_stderr = sys.stderr + + sys.stdout = capture.stdout + sys.stderr = capture.stderr + + try: + yield + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + if __name__ == '__main__': main()