Bug 1395933 - Expand geckodriver mach command with test and build targets. r?maja_zf,rillian draft
authorAndreas Tolfsen <ato@sny.no>
Wed, 13 Dec 2017 10:11:56 -0600
changeset 711231 2df16b9f5b5324d479cac387d62b74416ce9cb29
parent 711227 fb422b4bf275d34b7053d0c9a35fd18967944c72
child 743771 8cedd511a0d962970aa735be8a48fa9edd48fb11
push id93028
push userbmo:ato@sny.no
push dateWed, 13 Dec 2017 16:12:59 +0000
reviewersmaja_zf, rillian
bugs1395933
milestone59.0a1
Bug 1395933 - Expand geckodriver mach command with test and build targets. r?maja_zf,rillian The current "./mach geckodriver" commands runs the geckodriver binary, but this patch introduces a geckodriver namespace to mach and renames that command to "./mach geckodriver run". It also introduces two new commands to build geckodriver and run its Rust unit tests through "./mach geckodriver build" and "./mach geckodriver test", respectively. MozReview-Commit-ID: 5iO9FVkbch2
testing/geckodriver/CONTRIBUTING.md
testing/geckodriver/README.md
testing/geckodriver/mach_commands.py
--- a/testing/geckodriver/CONTRIBUTING.md
+++ b/testing/geckodriver/CONTRIBUTING.md
@@ -119,22 +119,22 @@ Whilst geckodriver lives in the same sou
 and is built in the [Firefox CI], is _is not_ built if you build
 Firefox locally.  To enable building of geckodriver locally, ensure
 you put this in your [mozconfig]:
 
 	ac_add_options --enable-geckodriver
 
 When you have, you are ready to start off your first build:
 
-	% ./mach build testing/geckodriver
+	% ./mach geckodriver build
 
 The geckodriver executable will appear in `${objdir}/dist/bin/geckodriver`
 alongside firefox-bin.  To run it you can use mach:
 
-	% ./mach geckodriver -- --version
+	% ./mach geckodriver run -- --version
 	 0:00.27 /home/ato/src/gecko/obj-x86_64-pc-linux-gnu/dist/bin/geckodriver --version --binary /home/ato/src/gecko/obj-x86_64-pc-linux-gnu/dist/bin/firefox
 	geckodriver 0.19.0 (f3e939a81ee1169f9501ad96eb43bbf4bf4a1bde 2017-10-11)
 
 [Rust]: https://www.rust-lang.org/
 [webdriver crate]: ../webdriver/README.md
 [commands]: https://docs.rs/webdriver/newest/webdriver/command/index.html
 [responses]: https://docs.rs/webdriver/newest/webdriver/response/index.html
 [errors]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html
@@ -149,28 +149,27 @@ Running the tests
 
 We verify and test geckodriver in a couple of different ways.
 Since it is an implementation of the WebDriver web standard, we share
 a set of conformance tests with other browser vendors through the
 [Web Platform Tests] (WPT) initiative.  This lets us ensure web
 compatibility between _different_ WebDriver implementations for
 different browsers.
 
-In addition to the WPT tests, geckodriver and libwebdriver has
-unit tests.  At the moment there is no way to run Rust unit tests
-through mach, although this is being worked on.  For the moment
-you need to kick off a separate build using [cargo]:
+In addition to the WPT tests, geckodriver and webdriver have unit tests.
+You can also use the mach geckodriver command to run geckodriver tests:
+
+	% ./mach geckodriver test
 
