gecko-dev/testing/marionette/mach_test_package_commands.py
Ricky Stewart 31755b431d Bug 1657650 - Require that Mach command providers subclass MachCommandBase. r=remote-protocol-reviewers,marionette-reviewers,maja_zf,mhentges,froydnj
Today we don't require that `mach` `CommandProvider`s subclass from any particular parent class and we're very lax about the requirements they must meet. While that's convenient in certain circumstances, it has some unfortunate implications for feature development.

Today the only requirements that we have for `CommandProvider`s are that they have an `__init__()` method that takes either 1 or 2 arguments, the second of which must be called `context` and is populated with the `mach` `CommandContext`. Again, while this flexibility is occasionally convenient, it is limiting. As we add features to `mach`, having a better idea what the shape of our `CommandProvider`s are and how we can instantiate them and use them is increasingly important, and this gives us additional control when having `mach` configure `CommandProvider`s based on data that is only available at the `mach` level. In particular, we plan to leverage this in bugs 985141 and 1654074.

Here we add validation to the `CommandProvider` decorator to ensure all classes inherit from `MachCommandBase`, update all `CommandProvider`s in-tree to inherit from `MachCommandBase`, and update source and test code accordingly.

Follow-up work: we now require (de facto) that the `context` be populated with a `topdir` attribute by the `populate_context_handler` function, since instantiating the `MachCommandBase` requires a `topdir` be provided. This is fine for now in the interest of keeping this patch reasonably sized, but some additional refactoring could make this cleaner.

Differential Revision: https://phabricator.services.mozilla.com/D86255
2020-08-07 18:24:59 +00:00

68 lines
2.0 KiB
Python

# 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
import argparse
import os
import sys
from functools import partial
from mach.decorators import (
CommandProvider,
Command,
)
from mozbuild.base import MachCommandBase
parser = None
def run_marionette(context, **kwargs):
from marionette.runtests import (
MarionetteTestRunner,
MarionetteHarness
)
from mozlog.structured import commandline
args = argparse.Namespace(**kwargs)
args.binary = args.binary or context.firefox_bin
test_root = os.path.join(context.package_root, 'marionette', 'tests')
if not args.tests:
args.tests = [os.path.join(test_root, 'testing', 'marionette', 'harness',
'marionette_harness', 'tests', 'unit-tests.ini')]
normalize = partial(context.normalize_test_path, test_root)
args.tests = list(map(normalize, args.tests))
commandline.add_logging_group(parser)
parser.verify_usage(args)
args.logger = commandline.setup_logging("Marionette Unit Tests",
args,
{"mach": sys.stdout})
status = MarionetteHarness(MarionetteTestRunner, args=vars(args)).run()
return 1 if status else 0
def setup_marionette_argument_parser():
from marionette.runner.base import BaseMarionetteArguments
global parser
parser = BaseMarionetteArguments()
return parser
@CommandProvider
class MachCommands(MachCommandBase):
@Command(
'marionette-test', category='testing',
description='Run a Marionette test (Check UI or the internal JavaScript '
'using marionette).',
parser=setup_marionette_argument_parser)
def run_marionette_test(self, **kwargs):
self.context.activate_mozharness_venv()
return run_marionette(self.context, **kwargs)