Bug 1147031 - Write mach command for luciddream. r=jgriffin
☠☠ backed out by e580bfc4a232 ☠ ☠
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 02 Apr 2015 10:55:00 -0400
changeset 237915 a209d4d37f8f9673258e87361acc16d1e6a08e22
parent 237914 61b5d6d08c8adc6086cadcd4a66b731bf60a8f3c
child 237916 a67a0be7325e9f707639a638e961dda35bfba38d
push id58061
push userryanvm@gmail.com
push dateTue, 07 Apr 2015 14:52:32 +0000
treeherdermozilla-inbound@a67a0be7325e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgriffin
bugs1147031
milestone40.0a1
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 1147031 - Write mach command for luciddream. r=jgriffin
build/mach_bootstrap.py
testing/luciddream/luciddream/__init__.py
testing/luciddream/luciddream/runluciddream.py
testing/luciddream/mach_commands.py
testing/mach_commands.py
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -47,16 +47,17 @@ SEARCH_PATHS = [
     'testing',
     'testing/taskcluster',
     'testing/xpcshell',
     'testing/web-platform',
     'testing/web-platform/harness',
     'testing/marionette/client',
     'testing/marionette/transport',
     'testing/marionette/driver',
+    'testing/luciddream',
     'testing/mozbase/mozcrash',
     'testing/mozbase/mozdebug',
     'testing/mozbase/mozdevice',
     'testing/mozbase/mozfile',
     'testing/mozbase/mozhttpd',
     'testing/mozbase/mozlog',
     'testing/mozbase/moznetwork',
     'testing/mozbase/mozprocess',
@@ -79,16 +80,17 @@ MACH_MODULES = [
     'python/mach_commands.py',
     'python/mach/mach/commands/commandinfo.py',
     'python/compare-locales/mach_commands.py',
     'python/mozboot/mozboot/mach_commands.py',
     'python/mozbuild/mozbuild/mach_commands.py',
     'python/mozbuild/mozbuild/backend/mach_commands.py',
     'python/mozbuild/mozbuild/frontend/mach_commands.py',
     'services/common/tests/mach_commands.py',
+    'testing/luciddream/mach_commands.py',
     'testing/mach_commands.py',
     'testing/taskcluster/mach_commands.py',
     'testing/marionette/mach_commands.py',
     'testing/mochitest/mach_commands.py',
     'testing/xpcshell/mach_commands.py',
     'testing/talos/mach_commands.py',
     'testing/web-platform/mach_commands.py',
     'testing/xpcshell/mach_commands.py',
--- a/testing/luciddream/luciddream/__init__.py
+++ b/testing/luciddream/luciddream/__init__.py
@@ -5,18 +5,19 @@
 #
 
 import os
 import sys
 from marionette.marionette_test import MarionetteTestCase, MarionetteJSTestCase
 from marionette_driver.errors import ScriptTimeoutException
 
 class LucidDreamTestCase(MarionetteTestCase):
-    def __init__(self, marionette_weakref, browser=None, **kwargs):
+    def __init__(self, marionette_weakref, browser=None, logger=None, **kwargs):
         self.browser = browser
+        self.logger = logger
         MarionetteTestCase.__init__(self, marionette_weakref, **kwargs)
 
     def run_js_test(self, filename, marionette):
         '''
         Run a JavaScript test file and collect its set of assertions
         into the current test's results.
 
         :param filename: The path to the JavaScript test file to execute.
--- a/testing/luciddream/luciddream/runluciddream.py
+++ b/testing/luciddream/luciddream/runluciddream.py
@@ -71,81 +71,80 @@ def parse_args(in_args):
 
 class LucidDreamTestRunner(BaseMarionetteTestRunner):
     def __init__(self, **kwargs):
         BaseMarionetteTestRunner.__init__(self, **kwargs)
         #TODO: handle something like MarionetteJSTestCase
         self.test_handlers = [LucidDreamTestCase]
 
 
-def start_browser(browserPath):
+def start_browser(browserPath, app_args):
     '''
     Start a Firefox browser and return a Marionette instance that
     can talk to it.
     '''
     marionette = Marionette(
         bin=browserPath,
         # Need to avoid the browser and emulator's ports stepping
         # on each others' toes.
         port=2929,
+        app_args=app_args,
+        gecko_log="firefox.log"
     )
     runner = marionette.runner
     if runner:
         runner.start()
     marionette.wait_for_port()
     marionette.start_session()
     marionette.set_context(marionette.CONTEXT_CHROME)
     return marionette
 
 
 #TODO: make marionette/client/marionette/runtests.py importable so we can
 # just use cli from there. A lot of this is copy/paste from that function.
-def main():
-    try:
-        args = parse_args(sys.argv[1:])
-    except CommandLineError as e:
-        return 1
-
-    logger = structured.commandline.setup_logging(
-        'luciddream', args, {"tbpl": sys.stdout})
+def main(firefox=None, b2g_desktop=None, emulator=None, emulator_arch=None, gaia_profile=None, manifest=None, browser_args=None, **kwargs):
 
     # It's sort of debatable here whether the marionette instance managed
     # by the test runner should be the browser or the emulator. Right now
     # it's the emulator because it feels like there's more fiddly setup around
     # that, but longer-term if we want to run tests against different
     # (non-B2G) targets this won't match up very well, so maybe it ought to
     # be the browser?
-    browser = start_browser(args.browserPath)
-    kwargs = {
-        'browser': browser,
-        'logger': logger,
-    }
-    if args.b2gPath:
-        kwargs['homedir'] = args.b2gPath
-        kwargs['emulator'] = args.emulator
-    elif args.b2gDesktopPath:
+    browser = start_browser(firefox, browser_args)
+
+    kwargs["browser"] = browser
+    if not "logger" in kwargs:
+        logger = structured.commandline.setup_logging(
+            "luciddream", kwargs, {"tbpl": sys.stdout})
+        kwargs["logger"] = logger
+
+    if emulator:
+        kwargs['homedir'] = emulator
+        kwargs['emulator'] = emulator_arch
+    elif b2g_desktop:
         # Work around bug 859952
-        if '-bin' not in args.b2gDesktopPath:
-            if args.b2gDesktopPath.endswith('.exe'):
-                newpath = args.b2gDesktopPath[:-4] + '-bin.exe'
+        if '-bin' not in b2g_desktop:
+            if b2g_desktop.endswith('.exe'):
+                newpath = b2g_desktop[:-4] + '-bin.exe'
             else:
-                newpath = args.b2gDesktopPath + '-bin'
+                newpath = b2g_desktop + '-bin'
             if os.path.exists(newpath):
-                args.b2gDesktopPath = newpath
-        kwargs['binary'] = args.b2gDesktopPath
+                b2g_desktop = newpath
+        kwargs['binary'] = b2g_desktop
         kwargs['app'] = 'b2gdesktop'
-        if args.gaiaProfile:
-            kwargs['profile'] = args.gaiaProfile
+        if gaia_profile:
+            kwargs['profile'] = gaia_profile
         else:
             kwargs['profile'] = os.path.join(
-                os.path.dirname(args.b2gDesktopPath),
+                os.path.dirname(b2g_desktop),
                 'gaia',
                 'profile'
             )
     runner = LucidDreamTestRunner(**kwargs)
-    runner.run_tests([args.manifest])
+    runner.run_tests([manifest])
     if runner.failed > 0:
         sys.exit(10)
     sys.exit(0)
 
 
 if __name__ == '__main__':
-    main()
+    args = parse_args(sys.argv[1:])
+    main(args)
new file mode 100644
--- /dev/null
+++ b/testing/luciddream/mach_commands.py
@@ -0,0 +1,99 @@
+# 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/.
+
+# Integrates luciddream test runner with mach.
+
+import os
+import re
+import sys
+
+import mozpack.path as mozpath
+
+from mozbuild.base import (
+    MachCommandBase,
+    MachCommandConditions as conditions,
+    MozbuildObject,
+)
+
+from mach.decorators import (
+    CommandArgument,
+    CommandProvider,
+    Command,
+)
+
+class LucidDreamRunner(MozbuildObject):
+    """Run luciddream tests."""
+    def run_tests(self, **kwargs):
+        self._run_make(target='jetpack-tests')
+
+@CommandProvider
+class MachCommands(MachCommandBase):
+    @Command('luciddream', category='testing',
+        description='Runs the luciddream test suite.')
+    @CommandArgument("--consoles", dest="consoles", action="store_true",
+                     help="Open jsconsole in both runtimes.")
+    @CommandArgument('--b2g-desktop', type=str, default=None,
+                     help='Path to b2g desktop binary.')
+    @CommandArgument('--firefox', type=str, default=None,
+                     help='Path to firefox binary.')
+    @CommandArgument('--gaia-profile', type=str, default=None,
+                     help='Path to gaia profile, optional, if not bundled with b2g desktop.')
+    @CommandArgument('--emulator', type=str, default=None,
+                     help='Path to android emulator.')
+    @CommandArgument('--emulator-arch', type=str, default="x86",
+                     help='Emulator arch: x86 or arm.')
+    @CommandArgument('test_paths', default=None, nargs='*', metavar='TEST',
+                     help='Test to run. Can be specified as a single file, a '
+                          'directory, or omitted. If omitted, the entire test suite is '
+                          'executed.')
+    def run_luciddream_test(self, firefox, b2g_desktop, test_paths, consoles, **params):
+        # import luciddream lazily as its marionette dependency make ./mach clobber fails
+        # early on TBPL
+        import luciddream.runluciddream
+
+        # get_binary_path is going to throw if we haven't built any product
+        # but luciddream can still be run if we provide both binaries...
+        binary_path=False
+        try:
+            binary_path = self.get_binary_path()
+        except Exception:
+            pass
+
+        # otherwise, if we have a build, automatically fetch the binary
+        if conditions.is_b2g(self):
+            if not b2g_desktop and binary_path:
+                b2g_desktop = binary_path
+        else:
+            if not firefox and binary_path:
+                firefox = binary_path
+
+        if not firefox:
+            print "Need firefox binary path via --firefox argument"
+            return 1
+        elif not os.path.exists(firefox):
+            print "Firefox binary doesn't exists: " + firefox
+            return 1
+
+        if not b2g_desktop:
+            print "Need b2g desktop binary path via --b2g-desktop argument"
+            return 1
+        elif not os.path.exists(b2g_desktop):
+            print "B2G desktop binary doesn't exists: " + b2g_desktop
+            return 1
+
+        if not test_paths or len(test_paths) == 0:
+            print "Please specify a test manifest to run"
+            return 1
+
+        browser_args = None
+        if consoles:
+            browser_args = ["-jsconsole"]
+            if "app_args" in params and isinstance(params["app_args"], list):
+                params["app_args"].append("-jsconsole")
+            else:
+                params["app_args"] = ["-jsconsole"]
+
+        for test in test_paths:
+          luciddream.runluciddream.main(firefox=firefox, b2g_desktop=b2g_desktop,
+            manifest=test, browser_args=browser_args, **params)
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -82,16 +82,20 @@ TEST_SUITES = {
     },
     'mochitest-ipcplugins': {
         'make_target': 'mochitest-ipcplugins',
     },
     'mochitest-plain': {
         'mach_command': 'mochitest',
         'kwargs': {'flavor': 'mochitest', 'test_paths': None},
     },
+    'luciddream': {
+        'mach_command': 'luciddream',
+        'kwargs': {'test_paths': None},
+    },
     'reftest': {
         'aliases': ('RR', 'rr', 'Rr'),
         'mach_command': 'reftest',
         'kwargs': {'test_file': None},
     },
     'reftest-ipc': {
         'aliases': ('Ripc',),
         'mach_command': 'reftest-ipc',