Improve import sanity test output handling. (#52136)

Handling of unexpected output for the following is improved:

- stdout
- stderr
- warnings
This commit is contained in:
Matt Clay 2019-02-12 17:32:57 -08:00 committed by GitHub
parent 0a461380a3
commit 1f3a74c0c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -8,6 +8,7 @@ import os
import re import re
import sys import sys
import traceback import traceback
import warnings
try: try:
import importlib.util import importlib.util
@ -146,6 +147,7 @@ class Capture(object):
def __init__(self): def __init__(self):
self.stdout = StringIO() self.stdout = StringIO()
self.stderr = StringIO() self.stderr = StringIO()
self.warnings = []
def capture_report(path, capture, messages): def capture_report(path, capture, messages):
@ -155,11 +157,37 @@ def capture_report(path, capture, messages):
:type messages: set[str] :type messages: set[str]
""" """
if capture.stdout.getvalue(): if capture.stdout.getvalue():
message = '%s:%d:%d: %s: %s' % (path, 0, 0, 'Output', 'Import resulted in output to stdout.') first = capture.stdout.getvalue().strip().splitlines()[0].strip()
message = '%s:%d:%d: %s: %s' % (path, 0, 0, 'StandardOutputUsed', first)
report_message(message, messages) report_message(message, messages)
if capture.stderr.getvalue(): if capture.stderr.getvalue():
message = '%s:%d:%d: %s: %s' % (path, 0, 0, 'Output', 'Import resulted in output to stderr.') first = capture.stderr.getvalue().strip().splitlines()[0].strip()
message = '%s:%d:%d: %s: %s' % (path, 0, 0, 'StandardErrorUsed', first)
report_message(message, messages)
for warning in capture.warnings:
msg = re.sub(r'\s+', ' ', '%s' % warning.message).strip()
filepath = os.path.relpath(warning.filename)
lineno = warning.lineno
import_dir = 'test/runner/.tox/import/'
minimal_dir = 'test/runner/.tox/minimal-'
if filepath.startswith('../') or filepath.startswith(minimal_dir):
# The warning occurred outside our source tree.
# The best we can do is to report the file which was tested that triggered the warning.
# If the responsible import is in shared code this warning will be repeated for each file tested which imports the shared code.
msg += ' (in %s:%d)' % (warning.filename, warning.lineno)
filepath = path
lineno = 0
elif filepath.startswith(import_dir):
# Strip the import dir from warning paths in shared code.
# Needed when warnings occur in places like module_utils but are caught by the modules importing the module_utils.
filepath = os.path.relpath(filepath, import_dir)
message = '%s:%d:%d: %s: %s' % (filepath, lineno, 0, warning.category.__name__, msg)
report_message(message, messages) report_message(message, messages)
@ -184,11 +212,14 @@ def capture_output(capture):
sys.stdout = capture.stdout sys.stdout = capture.stdout
sys.stderr = capture.stderr sys.stderr = capture.stderr
try: with warnings.catch_warnings(record=True) as captured_warnings:
yield try:
finally: yield
sys.stdout = old_stdout finally:
sys.stderr = old_stderr capture.warnings = captured_warnings
sys.stdout = old_stdout
sys.stderr = old_stderr
if __name__ == '__main__': if __name__ == '__main__':