Bug 1321517 - Propagate exception from server subprocess and re-raise. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Wed, 28 Mar 2018 16:06:14 +0100
changeset 776664 1fd493e00e5d7b90c175ec4bbd92e3fca4dedfba
parent 776663 fae065d4d6a4ea3535518c5eeafc0dd381802ac3
push id104941
push userbmo:ato@sny.no
push dateTue, 03 Apr 2018 15:05:46 +0000
reviewerswhimboo
bugs1321517
milestone61.0a1
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):