Bug 1451310 - [mozrunner] Catch exceptions when starting the client process. draft
authorHenrik Skupin <mail@hskupin.info>
Wed, 04 Apr 2018 15:04:42 +0200
changeset 777758 74bf85f9ee356e40c7d8fec556fbadc91f21e295
parent 777562 071ee904485e21e19ca08456d32bce6825b77a26
push id105280
push userbmo:hskupin@gmail.com
push dateThu, 05 Apr 2018 09:33:51 +0000
bugs1451310
milestone61.0a1
Bug 1451310 - [mozrunner] Catch exceptions when starting the client process. If a ProcessHandler instance has been created, but mozprocess fails to start the child process, a dangling process_handler instance is attached to the runner instance. This should be avoided, and a RunnerNotStartedError has to be thrown. MozReview-Commit-ID: LgNFVaT9qVs
testing/mozbase/mozrunner/mozrunner/base/runner.py
testing/mozbase/mozrunner/setup.py
--- a/testing/mozbase/mozrunner/mozrunner/base/runner.py
+++ b/testing/mozbase/mozrunner/mozrunner/base/runner.py
@@ -12,16 +12,17 @@ import traceback
 import sys
 
 from mozlog import get_default_logger
 from mozprocess import ProcessHandler
 try:
     import mozcrash
 except ImportError:
     mozcrash = None
+from six import reraise
 
 from ..application import DefaultContext
 from ..errors import RunnerNotStartedError
 
 if sys.version_info[0] < 3:
     unicode_type = unicode
 else:
     unicode_type = str
@@ -92,16 +93,18 @@ class BaseRunner(object):
         """
         Run self.command in the proper environment.
 
         :param debug_args: arguments for a debugger
         :param interactive: uses subprocess.Popen directly
         :param timeout: see process_handler.run()
         :param outputTimeout: see process_handler.run()
         :returns: the process id
+
+        :raises: RunnerNotStartedError
         """
         self.timeout = timeout
         self.output_timeout = outputTimeout
         cmd = self.command
 
         # ensure the runner is stopped
         self.stop()
 
@@ -121,18 +124,24 @@ class BaseRunner(object):
                 k = k.encode('utf-8')
             encoded_env[k] = v
 
         if interactive:
             self.process_handler = subprocess.Popen(cmd, env=encoded_env)
             # TODO: other arguments
         else:
             # this run uses the managed processhandler
-            self.process_handler = self.process_class(cmd, env=encoded_env, **self.process_args)
-            self.process_handler.run(self.timeout, self.output_timeout)
+            try:
+                process = self.process_class(cmd, env=encoded_env, **self.process_args)
+                process.run(self.timeout, self.output_timeout)
+
+                self.process_handler = process
+            except Exception:
+                _, value, tb = sys.exc_info()
+                reraise(RunnerNotStartedError, "Failed to start the process: %s" % value, tb)
 
         self.crashed = 0
         return self.process_handler.pid
 
     def wait(self, timeout=None):
         """
         Wait for the process to exit.
 
--- a/testing/mozbase/mozrunner/setup.py
+++ b/testing/mozbase/mozrunner/setup.py
@@ -13,16 +13,17 @@ PACKAGE_VERSION = '6.14'
 desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""
 
 deps = ['mozdevice >= 0.37',
         'mozfile >= 1.0',
         'mozinfo >= 0.7',
         'mozlog >= 3.0',
         'mozprocess >= 0.23',
         'mozprofile >= 0.18',
+        'six >= 1.10.0',
         ]
 
 EXTRAS_REQUIRE = {'crash': ['mozcrash >= 1.0']}
 
 # we only support python 2 right now
 assert sys.version_info[0] == 2
 
 setup(name=PACKAGE_NAME,