Bug 1321517 - Propagate exception from server subprocess and re-raise. r=whimboo
authorAndreas Tolfsen <ato@sny.no>
Wed, 28 Mar 2018 16:06:14 +0100
changeset 411682 1f158432b80165534e86a82cc1d9b74f6b543bb8
parent 411681 c7abc1d5b6ec9d32f54745f51e96065a89b774bf
child 411683 6b052fb6d3289aec5ee9805eb068687b9a2cc7e8
push id101729
push usercsabou@mozilla.com
push dateWed, 04 Apr 2018 18:07:35 +0000
treeherdermozilla-inbound@3c240f56a113 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswhimboo
bugs1321517
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1321517 - Propagate exception from server subprocess and re-raise. r=whimboo When an exception occurs during startup of ServerProxy it is logged to stdout and the subprocess terminates. The exception is however not propagated/communicated to the parent process so it can take action on it. This patch returns the exception via the BlockingChannel pipe and re-raises it in the parent process. This will cause serve.py to exit if one of the HTTPD servers fails to start. This fixes the problem reported in bug 1321517, where the HTTP server lives on when the HTTPS server fails to start due to a missing certificate or key file.
testing/marionette/harness/marionette_harness/runner/serve.py
--- a/testing/marionette/harness/marionette_harness/runner/serve.py
+++ b/testing/marionette/harness/marionette_harness/runner/serve.py
@@ -66,20 +66,21 @@ class ServerProxy(multiprocessing.Proces
     def __init__(self, channel, init_func, *init_args, **init_kwargs):
         multiprocessing.Process.__init__(self)
         BlockingChannel.__init__(self, channel)
         self.init_func = init_func
         self.init_args = init_args
         self.init_kwargs = init_kwargs
 
     def run(self):
-        server = self.init_func(*self.init_args, **self.init_kwargs)
-        server.start(block=False)
+        try:
+            server = self.init_func(*self.init_args, **self.init_kwargs)
+            server.start(block=False)
+            self.send(("ok", ()))
 
-        try:
             while True:
                 # ["func", ("arg", ...)]
                 # ["prop", ()]
                 sattr, fargs = self.recv()
                 attr = getattr(server, sattr)
 
                 # apply fargs to attr if it is a function
                 if callable(attr):
@@ -89,16 +90,19 @@ class ServerProxy(multiprocessing.Proces
                 else:
                     rv = attr
 
                 self.send(rv)
 
                 if sattr == "stop":
                     return
 
+        except Exception as e:
+            self.send(("stop", e))
+
         except KeyboardInterrupt:
             server.stop()
 
 
 class ServerProc(BlockingChannel):
 
     def __init__(self, init_func):
         self._init_func = init_func
@@ -108,16 +112,20 @@ class ServerProc(BlockingChannel):
         BlockingChannel.__init__(self, parent_chan)
 
     def start(self, doc_root, ssl_config, **kwargs):
         self.proc = ServerProxy(
             self.child_chan, self._init_func, doc_root, ssl_config, **kwargs)
         self.proc.daemon = True
         self.proc.start()
 
+        res, exc = self.recv()
+        if res == "stop":
+            raise exc
+
     def get_url(self, url):
         return self.call("get_url", (url,))
 
     @property
     def doc_root(self):
         return self.call("doc_root", ())
 
     def stop(self):