Bug 1312739 - Move mochitest 'ALL_FLAVORS' dict from mach_commands.py to mochitest_options.py, r?jmaher draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Tue, 20 Dec 2016 10:50:43 -0500
changeset 454672 fa88870077bc85d7e1047e2dc120eed2dcb932dd
parent 454671 1858a65c567f20be728ab93e2835637844d1dee1
child 454673 7b63c121b334cd4c506352264b005e3e5793f5b8
push id39997
push userahalberstadt@mozilla.com
push dateThu, 29 Dec 2016 22:27:12 +0000
reviewersjmaher
bugs1312739
milestone53.0a1
Bug 1312739 - Move mochitest 'ALL_FLAVORS' dict from mach_commands.py to mochitest_options.py, r?jmaher Information in the ALL_FLAVORS dict is needed by interactive loaners (in the mach_test_package_commands.py file). Because the normal mach_commands.py file doesn't get copied to the tests.zip, this commit refactors ALL_FLAVORS into mochitest_options.py (which is copied to tests.zip) to avoid duplicating it. A side benefit of moving ALL_FLAVORS to mochitest_options.py, is that mochitest_options.py itself can make use of this dict. This means we no longer need to redefine the --flavor argument in the mach command. The __init__.py file is added to turn the testing/mochitest directory into a python module. This allows things like mach_commands.py to do things like 'from mochitest import runtests'. Mach commands are able to find this module because the 'testing' directory is already added to sys.path in the mach bootstrap. In the future, having mochitest as an importable module should help with running it from the srcdir. So this is a change we should start making anyway. Unfortunately, we still need to import the main runtests.py file from the objdir, as lots of things depend on the SCRIPT_DIR variable being in the objdir. We could probably fix this with minimal work, but that is scope bloat for this bug. MozReview-Commit-ID: KtWCk91bX0K
testing/mochitest/__init__.py
testing/mochitest/mach_commands.py
testing/mochitest/mochitest_options.py
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/__init__.py
@@ -0,0 +1,3 @@
+# 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/.
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -1,17 +1,16 @@
 # 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 __future__ import absolute_import, unicode_literals
 
 from argparse import Namespace
 from collections import defaultdict
