[yocto] [[PATCH][qa-tools] 06/16] tests/toaster/helpers.py: Fix toaster_start deadlocks.

Aníbal Limón anibal.limon at linux.intel.com
Tue Feb 9 14:43:15 PST 2016


When call toaster_start on failing scenarios (already started) it
becomes blocked on process.communicate() function so add my own
function for solve this issue.

The new function uses a tempfile instead of PIPE for avoid deadlocks.

Signed-off-by: Aníbal Limón <anibal.limon at linux.intel.com>
---
 tests/toaster/helpers.py | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/tests/toaster/helpers.py b/tests/toaster/helpers.py
index 7b82e88..5e54723 100644
--- a/tests/toaster/helpers.py
+++ b/tests/toaster/helpers.py
@@ -2,17 +2,47 @@ import subprocess
 import os
 import shutil
 import signal
+import tempfile
 
 TOASTER_TEST_BRANCH = 'toaster_tests'
 VENV_NAME = 'venv'
 SHELL_CMD = os.environ['SHELL'] if 'SHELL' in os.environ else "/bin/bash"
 
+def _check_output1(*popenargs, **kwargs):
+    """
+        Almost the same as subprocess.check_output but change the stdout from
+        PIPE to tempfile to avoid deadlocks when trying to read the PIPE using
+        communicate(). This scenario can be seen calling toaster_start on failure
+        scenarios.
+
+        This causes a little overhead by the tempfile.
+    """
+
+    f = tempfile.TemporaryFile(mode='rw+')
+    if 'stdout' in kwargs:
+        raise ValueError('stdout argument not allowed, it will be overridden.')
+    process = subprocess.Popen(stdout=f, *popenargs, **kwargs)
+    retcode = process.wait()
+
+    f.flush()
+    os.fsync(f.fileno())
+    f.seek(0, 0)
+    output = f.read()
+    f.close()
+
+    if retcode:
+        cmd = kwargs.get("args")
+        if cmd is None:
+            cmd = popenargs[0]
+        raise subprocess.CalledProcessError(retcode, cmd, output=output)
+    return output
+
 def _execute_command(directory, cmd):
-    subprocess.check_call([SHELL_CMD, "-c", "cd %s; %s" % \
+    return _check_output1([SHELL_CMD, "-c", "cd %s; %s" % \
         (directory, cmd)], stderr=subprocess.STDOUT)
 
 def _execute_command_venv(directory, venv, cmd):
-    _execute_command(directory, "source %s/%s/bin/activate; %s" % \
+    return _execute_command(directory, "source %s/%s/bin/activate; %s" % \
         (directory, venv, cmd))
 
 def toaster_clone(directory, repo, ref='master', rm=False):
@@ -33,11 +63,11 @@ def toaster_setup(directory):
         " bitbake/toaster-requirements.txt")
 
 def toaster_start(directory):
-    _execute_command_venv(directory, VENV_NAME,
+    return _execute_command_venv(directory, VENV_NAME,
         "source %s/oe-init-build-env; source %s/bitbake/bin/toaster start" % \
         (directory, directory))
 
 def toaster_stop(directory):
-    _execute_command_venv(directory, VENV_NAME,
+    return _execute_command_venv(directory, VENV_NAME,
         "source %s/oe-init-build-env; source %s/bitbake/bin/toaster stop" % \
         (directory, directory))
-- 
2.1.4




More information about the yocto mailing list