Bug 1185761 - [mochitest] Allow boolean values to --keep-open for overriding the default, r=ted
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Thu, 06 Aug 2015 17:40:54 -0400
changeset 279551 992b47960b9ea6fdcb4e824587bef6a3f8a9dc9d
parent 279550 e671afb6659132bdc041ceada37d39505240a387
child 279552 291adc935f335c6f6c2a1ea9c453fe87bf8ad9d6
push id8456
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:31:52 +0000
treeherdermozilla-aurora@7f2f0fb041b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs1185761
milestone43.0a1
Bug 1185761 - [mochitest] Allow boolean values to --keep-open for overriding the default, r=ted Most of the time the default is to close the browser after tests run. And that can be overridden with --keep-open. But in some corner cases, the default is to leave the browser open after tests have run. In these cases, it is not currently possible to override. This patch allows the syntax --keep-open or --keep-open=false, the latter overrides the edge case default.
testing/mochitest/mach_commands.py
testing/mochitest/mochitest_options.py
testing/mochitest/runtests.py
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -334,19 +334,22 @@ class MochitestRunner(MozbuildObject):
                 options.app = self.get_webapp_runtime_path()
             options.xrePath = self.get_webapp_runtime_xre_path()
 
         from manifestparser import TestManifest
         manifest = TestManifest()
         manifest.tests.extend(tests)
         options.manifestFile = manifest
 
-        # XXX why is this such a special case?
-        if len(tests) == 1 and options.closeWhenDone and suite == 'plain':
-            options.closeWhenDone = False
+        # When developing mochitest-plain tests, it's often useful to be able to
+        # refresh the page to pick up modifications. Therefore leave the browser
+        # open if only running a single mochitest-plain test. This behaviour can
+        # be overridden by passing in --keep-open=false.
+        if len(tests) == 1 and options.keep_open is None and suite == 'plain':
+            options.keep_open = True
 
         # We need this to enable colorization of output.
         self.log_manager.enable_unstructured()
         result = mochitest.run_test_harness(options)
         self.log_manager.disable_unstructured()
         return result
 
     def run_android_test(self, context, tests, suite=None, **kwargs):
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -1,14 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from abc import ABCMeta, abstractmethod, abstractproperty
 from argparse import ArgumentParser, SUPPRESS
+from distutils.util import strtobool
 from urlparse import urlparse
 import os
 import tempfile
 
 from droid import DroidADB, DroidSUT
 from mozprofile import DEFAULT_PORTS
 import mozinfo
 import mozlog
@@ -61,20 +62,22 @@ class MochitestArguments(ArgumentContain
         [["test_paths"],
          {"nargs": "*",
           "metavar": "TEST",
           "default": [],
           "help": "Test to run. Can be a single test file or a directory of tests "
                   "(to run recursively). If omitted, the entire suite is run.",
           }],
         [["--keep-open"],
-         {"action": "store_false",
-          "dest": "closeWhenDone",
-          "default": True,
-          "help": "Always keep the browser open after tests complete.",
+         {"nargs": "?",
+          "type": strtobool,
+          "const": "true",
+          "default": None,
+          "help": "Always keep the browser open after tests complete. Or always close the "
+                  "browser with --keep-open=false",
           }],
         [["--appname"],
          {"dest": "app",
           "default": None,
           "help": "Override the default binary used to run tests with the path provided, e.g "
                   "/usr/bin/firefox. If you have run ./mach package beforehand, you can "
                   "specify 'dist' to run tests against the distribution bundle's binary.",
           "suppress": build_obj is not None,
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -327,17 +327,17 @@ else:
 class MochitestServer(object):
 
     "Web server used to serve Mochitests, for closer fidelity to the real web."
 
     def __init__(self, options, logger):
         if isinstance(options, Namespace):
             options = vars(options)
         self._log = logger
-        self._closeWhenDone = options['closeWhenDone']
+        self._keep_open = bool(options['keep_open'])
         self._utilityPath = options['utilityPath']
         self._xrePath = options['xrePath']
         self._profileDir = options['profilePath']
         self.webServer = options['webServer']
         self.httpPort = options['httpPort']
         self.shutdownURL = "http://%(server)s:%(port)s/server/shutdown" % {
             "server": self.webServer,
             "port": self.httpPort}
@@ -385,17 +385,17 @@ class MochitestServer(object):
             """const _PROFILE_PATH = '%(profile)s'; const _SERVER_PORT = '%(port)s'; const _SERVER_ADDR = '%(server)s'; const _TEST_PREFIX = %(testPrefix)s; const _DISPLAY_RESULTS = %(displayResults)s;""" % {
                 "profile": self._profileDir.replace(
                     '\\',
                     '\\\\'),
                 "port": self.httpPort,
                 "server": self.webServer,
                 "testPrefix": self.testPrefix,
                 "displayResults": str(
-                    not self._closeWhenDone).lower()},
+                    self._keep_open).lower()},
             "-f",
             os.path.join(
                 SCRIPT_DIR,
                 "server.js")]
 
         xpcshell = os.path.join(self._utilityPath,
                                 "xpcshell" + mozinfo.info['bin_suffix'])
         command = [xpcshell] + args
@@ -589,17 +589,17 @@ class MochitestUtilsMixin(object):
             self.makeTestConfig(options)
         else:
             if options.autorun:
                 self.urlOpts.append("autorun=1")
             if options.timeout:
                 self.urlOpts.append("timeout=%d" % options.timeout)
             if options.maxTimeouts:
                 self.urlOpts.append("maxTimeouts=%d" % options.maxTimeouts)
-            if options.closeWhenDone:
+            if not options.keep_open:
                 self.urlOpts.append("closeWhenDone=1")
             if options.webapprtContent:
                 self.urlOpts.append("testRoot=webapprtContent")
             if options.logFile:
                 self.urlOpts.append(
                     "logFile=" +
                     encodeURIComponent(
                         options.logFile))
@@ -2526,16 +2526,18 @@ class Mochitest(MochitestUtilsMixin):
         if "MOZ_HIDE_RESULTS_TABLE" in os.environ and os.environ[
                 "MOZ_HIDE_RESULTS_TABLE"] == "1":
             options.hideResultsTable = True
 
         # strip certain unnecessary items to avoid serialization errors in json.dumps()
         d = dict((k, v) for k, v in options.__dict__.items() if (v is None) or
             isinstance(v,(basestring,numbers.Number)))
         d['testRoot'] = self.testRoot
+        if not options.keep_open:
+            d['closeWhenDone'] = '1'
         content = json.dumps(d)
 
         with open(os.path.join(options.profilePath, "testConfig.js"), "w") as config:
             config.write(content)
 
     def getTestManifest(self, options):
         if isinstance(options.manifestFile, TestManifest):
             manifest = options.manifestFile