Bug 1289444 - Forward extra arguments in |mach test| to the underlying test commands, r?chmanchester draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Wed, 03 Aug 2016 14:13:44 -0400
changeset 397390 d896fd9618d005f6c4f9efdf260c3db5e099d0cc
parent 397204 d320ef56876f52db9bc0eb79554c7332d4793769
child 527441 54b5f0d323e4bfb61f91700f71d9929384119976
push id25282
push userahalberstadt@mozilla.com
push dateFri, 05 Aug 2016 19:12:58 +0000
reviewerschmanchester
bugs1289444
milestone51.0a1
Bug 1289444 - Forward extra arguments in |mach test| to the underlying test commands, r?chmanchester This will allow developers to pass things like --disable-e10s directly on the |mach test| commandline. There is no good way to tell which arguments will be accepted by which harness', so any test harness that does not recognize the argument will simply ignore it. This also means that we can't directly add the arguments to |mach test| and therefore won't be documented when running |mach help test|. MozReview-Commit-ID: 62YSrlt0PAu
python/mach/mach/registrar.py
testing/mach_commands.py
--- a/python/mach/mach/registrar.py
+++ b/python/mach/mach/registrar.py
@@ -111,16 +111,20 @@ class MachRegistrar(object):
 
         if handler.parser:
             parser = handler.parser
 
             # save and restore existing defaults so **kwargs don't persist across
             # subsequent invocations of Registrar.dispatch()
             old_defaults = parser._defaults.copy()
             parser.set_defaults(**kwargs)
-            kwargs, _ = parser.parse_known_args(argv or [])
+            kwargs, unknown = parser.parse_known_args(argv or [])
             kwargs = vars(kwargs)
             parser._defaults = old_defaults
 
+            if unknown:
+                print("warning: unknown arguments {}".format(
+                    ', '.join(["'{}'".format(arg) for arg in unknown])))
+
         return self._run_command_handler(handler, context=context, **kwargs)
 
 
 Registrar = MachRegistrar()
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -5,16 +5,17 @@
 from __future__ import absolute_import, print_function, unicode_literals
 
 import json
 import os
 import sys
 import tempfile
 import subprocess
 import shutil
+from argparse import REMAINDER
 from collections import defaultdict
 
 from mach.decorators import (
     CommandArgument,
     CommandProvider,
     Command,
 )
 
@@ -192,17 +193,20 @@ The following test suites and aliases ar
 ''' % ', '.join(sorted(TEST_SUITES))
 TEST_HELP = TEST_HELP.strip()
 
 
 @CommandProvider
 class Test(MachCommandBase):
     @Command('test', category='testing', description='Run tests (detects the kind of test and runs it).')
     @CommandArgument('what', default=None, nargs='*', help=TEST_HELP)
-    def test(self, what):
+    @CommandArgument('extra_args', default=None, nargs=REMAINDER,
+        help="Extra arguments to pass to the underlying test command(s). If an underlying "
+             "command doesn't recognize the argument, it will be ignored for that test harness.")
+    def test(self, what, extra_args):
         """Run tests from names or paths.
 
         mach test accepts arguments specifying which tests to run. Each argument
         can be:
 
         * The path to a test file
         * A directory containing tests
         * A test suite name
@@ -295,17 +299,17 @@ class Test(MachCommandBase):
 
         status = None
         for suite_name in run_suites:
             suite = TEST_SUITES[suite_name]
 
             if 'mach_command' in suite:
                 res = self._mach_context.commands.dispatch(
                     suite['mach_command'], self._mach_context,
-                    **suite['kwargs'])
+                    argv=extra_args, **suite['kwargs'])
                 if res:
                     status = res
 
         buckets = {}
         for test in run_tests:
             key = (test['flavor'], test['subsuite'])
             buckets.setdefault(key, []).append(test)
 
@@ -321,17 +325,17 @@ class Test(MachCommandBase):
                 status = 1
                 continue
 
             kwargs = dict(m['kwargs'])
             kwargs['subsuite'] = subsuite
 
             res = self._mach_context.commands.dispatch(
                     m['mach_command'], self._mach_context,
-                    test_objects=tests, **kwargs)
+                    argv=extra_args, test_objects=tests, **kwargs)
             if res:
                 status = res
 
         return status
 
 
 @CommandProvider
 class MachCommands(MachCommandBase):