Bug 795772 - More mach options to control xpcshell test execution; r=ted
authorGregory Szorc <gps@mozilla.com>
Wed, 31 Oct 2012 10:29:26 -0700
changeset 119822 3162d35c6ffd149abb4598645ece37c4c3964777
parent 119821 baa695a1f5ca825748d1bb41d8b12a3a455559ef
child 119823 7a52ba9b15428708096c21d37d7eb1193c7edf83
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 795772 - More mach options to control xpcshell test execution; r=ted DONTBUILD (NPOTB)
--- a/testing/xpcshell/mach_commands.py
+++ b/testing/xpcshell/mach_commands.py
@@ -16,71 +16,84 @@ from mach.base import (
 class XPCShellRunner(MozbuildObject):
     """Run xpcshell tests."""
-    def run_suite(self):
-        # TODO hook up to harness runner and support things like shuffle,
-        # proper progress updates, etc.
-        self._run_make(directory='.', target='xpcshell-tests')
+    def run_suite(self, **kwargs):
+        manifest = os.path.join(self.topobjdir, '_tests', 'xpcshell',
+            'xpcshell.ini')
+        self._run_xpcshell_harness(manifest=manifest, **kwargs)
-    def run_test(self, test_file, debug=False):
+    def run_test(self, test_file, debug=False, interactive=False,
+        keep_going=False, shuffle=False):
         """Runs an individual xpcshell test."""
         if test_file == 'all':
-            self.run_suite()
+            self.run_suite(debug=debug, interactive=interactive,
+                keep_going=keep_going, shuffle=shuffle)
         # dirname() gets confused if there isn't a trailing slash.
         if os.path.isdir(test_file) and not test_file.endswith(os.path.sep):
             test_file += os.path.sep
         relative_dir = test_file
         if test_file.startswith(self.topsrcdir):
             relative_dir = test_file[len(self.topsrcdir):]
         test_dir = os.path.join(self.topobjdir, '_tests', 'xpcshell',
         args = {
             'debug': debug,
+            'interactive': interactive,
+            'keep_going': keep_going,
+            'shuffle': shuffle,
             'test_dirs': [test_dir],
         if os.path.isfile(test_file):
             args['test_path'] = os.path.basename(test_file)
     def _run_xpcshell_harness(self, test_dirs=None, manifest=None,
-        test_path=None, debug=False):
+        test_path=None, debug=False, shuffle=False, interactive=False,
+        keep_going=False):
         # Obtain a reference to the xpcshell test runner.
         import runxpcshelltests
         dummy_log = StringIO()
         xpcshell = runxpcshelltests.XPCShellTests(log=dummy_log)
         tests_dir = os.path.join(self.topobjdir, '_tests', 'xpcshell')
         modules_dir = os.path.join(self.topobjdir, '_tests', 'modules')
         args = {
             'xpcshell': os.path.join(self.bindir, 'xpcshell'),
             'mozInfo': os.path.join(self.topobjdir, 'mozinfo.json'),
             'symbolsPath': os.path.join(self.distdir, 'crashreporter-symbols'),
+            'interactive': interactive,
+            'keepGoing': keep_going,
             'logfiles': False,
+            'shuffle': shuffle,
             'testsRootDir': tests_dir,
             'testingModulesDir': modules_dir,
             'profileName': 'firefox',
             'verbose': test_path is not None,
+            'xunitFilename': os.path.join(self.statedir, 'xpchsell.xunit.xml'),
+            'xunitName': 'xpcshell',
         if manifest is not None:
             args['manifest'] = manifest
         elif test_dirs is not None:
             if isinstance(test_dirs, list):
                 args['testdirs'] = test_dirs
@@ -100,12 +113,18 @@ class XPCShellRunner(MozbuildObject):
 class MachCommands(MozbuildObject):
     @Command('xpcshell-test', help='Run an xpcshell test.')
     @CommandArgument('test_file', default='all', nargs='?', metavar='TEST',
         help='Test to run. Can be specified as a single JS file, a directory, '
              'or omitted. If omitted, the entire test suite is executed.')
     @CommandArgument('--debug', '-d', action='store_true',
         help='Run test in a debugger.')
+    @CommandArgument('--interactive', '-i', action='store_true',
+        help='Open an xpcshell prompt before running tests.')
+    @CommandArgument('--keep-going', '-k', action='store_true',
+        help='Continue running tests after a SIGINT is received.')
+    @CommandArgument('--shuffle', '-s', action='store_true',
+        help='Randomize the execution order of tests.')
     def run_xpcshell_test(self, **params):
         xpcshell = self._spawn(XPCShellRunner)
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -477,17 +477,17 @@ class XPCShellTests(object):
       |results|, Iterable of tuples describing the results.
     if filename is None and fh is None:
       raise Exception("One of filename or fh must be defined.")
     if name is None:
       name = "xpcshell"
-      assert isinstance(name, str)
+      assert isinstance(name, basestring)
     if filename is not None:
       fh = open(filename, 'wb')
     doc = xml.dom.minidom.Document()
     testsuite = doc.createElement("testsuite")
     testsuite.setAttribute("name", name)
@@ -632,17 +632,17 @@ class XPCShellTests(object):
     global gotSIGINT
     if testdirs is None:
         testdirs = []
     if xunitFilename is not None or xunitName is not None:
-        if not isinstance(testsRootDir, str):
+        if not isinstance(testsRootDir, basestring):
             raise Exception("testsRootDir must be a str when outputting xUnit.")
         if not os.path.isabs(testsRootDir):
             testsRootDir = os.path.abspath(testsRootDir)
         if not os.path.exists(testsRootDir):
             raise Exception("testsRootDir path does not exists: %s" %