Bug 1248056 - Increase marionette connection timeouts in mochitest when running with valgrind, r=chmanchester
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Tue, 16 Feb 2016 10:04:52 -0500
changeset 331614 bf27afd3c5c65aa65df640a9b5da620326757930
parent 331613 24253491a3e22a92475775eb0e40291d9d1fa06a
child 331615 0715e0b9a3167b0ac90c9f78f1195557ac12cd17
push id11020
push userjolesen@mozilla.com
push dateWed, 17 Feb 2016 18:16:38 +0000
reviewerschmanchester
bugs1248056
milestone47.0a1
Bug 1248056 - Increase marionette connection timeouts in mochitest when running with valgrind, r=chmanchester MozReview-Commit-ID: 71d5XIgqcCJ
testing/marionette/driver/marionette_driver/marionette.py
testing/mochitest/mochitest_options.py
testing/mochitest/runtests.py
--- a/testing/marionette/driver/marionette_driver/marionette.py
+++ b/testing/marionette/driver/marionette_driver/marionette.py
@@ -528,23 +528,24 @@ class Alert(object):
 class Marionette(object):
     """Represents a Marionette connection to a browser or device."""
 
     CONTEXT_CHROME = 'chrome' # non-browser content: windows, dialogs, etc.
     CONTEXT_CONTENT = 'content' # browser content: iframes, divs, etc.
     TIMEOUT_SEARCH = 'implicit'
     TIMEOUT_SCRIPT = 'script'
     TIMEOUT_PAGE = 'page load'
+    DEFAULT_SOCKET_TIMEOUT = 360
     DEFAULT_STARTUP_TIMEOUT = 60
 
     def __init__(self, host='localhost', port=2828, app=None, app_args=None, bin=None,
                  profile=None, addons=None, emulator=None, sdcard=None, emulator_img=None,
                  emulator_binary=None, emulator_res=None, connect_to_running_emulator=False,
                  gecko_log=None, homedir=None, baseurl=None, no_window=False, logdir=None,
-                 busybox=None, symbols_path=None, timeout=None, socket_timeout=360,
+                 busybox=None, symbols_path=None, timeout=None, socket_timeout=None,
                  device_serial=None, adb_path=None, process_args=None,
                  adb_host=None, adb_port=None, prefs=None, startup_timeout=None,
                  workspace=None, verbose=0):
         self.host = host
         self.port = self.local_port = port
         self.bin = bin
         self.profile = profile
         self.addons = addons
@@ -555,17 +556,17 @@ class Marionette(object):
         self.chrome_window = None
         self.runner = None
         self.emulator = None
         self.extra_emulators = []
         self.baseurl = baseurl
         self.no_window = no_window
         self._test_name = None
         self.timeout = timeout
-        self.socket_timeout = socket_timeout
+        self.socket_timeout = socket_timeout or self.DEFAULT_SOCKET_TIMEOUT
         self.device_serial = device_serial
         self.adb_host = adb_host
         self.adb_port = adb_port
 
         startup_timeout = startup_timeout or self.DEFAULT_STARTUP_TIMEOUT
 
         if bin:
             port = int(self.port)
@@ -665,17 +666,18 @@ class Marionette(object):
         try:
             s.bind((host, port))
             return True
         except socket.error:
             return False
         finally:
             s.close()
 
-    def wait_for_port(self, timeout=60):
+    def wait_for_port(self, timeout=None):
+        timeout = timeout or self.DEFAULT_STARTUP_TIMEOUT
         return transport.wait_for_port(self.host, self.port, timeout=timeout)
 
     @do_crash_check
     def raise_for_port(self, port_obtained):
         if not port_obtained:
             raise IOError("Timed out waiting for port!")
 
 
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -557,16 +557,26 @@ class MochitestArguments(ArgumentContain
           "dest": "enableCPOWWarnings",
           "help": "Enable logging of unsafe CPOW usage, which is disabled by default for tests",
           "suppress": True,
           }],
         [["--marionette"],
          {"default": None,
           "help": "host:port to use when connecting to Marionette",
           }],
+        [["--marionette-port-timeout"],
+         {"default": None,
+          "help": "Timeout while waiting for the marionette port to open.",
+          "suppress": True,
+          }],
+        [["--marionette-socket-timeout"],
+         {"default": None,
+          "help": "Timeout while waiting to receive a message from the marionette server.",
+          "suppress": True,
+          }],
     ]
 
     defaults = {
         # Bug 1065098 - The geckomediaplugin process fails to produce a leak
         # log for some reason.
         'ignoreMissingLeaks': ["geckomediaplugin"],
         'extensionsToExclude': ['specialpowers'],
         # Set server information on the args object
@@ -696,16 +706,22 @@ class MochitestArguments(ArgumentContain
         if options.debugOnFailure and not options.jsdebugger:
             parser.error(
                 "--debug-on-failure requires --jsdebugger.")
 
         if options.debuggerArgs and not options.debugger:
             parser.error(
                 "--debugger-args requires --debugger.")
 
+        if options.valgrind or options.debugger:
+            # valgrind and some debuggers may cause Gecko to start slowly. Make sure
+            # marionette waits long enough to connect.
+            options.marionette_port_timeout = 900
+            options.marionette_socket_timeout = 540
+
         if options.store_chrome_manifest:
             options.store_chrome_manifest = os.path.abspath(options.store_chrome_manifest)
             if not os.path.isdir(os.path.dirname(options.store_chrome_manifest)):
                 parser.error(
                     "directory for %s does not exist as a destination to copy a "
                     "chrome manifest." % options.store_chrome_manifest)
 
         if options.jscov_dir_prefix:
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -1997,18 +1997,19 @@ class MochitestDesktop(MochitestBase):
                          interactive=interactive,
                          outputTimeout=timeout)
             proc = runner.process_handler
             self.log.info("runtests.py | Application pid: %d" % proc.pid)
             self.log.process_start("Main app process")
 
             # start marionette and kick off the tests
             marionette_args = marionette_args or {}
+            port_timeout = marionette_args.pop('port_timeout')
             self.marionette = Marionette(**marionette_args)
-            self.marionette.start_session()
+            self.marionette.start_session(timeout=port_timeout)
 
             # install specialpowers and mochikit as temporary addons
             addons = Addons(self.marionette)
 
             if mozinfo.info.get('toolkit') != 'gonk':
                 addons.install(os.path.join(here, 'extensions', 'specialpowers'), temp=True)
                 addons.install(self.mochijar, temp=True)
 
@@ -2349,16 +2350,18 @@ class MochitestDesktop(MochitestBase):
 
             # detect shutdown leaks for m-bc runs
             detectShutdownLeaks = mozinfo.info[
                 "debug"] and options.browserChrome and not options.webapprtChrome
 
             self.start_script_args.append(self.getTestFlavor(options))
             marionette_args = {
                 'symbols_path': options.symbolsPath,
+                'socket_timeout': options.marionette_socket_timeout,
+                'port_timeout': options.marionette_port_timeout,
             }
 
             if options.marionette:
                 host, port = options.marionette.split(':')
                 marionette_args['host'] = host
                 marionette_args['port'] = int(port)
 
             self.log.info("runtests.py | Running tests: start.\n")