-	% cd testing/geckodriver
-	   Compiling geckodriver v0.19.0 (file:///home/ato/src/gecko/testing/geckodriver)
-	…
-	test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
+The webdriver crate tests are unfortunately not yet runnable through mach.
+Work to make this possible is tracked in [[https://bugzil.la/1424369]].
+For the moment you must run them manually through `cargo`:
 
-Because the unit tests _are not_ currently run in the [Firefox CI],
-hopefully you will find that they all pass. (-:
+	% cd testing/webdriver
+	% cargo test
 
 To run the more extensive WPT tests you can use mach, but first
 make sure you have a build of Firefox:
 
 	% ./mach build
 	% ./mach wpt testing/web-platform/tests/webdriver
 
 As these are functional integration tests and pop up Firefox windows
--- a/testing/geckodriver/README.md
+++ b/testing/geckodriver/README.md
@@ -573,16 +573,22 @@ geckodriver is built in the [Firefox CI]
 build Firefox locally.  To enable building of geckodriver locally,
 ensure you put this in your [mozconfig]:
 
 	ac_add_options --enable-geckodriver
 
 The _geckodriver_ binary will appear in `${objdir}/dist/bin/geckodriver`
 alongside _firefox-bin_.
 
+The following self-explanatory targets are available through mach:
+
+  * `./mach geckodriver build`
+  * `./mach geckodriver test`
+  * `./mach geckodriver run`
+
 [Rust]: https://www.rust-lang.org/
 [Mozilla]: https://www.mozilla.org/en-US/
 [webdriver crate]: https://github.com/mozilla/webdriver-rust
 [commands]: https://docs.rs/webdriver/0.25.0/webdriver/command/index.html
 [responses]: https://docs.rs/webdriver/0.25.0/webdriver/response/index.html
 [errors]: https://docs.rs/webdriver/0.25.0/webdriver/error/enum.ErrorStatus.html
 [Marionette protocol]: https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Protocol
 [WebDriver]: https://w3c.github.io/webdriver/webdriver-spec.html
--- a/testing/geckodriver/mach_commands.py
+++ b/testing/geckodriver/mach_commands.py
@@ -1,64 +1,77 @@
+# 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, print_function, unicode_literals
+
 import argparse
 import os
 
-from mozbuild.base import (
-    MachCommandBase
-)
-
 from mach.decorators import (
+    Command,
     CommandArgument,
     CommandArgumentGroup,
     CommandProvider,
-    Command,
+    SubCommand,
+)
+
+from mozbuild.base import (
+    MachCommandBase,
+    MachCommandConditions as conditions,
 )
 
 
 @CommandProvider
-class RunGeckodriver(MachCommandBase):
-    """Run the compiled program."""
+class GeckoDriver(MachCommandBase):
+
+    @Command("geckodriver",
+        category="post-build",
+        description="WebDriver implementation for Gecko",
+        conditions=[conditions.is_firefox])
+    def geckodriver(self):
+        pass
 
-    @Command('geckodriver', category='post-build',
-        description='Run the geckodriver WebDriver implementation')
-    @CommandArgument('--binary', type=str,
-        help='Firefox binary (defaults to the local build).')
-    @CommandArgument('params', nargs='...',
-        help='Command-line arguments to be passed through to the program.')
-
-    @CommandArgumentGroup('debugging')
-    @CommandArgument('--debug', action='store_true', group='debugging',
-        help='Enable the debugger. Not specifying a --debugger option will result in the default debugger being used.')
-    @CommandArgument('--debugger', default=None, type=str, group='debugging',
-        help='Name of debugger to use.')
-    @CommandArgument('--debugger-args', default=None, metavar='params', type=str,
-        group='debugging',
-        help='Command-line arguments to pass to the debugger itself; split as the Bourne shell would.')
+    @SubCommand("geckodriver", "run",
+        description="Run geckodriver.")
+    @CommandArgument("--binary", type=str,
+        help="Firefox binary (defaults to the local build).")
+    @CommandArgument("params", nargs="...",
+        help="Flags to be passed through to geckodriver.")
+    @CommandArgumentGroup("debugging")
+    @CommandArgument("--debug", action="store_true", group="debugging",
+        help="Enable the debugger. Not specifying a --debugger option will result in the default debugger being used.")
+    @CommandArgument("--debugger", default=None, type=str, group="debugging",
+        help="Name of debugger to use.")
+    @CommandArgument("--debugger-args", default=None, metavar="params", type=str,
+        group="debugging",
+        help="Flags to pass to the debugger itself; split as the Bourne shell would.")
     def run(self, binary, params, debug, debugger, debugger_args):
         try:
-            binpath = self.get_binary_path('geckodriver')
+            binpath = self.get_binary_path("geckodriver")
         except Exception as e:
                 print("It looks like geckodriver isn't built. "
                       "Add ac_add_options --enable-geckodrver to your mozconfig ",
                       "and run |mach build| to build it.")
                 print(e)
                 return 1
 
         args = [binpath]
 
         if params:
             args.extend(params)
 
         if binary is None:
-            binary = self.get_binary_path('app')
+            binary = self.get_binary_path("app")
 
         args.extend(["--binary", binary])
 
         if debug or debugger or debugger_args:
-            if 'INSIDE_EMACS' in os.environ:
+            if "INSIDE_EMACS" in os.environ:
                 self.log_manager.terminal_handler.setLevel(logging.WARNING)
 
             import mozdebug
             if not debugger:
                 # No debugger name was provided. Look for the default ones on
                 # current OS.
                 debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)
 
@@ -79,8 +92,38 @@ class RunGeckodriver(MachCommandBase):
                     print("(We can't handle the %r character.)" % e.char)
                     return 1
 
             # Prepend the debugger args.
             args = [self.debuggerInfo.path] + self.debuggerInfo.args + args
 
         return self.run_process(args=args, ensure_exit_code=False,
             pass_thru=True)
+
+    @SubCommand("geckodriver", "build",
+        description="Build geckodriver.")
+    @CommandArgument("-v", "--verbose", action="store_true",
+        help="Verbose output for what commands the build is running.")
+    def build(self, verbose=False):
+        from mozbuild.controller.building import BuildDriver
+
+        self.log_manager.enable_all_structured_loggers()
+
+        driver = self._spawn(BuildDriver)
+        return driver.build(
+            what=["testing/geckodriver"],
+            verbose=verbose,
+            mach_context=self._mach_context)
+
+    @SubCommand("geckodriver", "test",
+        description="Run geckodriver unit tests.")
+    @CommandArgument("-v", "--verbose", action="store_true",
+        help="Verbose output for what commands the build is running.")
+    def test(self, verbose=False):
+        from mozbuild.controller.building import BuildDriver
+
+        self.log_manager.enable_all_structured_loggers()
+
+        driver = self._spawn(BuildDriver)
+        return driver.build(
+            what=["testing/geckodriver/check"],
+            verbose=verbose,
+            mach_context=self._mach_context)