mach_commands.py (3673B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import argparse 6 import functools 7 import logging 8 import os 9 import sys 10 11 from mach.decorators import Command, CommandArgument 12 from mozbuild.base import ( 13 MachCommandConditions as conditions, 14 BinaryNotFoundException, 15 ) 16 17 SUPPORTED_APPS = ["firefox", "android", "thunderbird"] 18 19 20 def create_parser_tests(): 21 from marionette_harness.runtests import MarionetteArguments 22 from mozlog.structured import commandline 23 24 parser = MarionetteArguments() 25 commandline.add_logging_group(parser) 26 return parser 27 28 29 def run_marionette( 30 tests, binary=None, topsrcdir=None, allow_nonlocal_connections=False, **kwargs 31 ): 32 from mozlog.structured import commandline 33 34 from marionette_harness.runtests import MarionetteTestRunner, MarionetteHarness 35 36 parser = create_parser_tests() 37 38 args = argparse.Namespace(tests=tests) 39 40 args.binary = binary 41 args.logger = kwargs.pop("log", None) 42 43 for k, v in kwargs.items(): 44 setattr(args, k, v) 45 46 parser.verify_usage(args) 47 48 # Causes Firefox to crash when using non-local connections. 49 if not allow_nonlocal_connections: 50 os.environ["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" 51 52 if not args.logger: 53 args.logger = commandline.setup_logging( 54 "Marionette Unit Tests", args, {"mach": sys.stdout} 55 ) 56 failed = MarionetteHarness(MarionetteTestRunner, args=vars(args)).run() 57 if failed > 0: 58 return 1 59 else: 60 return 0 61 62 63 @Command( 64 "marionette-test", 65 category="testing", 66 description="Remote control protocol to Gecko, used for browser automation.", 67 conditions=[functools.partial(conditions.is_buildapp_in, apps=SUPPORTED_APPS)], 68 parser=create_parser_tests, 69 ) 70 @CommandArgument( 71 "--allow-nonlocal-connections", 72 dest="allow_nonlocal_connections", 73 action="store_true", 74 default=False, 75 help="Allow loading of websites from remote locations. Only use it for local testing!", 76 ) 77 def marionette_test(command_context, tests, allow_nonlocal_connections=False, **kwargs): 78 if "test_objects" in kwargs: 79 tests = [] 80 for obj in kwargs["test_objects"]: 81 tests.append(obj["path"]) 82 del kwargs["test_objects"] 83 84 if not tests: 85 if conditions.is_thunderbird(command_context): 86 tests = [ 87 os.path.join( 88 command_context.topsrcdir, 89 "comm/testing/marionette/unit-tests.toml", 90 ) 91 ] 92 else: 93 tests = [ 94 os.path.join( 95 command_context.topsrcdir, 96 "testing/marionette/harness/marionette_harness/tests/unit-tests.toml", 97 ) 98 ] 99 100 if not kwargs.get("binary") and ( 101 conditions.is_firefox(command_context) 102 or conditions.is_thunderbird(command_context) 103 ): 104 try: 105 kwargs["binary"] = command_context.get_binary_path("app") 106 except BinaryNotFoundException as e: 107 command_context.log( 108 logging.ERROR, 109 "marionette-test", 110 {"error": str(e)}, 111 "ERROR: {error}", 112 ) 113 command_context.log( 114 logging.INFO, "marionette-test", {"help": e.help()}, "{help}" 115 ) 116 return 1 117 118 return run_marionette( 119 tests, 120 topsrcdir=command_context.topsrcdir, 121 allow_nonlocal_connections=allow_nonlocal_connections, 122 **kwargs 123 )