aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/mtest.py
diff options
context:
space:
mode:
authorMarcel Hollerbach <m.hollerbach@partner.samsung.com>2018-10-30 18:42:28 +0100
committerJussi Pakkanen <jpakkane@gmail.com>2018-11-04 18:46:50 +0200
commit253c581412d7f2b09af353dd83d943454bd555be (patch)
tree402d5cad1a7377fdec6aa1ca3be9d75abdc60ec3 /mesonbuild/mtest.py
parent63f4f9481ebc865b11a06aeecf0c624104d46afd (diff)
downloadmeson-253c581412d7f2b09af353dd83d943454bd555be.zip
meson-253c581412d7f2b09af353dd83d943454bd555be.tar.gz
meson-253c581412d7f2b09af353dd83d943454bd555be.tar.bz2
test: do not use PIPE
as instructed in the python docs, you should not use PIPE here. This can lead to deadlocks, with massive testsuite output. Which was the case for efl. For now the output of the tests is redirected into the a temp file, the content from there can then be used to fill the TestRun structure. This fixes test running problems in efl.
Diffstat (limited to 'mesonbuild/mtest.py')
-rw-r--r--mesonbuild/mtest.py33
1 files changed, 21 insertions, 12 deletions
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 78f2252..6c4cdb3 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -23,6 +23,7 @@ from mesonbuild.dependencies import ExternalProgram
from mesonbuild.mesonlib import substring_is_in_list, MesonException
from mesonbuild import mlog
+import tempfile
import time, datetime, multiprocessing, json
import concurrent.futures as conc
import platform
@@ -289,8 +290,8 @@ class SingleTestRunner:
stdout = None
stderr = None
if not self.options.verbose:
- stdout = subprocess.PIPE
- stderr = subprocess.PIPE if self.options and self.options.split else subprocess.STDOUT
+ stdout = tempfile.TemporaryFile("wb+")
+ stderr = tempfile.TemporaryFile("wb+") if self.options and self.options.split else stdout
# Let gdb handle ^C instead of us
if self.options.gdb:
@@ -324,7 +325,7 @@ class SingleTestRunner:
else:
timeout = self.test.timeout
try:
- (stdo, stde) = p.communicate(timeout=timeout)
+ p.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
if self.options.verbose:
print('%s time out (After %d seconds)' % (self.test.name, timeout))
@@ -337,6 +338,8 @@ class SingleTestRunner:
# Let us accept ^C again
signal.signal(signal.SIGINT, previous_sigint_handler)
+ additional_error = None
+
if kill_test or timed_out:
# Python does not provide multiplatform support for
# killing a process and all its children so we need
@@ -353,25 +356,31 @@ class SingleTestRunner:
# already died) so carry on.
pass
try:
- (stdo, stde) = p.communicate(timeout=1)
+ p.communicate(timeout=1)
except subprocess.TimeoutExpired:
# An earlier kill attempt has not worked for whatever reason.
# Try to kill it one last time with a direct call.
# If the process has spawned children, they will remain around.
p.kill()
try:
- (stdo, stde) = p.communicate(timeout=1)
+ p.communicate(timeout=1)
except subprocess.TimeoutExpired:
- stdo = b'Test process could not be killed.'
- stde = b''
+ additional_error = b'Test process could not be killed.'
except ValueError:
- stdo = b'Could not read output. Maybe the process has redirected its stdout/stderr?'
- stde = b''
+ additional_error = b'Could not read output. Maybe the process has redirected its stdout/stderr?'
endtime = time.time()
duration = endtime - starttime
- stdo = decode(stdo)
- if stde:
- stde = decode(stde)
+ if additional_error is None:
+ stdout.seek(0)
+ stdo = decode(stdout.read())
+ if stderr != stdout:
+ stderr.seek(0)
+ stde = decode(stderr.read())
+ else:
+ stde = ""
+ else:
+ stdo = ""
+ stde = additional_error
if timed_out:
res = TestResult.TIMEOUT
elif p.returncode == GNU_SKIP_RETURNCODE: