From 282396f27addf4ae6586865ccf449f60753a106c Mon Sep 17 00:00:00 2001 From: "R. David Murray" Date: Sun, 18 Oct 2009 21:12:37 +0000 Subject: Issue #7151: regrtest would generate a JSON failure if there was output to stderr during the test run and it happened to get emitted after the worker thread emitted the result JSON. Now we capture stdout and stderr separately, which avoids that problem. It also means that _all_ stderr output is after all stdout output when we print the test results, but that seems acceptable, since output ordering is not guaranteed anyway. The patch also moves the emit of the test name into the output block generated after the test completes. Otherwise test names and test output/errors were mixed in the terminal display, making it difficult to determine which test generated the output. --- Lib/test/regrtest.py | 29 ++++++++++++++++------------- Misc/NEWS | 3 +++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index be88716..d8456df 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -426,35 +426,38 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, try: test, args_tuple = pending.popleft() except IndexError: - output.put((None, None, None)) + output.put((None, None, None, None)) return - if not quiet: - print test - sys.stdout.flush() # -E is needed by some tests, e.g. test_import popen = Popen([sys.executable, '-E', '-m', 'test.regrtest', '--slaveargs', json.dumps(args_tuple)], - stdout=PIPE, stderr=STDOUT, + stdout=PIPE, stderr=PIPE, universal_newlines=True, close_fds=True) - out = popen.communicate()[0].strip() - out = debug_output_pat.sub("", out) - out, _, result = out.strip().rpartition("\n") + stdout, stderr = popen.communicate() + # Strip last refcount output line if it exists, since it + # comes from the shutdown of the interpreter in the subcommand. + stderr = debug_output_pat.sub("", stderr) + stdout, _, result = stdout.strip().rpartition("\n") result = json.loads(result) - output.put((test, out.strip(), result)) + if not quiet: + stdout = test+'\n'+stdout + output.put((test, stdout.rstrip(), stderr.rstrip(), result)) except BaseException: - output.put((None, None, None)) + output.put((None, None, None, None)) raise workers = [Thread(target=work) for i in range(use_mp)] for worker in workers: worker.start() finished = 0 while finished < use_mp: - test, out, result = output.get() + test, stdout, stderr, result = output.get() if test is None: finished += 1 continue - if out: - print out + if stdout: + print stdout + if stderr: + print >>sys.stderr, stderr if result[0] == -4: assert result[1] == 'KeyboardInterrupt' pending.clear() diff --git a/Misc/NEWS b/Misc/NEWS index d694056..f684325 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1473,6 +1473,9 @@ Extension Modules Tests ----- +- Issue #7151: fixed regrtest -j so that output to stderr from a test no + longer runs the risk of causing the worker thread to fail. + - Issue #7055: test___all__ now greedily detects all modules which have an __all__ attribute, rather than using a hardcoded and incomplete list. -- cgit v0.12