-from itertools import chain
 import logging
 import os
 import sys
 import warnings
 
 from mozbuild.base import (
     MachCommandBase,
     MachCommandConditions as conditions,
@@ -71,71 +70,17 @@ Please check spelling and make sure the 
 
 NOW_RUNNING = '''
 ######
 ### Now running mochitest-{}.
 ######
 '''
 
 
-# Maps test flavors to data needed to run them
-ALL_FLAVORS = {
-    'mochitest': {
-        'suite': 'plain',
-        'aliases': ('plain', 'mochitest'),
-        'enabled_apps': ('firefox', 'android'),
-        'extra_args': {
-            'flavor': 'plain',
-        }
-    },
-    'chrome': {
-        'suite': 'chrome',
-        'aliases': ('chrome', 'mochitest-chrome'),
-        'enabled_apps': ('firefox', 'android'),
-        'extra_args': {
-            'flavor': 'chrome',
-        }
-    },
-    'browser-chrome': {
-        'suite': 'browser',
-        'aliases': ('browser', 'browser-chrome', 'mochitest-browser-chrome', 'bc'),
-        'enabled_apps': ('firefox',),
-        'extra_args': {
-            'flavor': 'browser',
-        }
-    },
-    'jetpack-package': {
-        'suite': 'jetpack-package',
-        'aliases': ('jetpack-package', 'mochitest-jetpack-package', 'jpp'),
-        'enabled_apps': ('firefox',),
-        'extra_args': {
-            'flavor': 'jetpack-package',
-        }
-    },
-    'jetpack-addon': {
-        'suite': 'jetpack-addon',
-        'aliases': ('jetpack-addon', 'mochitest-jetpack-addon', 'jpa'),
-        'enabled_apps': ('firefox',),
-        'extra_args': {
-            'flavor': 'jetpack-addon',
-        }
-    },
-    'a11y': {
-        'suite': 'a11y',
-        'aliases': ('a11y', 'mochitest-a11y', 'accessibility'),
-        'enabled_apps': ('firefox',),
-        'extra_args': {
-            'flavor': 'a11y',
-        }
-    },
-}
-
 SUPPORTED_APPS = ['firefox', 'android']
-SUPPORTED_FLAVORS = list(chain.from_iterable([f['aliases'] for f in ALL_FLAVORS.values()]))
-CANONICAL_FLAVORS = sorted([f['aliases'][0] for f in ALL_FLAVORS.values()])
 
 parser = None
 
 
 class MochitestRunner(MozbuildObject):
 
     """Easily run mochitests.
 
@@ -329,21 +274,19 @@ def verify_host_bin():
 
 
 @CommandProvider
 class MachCommands(MachCommandBase):
     @Command('mochitest', category='testing',
              conditions=[is_buildapp_in(*SUPPORTED_APPS)],
              description='Run any flavor of mochitest (integration test).',
              parser=setup_argument_parser)
-    @CommandArgument('-f', '--flavor',
-                     metavar='{{{}}}'.format(', '.join(CANONICAL_FLAVORS)),
-                     choices=SUPPORTED_FLAVORS,
-                     help='Only run tests of this flavor.')
     def run_mochitest_general(self, flavor=None, test_objects=None, resolve_tests=True, **kwargs):
+        from mochitest.mochitest_options import ALL_FLAVORS
+
         buildapp = None
         for app in SUPPORTED_APPS:
             if is_buildapp_in(app)(self):
                 buildapp = app
                 break
 
         flavors = None
         if flavor:
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -1,15 +1,16 @@
 # 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 itertools import chain
 from urlparse import urlparse
 import json
 import os
 import tempfile
 
 from mozdevice import DroidADB, DroidSUT
 from mozprofile import DEFAULT_PORTS
 import mozinfo
@@ -25,16 +26,71 @@ try:
         MachCommandConditions as conditions,
     )
     build_obj = MozbuildObject.from_environment(cwd=here)
 except ImportError:
     build_obj = None
     conditions = None
 
 
+# Maps test flavors to data needed to run them
+ALL_FLAVORS = {
+    'mochitest': {
+        'suite': 'plain',
+        'aliases': ('plain', 'mochitest'),
+        'enabled_apps': ('firefox', 'android'),
+        'extra_args': {
+            'flavor': 'plain',
+        }
+    },
+    'chrome': {
+        'suite': 'chrome',
+        'aliases': ('chrome', 'mochitest-chrome'),
+        'enabled_apps': ('firefox', 'android'),
+        'extra_args': {
+            'flavor': 'chrome',
+        }
+    },
+    'browser-chrome': {
+        'suite': 'browser',
+        'aliases': ('browser', 'browser-chrome', 'mochitest-browser-chrome', 'bc'),
+        'enabled_apps': ('firefox',),
+        'extra_args': {
+            'flavor': 'browser',
+        }
+    },
+    'jetpack-package': {
+        'suite': 'jetpack-package',
+        'aliases': ('jetpack-package', 'mochitest-jetpack-package', 'jpp'),
+        'enabled_apps': ('firefox',),
+        'extra_args': {
+            'flavor': 'jetpack-package',
+        }
+    },
+    'jetpack-addon': {
+        'suite': 'jetpack-addon',
+        'aliases': ('jetpack-addon', 'mochitest-jetpack-addon', 'jpa'),
+        'enabled_apps': ('firefox',),
+        'extra_args': {
+            'flavor': 'jetpack-addon',
+        }
+    },
+    'a11y': {
+        'suite': 'a11y',
+        'aliases': ('a11y', 'mochitest-a11y', 'accessibility'),
+        'enabled_apps': ('firefox',),
+        'extra_args': {
+            'flavor': 'a11y',
+        }
+    },
+}
+SUPPORTED_FLAVORS = list(chain.from_iterable([f['aliases'] for f in ALL_FLAVORS.values()]))
+CANONICAL_FLAVORS = sorted([f['aliases'][0] for f in ALL_FLAVORS.values()])
+
+
 def get_default_valgrind_suppression_files():
     # We are trying to locate files in the source tree.  So if we
     # don't know where the source tree is, we must give up.
     #
     # When this is being run by |mach mochitest --valgrind ...|, it is
     # expected that |build_obj| is not None, and so the logic below will
     # select the correct suppression files.
     #
@@ -80,33 +136,31 @@ class ArgumentContainer():
 
     def get_full_path(self, path, cwd):
         """Get an absolute path relative to cwd."""
         return os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
 
 
 class MochitestArguments(ArgumentContainer):
     """General mochitest arguments."""
-
-    FLAVORS = ('a11y', 'browser', 'chrome', 'jetpack-addon', 'jetpack-package', 'plain')
     LOG_LEVELS = ("DEBUG", "INFO", "WARNING", "ERROR", "FATAL")
 
     args = [
         [["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.",
           }],
         [["-f", "--flavor"],
-         {"default": "plain",
-          "choices": FLAVORS,
-          "help": "Mochitest flavor to run, one of {}. Defaults to 'plain'.".format(FLAVORS),
-          "suppress": build_obj is not None,
+         {"choices": SUPPORTED_FLAVORS,
+          "metavar": "{{{}}}".format(', '.join(CANONICAL_FLAVORS)),
+          "default": None,
+          "help": "Only run tests of this flavor.",
           }],
         [["--keep-open"],
          {"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",
@@ -578,16 +632,19 @@ class MochitestArguments(ArgumentContain
                 options.app = build_obj.get_binary_path(where='staged-package')
 
             options.app = self.get_full_path(options.app, parser.oldcwd)
             if not os.path.exists(options.app):
                 parser.error("Error: Path {} doesn't exist. Are you executing "
                              "$objdir/_tests/testing/mochitest/runtests.py?".format(
                                  options.app))
 
+        if options.flavor is None:
+            options.flavor = 'plain'
+
         if options.gmp_path is None and options.app and build_obj:
             # Need to fix the location of gmp_fake which might not be shipped in the binary
             gmp_modules = (
                 ('gmp-fake', '1.0'),
                 ('gmp-clearkey', '0.1'),
                 ('gmp-fakeopenh264', '1.0')
             )
             options.gmp_path = os.pathsep.join(