summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2021-04-04 11:33:14 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-04-06 09:30:10 +0100
commit855fbb6f99655384bae413b2fe4909fd003fa866 (patch)
tree41f8e1517ae617aad840981dfc4c2e2fee756074
parentf0c5a904d9ebe1e2ae4f691273e06e8dfd86cb56 (diff)
downloadpoky-855fbb6f99655384bae413b2fe4909fd003fa866.tar.gz
oeqa/concurrencytest: Fix display of test stdout/stderr
If oe-selftest is run with -j, the output to stdout/stderr is being lost at present. Capture this and display it upon test failure. We have code that previously tried to enable this but it wasn't functioning correctly. This should give more usable error reports on the autobuilder. This code will mix stdout and stderr as the output is streamed from the test server without markup. This is most in keeping with subunit/testools though and the easiest way to handle the various challenges here as far as I can see. (From OE-Core rev: 6a954ce5834c8026adecff8478c3d827640bc647) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oeqa/core/utils/concurrencytest.py33
1 files changed, 17 insertions, 16 deletions
diff --git a/meta/lib/oeqa/core/utils/concurrencytest.py b/meta/lib/oeqa/core/utils/concurrencytest.py
index 347dc89602..161a2f6e90 100644
--- a/meta/lib/oeqa/core/utils/concurrencytest.py
+++ b/meta/lib/oeqa/core/utils/concurrencytest.py
@@ -48,11 +48,15 @@ _all__ = [
48# 48#
49class BBThreadsafeForwardingResult(ThreadsafeForwardingResult): 49class BBThreadsafeForwardingResult(ThreadsafeForwardingResult):
50 50
51 def __init__(self, target, semaphore, threadnum, totalinprocess, totaltests): 51 def __init__(self, target, semaphore, threadnum, totalinprocess, totaltests, output, finalresult):
52 super(BBThreadsafeForwardingResult, self).__init__(target, semaphore) 52 super(BBThreadsafeForwardingResult, self).__init__(target, semaphore)
53 self.threadnum = threadnum 53 self.threadnum = threadnum
54 self.totalinprocess = totalinprocess 54 self.totalinprocess = totalinprocess
55 self.totaltests = totaltests 55 self.totaltests = totaltests
56 self.buffer = True
57 self.outputbuf = output
58 self.finalresult = finalresult
59 self.finalresult.buffer = True
56 60
57 def _add_result_with_semaphore(self, method, test, *args, **kwargs): 61 def _add_result_with_semaphore(self, method, test, *args, **kwargs):
58 self.semaphore.acquire() 62 self.semaphore.acquire()
@@ -71,6 +75,8 @@ class BBThreadsafeForwardingResult(ThreadsafeForwardingResult):
71 test.id()) 75 test.id())
72 finally: 76 finally:
73 self.semaphore.release() 77 self.semaphore.release()
78 self.finalresult._stderr_buffer = io.StringIO(initial_value=self.outputbuf.getvalue().decode("utf-8"))
79 self.finalresult._stdout_buffer = io.StringIO()
74 super(BBThreadsafeForwardingResult, self)._add_result_with_semaphore(method, test, *args, **kwargs) 80 super(BBThreadsafeForwardingResult, self)._add_result_with_semaphore(method, test, *args, **kwargs)
75 81
76class ProxyTestResult: 82class ProxyTestResult:
@@ -196,19 +202,11 @@ class ConcurrentTestSuite(unittest.TestSuite):
196 queue = Queue() 202 queue = Queue()
197 semaphore = threading.Semaphore(1) 203 semaphore = threading.Semaphore(1)
198 result.threadprogress = {} 204 result.threadprogress = {}
199 for i, (testserver, testnum) in enumerate(testservers): 205 for i, (testserver, testnum, output) in enumerate(testservers):
200 result.threadprogress[i] = [] 206 result.threadprogress[i] = []
201 process_result = BBThreadsafeForwardingResult( 207 process_result = BBThreadsafeForwardingResult(
202 ExtraResultsDecoderTestResult(result), 208 ExtraResultsDecoderTestResult(result),
203 semaphore, i, testnum, totaltests) 209 semaphore, i, testnum, totaltests, output, result)
204 # Force buffering of stdout/stderr so the console doesn't get corrupted by test output
205 # as per default in parent code
206 process_result.buffer = True
207 # We have to add a buffer object to stdout to keep subunit happy
208 process_result._stderr_buffer = io.StringIO()
209 process_result._stderr_buffer.buffer = dummybuf(process_result._stderr_buffer)
210 process_result._stdout_buffer = io.StringIO()
211 process_result._stdout_buffer.buffer = dummybuf(process_result._stdout_buffer)
212 reader_thread = threading.Thread( 210 reader_thread = threading.Thread(
213 target=self._run_test, args=(testserver, process_result, queue)) 211 target=self._run_test, args=(testserver, process_result, queue))
214 threads[testserver] = reader_thread, process_result 212 threads[testserver] = reader_thread, process_result
@@ -273,10 +271,11 @@ def fork_for_tests(concurrency_num, suite):
273 newsi = os.open(os.devnull, os.O_RDWR) 271 newsi = os.open(os.devnull, os.O_RDWR)
274 os.dup2(newsi, sys.stdin.fileno()) 272 os.dup2(newsi, sys.stdin.fileno())
275 273
274 # Send stdout/stderr over the stream
275 os.dup2(c2pwrite, sys.stdout.fileno())
276 os.dup2(c2pwrite, sys.stderr.fileno())
277
276 subunit_client = TestProtocolClient(stream) 278 subunit_client = TestProtocolClient(stream)
277 # Force buffering of stdout/stderr so the console doesn't get corrupted by test output
278 # as per default in parent code
279 subunit_client.buffer = True
280 subunit_result = AutoTimingTestResultDecorator(subunit_client) 279 subunit_result = AutoTimingTestResultDecorator(subunit_client)
281 unittest_result = process_suite.run(ExtraResultsEncoderTestResult(subunit_result)) 280 unittest_result = process_suite.run(ExtraResultsEncoderTestResult(subunit_result))
282 if ourpid != os.getpid(): 281 if ourpid != os.getpid():
@@ -306,8 +305,10 @@ def fork_for_tests(concurrency_num, suite):
306 else: 305 else:
307 os.close(c2pwrite) 306 os.close(c2pwrite)
308 stream = os.fdopen(c2pread, 'rb', 1) 307 stream = os.fdopen(c2pread, 'rb', 1)
309 testserver = ProtocolTestCase(stream) 308 # Collect stdout/stderr into an io buffer
310 testservers.append((testserver, numtests)) 309 output = io.BytesIO()
310 testserver = ProtocolTestCase(stream, passthrough=output)
311 testservers.append((testserver, numtests, output))
311 return testservers, totaltests 312 return testservers, totaltests
312 313
313def partition_tests(suite, count): 314def partition_tests(suite, count):