--- a/testing/config/mozharness/android_arm_4_3_config.py
+++ b/testing/config/mozharness/android_arm_4_3_config.py
@@ -31,19 +31,19 @@ config = {
"run_filename": "runtestsremote.py",
"testsdir": "mochitest",
"options": ["--dm_trans=adb", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
"--quiet", "--log-raw=%(raw_log_file)s",
"--total-chunks=4",
- "--robocop-path=../..",
+ "--robocop-apk=../../robocop.apk",
"--robocop-ids=fennec_ids.txt",
- "--robocop=robocop.ini",
+ "--robocop-ini=robocop.ini",
],
},
"reftest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [ "--app=%(app)s", "--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
--- a/testing/config/mozharness/android_arm_config.py
+++ b/testing/config/mozharness/android_arm_config.py
@@ -34,19 +34,19 @@ config = {
"testsdir": "mochitest",
"options": ["--dm_trans=sut", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
"--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
"--quiet", "--log-raw=%(raw_log_file)s",
"--total-chunks=4",
- "--robocop-path=../..",
+ "--robocop-apk=../../robocop.apk",
"--robocop-ids=fennec_ids.txt",
- "--robocop=robocop.ini",
+ "--robocop-ini=robocop.ini",
],
},
"reftest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [ "--app=%(app)s", "--ignore-window-size",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -276,27 +276,31 @@ class MochitestRunner(MozbuildObject):
options.manifestFile = manifest
# We need this to enable colorization of output.
self.log_manager.enable_unstructured()
result = mochitest.run_test_harness(options)
self.log_manager.disable_unstructured()
return result
- def run_android_test(self, args):
+ def run_android_test(self, test_path, **kwargs):
self.tests_dir = os.path.join(self.topobjdir, '_tests')
self.mochitest_dir = os.path.join(self.tests_dir, 'testing', 'mochitest')
import imp
path = os.path.join(self.mochitest_dir, 'runtestsremote.py')
with open(path, 'r') as fh:
imp.load_module('runtestsremote', fh, path,
('.py', 'r', imp.PY_SOURCE))
import runtestsremote
- sys.exit(runtestsremote.main(args))
+ options = Namespace(**kwargs)
+ if test_path:
+ options.testPath = test_path
+
+ sys.exit(runtestsremote.run_test_harness(options))
# parser
def TestPathArg(func):
test_paths = CommandArgument('test_paths', nargs='*', metavar='TEST', default=None,
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.')
@@ -593,83 +597,51 @@ class MachCommands(MachCommandBase):
self._ensure_state_subdir_exists('.')
driver = self._spawn(BuildDriver)
driver.install_tests(remove=False)
mochitest = self._spawn(MochitestRunner)
return mochitest.run_b2g_test(test_paths=test_paths, **kwargs)
- def run_mochitest_android(self, test_paths, chrome=False, **kwargs):
+ def run_mochitest_android(self, test_paths, **kwargs):
host_ret = verify_host_bin()
if host_ret != 0:
return host_ret
- args = [
- '--xre-path=' + os.environ.get('MOZ_HOST_BIN'),
- '--dm_trans=adb',
- '--deviceIP=',
- '--console-level=INFO',
- '--app=' + self.substs['ANDROID_PACKAGE_NAME'],
- '--log-mach=-',
- '--autorun',
- '--close-when-done',
- '--testing-modules-dir=' + os.path.join(self.topobjdir, '_tests', 'modules'),
- ]
+ test_path = None
if test_paths:
if len(test_paths) > 1:
print('Warning: Only the first test path will be used.')
test_path = self._wrap_path_argument(test_paths[0]).relpath()
- args.append('--test-path=%s' % test_path)
- if chrome:
- args.append('--chrome')
mochitest = self._spawn(MochitestRunner)
- return mochitest.run_android_test(args)
+ return mochitest.run_android_test(test_path, **kwargs)
@CommandProvider
class AndroidCommands(MachCommandBase):
@Command('robocop', category='testing',
conditions=[conditions.is_android],
- description='Run a Robocop test.')
+ description='Run a Robocop test.',
+ parser=setup_argument_parser)
@CommandArgument(
'test_path',
default=None,
nargs='?',
metavar='TEST',
help='Test to run. Can be specified as a Robocop test name (like "testLoad"), '
'or omitted. If omitted, the entire test suite is executed.')
- def run_robocop(self, test_path):
+ def run_robocop(self, test_path, **kwargs):
host_ret = verify_host_bin()
if host_ret != 0:
return host_ret
- args = [
- '--xre-path=' + os.environ.get('MOZ_HOST_BIN'),
- '--dm_trans=adb',
- '--deviceIP=',
- '--console-level=INFO',
- '--app=' +
- self.substs['ANDROID_PACKAGE_NAME'],
- '--robocop-apk=' +
- os.path.join(
- self.topobjdir,
- 'build',
- 'mobile',
- 'robocop',
- 'robocop-debug.apk'),
- '--robocop-ini=' +
- os.path.join(
- self.topobjdir,
- 'build',
- 'mobile',
- 'robocop',
- 'robocop.ini'),
- '--log-mach=-',
- ]
+ if not kwargs.get('robocopIni'):
+ kwargs['robocopIni'] = os.path.join(self.topobjdir, 'build', 'mobile',
+ 'robocop', 'robocop.ini')
- if test_path:
- args.append('--test-path=%s' % test_path)
-
+ if not kwargs.get('robocopApk'):
+ kwargs['robocopApk'] = os.path.join(self.topobjdir, 'build', 'mobile',
+ 'robocop', 'robocop-debug.apk')
mochitest = self._spawn(MochitestRunner)
- return mochitest.run_android_test(args)
+ return mochitest.run_android_test(test_path, **kwargs)
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -513,17 +513,17 @@ class MochitestArguments(ArgumentContain
'webSocketPort': '9988',
# The default websocket port is incorrect in mozprofile; it is
# set to the SSL proxy setting. See:
# see https://bugzilla.mozilla.org/show_bug.cgi?id=916517
# args.webSocketPort = DEFAULT_PORTS['ws']
}
def validate(self, parser, options, context):
- """ verify correct options and cleanup paths """
+ """Validate generic options."""
# for test manifest parsing.
mozinfo.update({"strictContentSandbox": options.strictContentSandbox})
# for test manifest parsing.
mozinfo.update({"nested_oop": options.nested_oop})
# b2g and android don't use 'app' the same way, so skip validation
if parser.app not in ('b2g', 'android'):
@@ -845,16 +845,18 @@ class B2GArguments(ArgumentContainer):
defaults = {
'logFile': 'mochitest.log',
'extensionsToExclude': ['specialpowers'],
# See dependencies of bug 1038943.
'defaultLeakThreshold': 5536,
}
def validate(self, parser, options, context):
+ """Validate b2g options."""
+
if options.desktop and not options.app:
if not (build_obj and conditions.is_b2g_desktop(build_obj)):
parser.error(
"--desktop specified, but no b2g desktop build detected! Either "
"build for b2g desktop, or point --appname to a b2g desktop binary.")
elif build_obj and conditions.is_b2g_desktop(build_obj):
options.desktop = True
if not options.app:
@@ -945,96 +947,93 @@ class AndroidArguments(ArgumentContainer
{"dest": "deviceSerial",
"help": "ip address of remote device to test",
"default": None,
}],
[["--dm_trans"],
{"choices": ["adb", "sut"],
"default": "adb",
"help": "The transport to use for communication with the device [default: adb].",
+ "suppress": True,
}],
[["--devicePort"],
{"dest": "devicePort",
"type": int,
"default": 20701,
"help": "port of remote device to test",
}],
[["--remote-product-name"],
{"dest": "remoteProductName",
"default": "fennec",
"help": "The executable's name of remote product to test - either \
fennec or firefox, defaults to fennec",
+ "suppress": True,
}],
[["--remote-logfile"],
{"dest": "remoteLogFile",
"default": None,
"help": "Name of log file on the device relative to the device \
root. PLEASE ONLY USE A FILENAME.",
}],
[["--remote-webserver"],
{"dest": "remoteWebServer",
"default": None,
"help": "ip address where the remote web server is hosted at",
}],
[["--http-port"],
{"dest": "httpPort",
"default": DEFAULT_PORTS['http'],
"help": "http port of the remote web server",
+ "suppress": True,
}],
[["--ssl-port"],
{"dest": "sslPort",
"default": DEFAULT_PORTS['https'],
"help": "ssl port of the remote web server",
+ "suppress": True,
}],
[["--robocop-ini"],
{"dest": "robocopIni",
"default": "",
"help": "name of the .ini file containing the list of tests to run",
}],
- [["--robocop"],
- {"dest": "robocop",
- "default": "",
- "help": "name of the .ini file containing the list of tests to run. \
- [DEPRECATED- please use --robocop-ini",
- }],
[["--robocop-apk"],
{"dest": "robocopApk",
"default": "",
"help": "name of the Robocop APK to use for ADB test running",
}],
- [["--robocop-path"],
- {"dest": "robocopPath",
- "default": "",
- "help": "Path to the folder where robocop.apk is located at. \
- Primarily used for ADB test running. \
- [DEPRECATED- please use --robocop-apk]",
- }],
[["--robocop-ids"],
{"dest": "robocopIds",
"default": "",
"help": "name of the file containing the view ID map \
(fennec_ids.txt)",
}],
[["--remoteTestRoot"],
{"dest": "remoteTestRoot",
"default": None,
"help": "remote directory to use as test root \
(eg. /mnt/sdcard/tests or /data/local/tests)",
+ "suppress": True,
}],
]
defaults = {
'dm': None,
'logFile': 'mochitest.log',
'utilityPath': None,
}
def validate(self, parser, options, context):
+ """Validate android options."""
+
+ if build_obj:
+ options.log_mach = '-'
+
if options.dm_trans == "adb":
- if (options.deviceIP):
+ if options.deviceIP:
options.dm = DroidADB(
options.deviceIP,
options.devicePort,
deviceRoot=options.remoteTestRoot)
elif options.deviceSerial:
options.dm = DroidADB(
None,
None,
@@ -1073,53 +1072,46 @@ class AndroidArguments(ArgumentContainer
'/' + options.remoteLogFile
if options.remoteAppPath and options.app:
parser.error(
"You cannot specify both the remoteAppPath and the app setting")
elif options.remoteAppPath:
options.app = options.remoteTestRoot + "/" + options.remoteAppPath
elif options.app is None:
- # Neither remoteAppPath nor app are set -- error
- parser.error("You must specify either appPath or app")
+ if build_obj:
+ options.app = build_obj.substs['ANDROID_PACKAGE_NAME']
+ else:
+ # Neither remoteAppPath nor app are set -- error
+ parser.error("You must specify either appPath or app")
+
+ if 'MOZ_HOST_BIN' in os.environ:
+ options.xrePath = os.environ['MOZ_HOST_BIN']
# Only reset the xrePath if it wasn't provided
if options.xrePath is None:
options.xrePath = options.utilityPath
if options.pidFile != "":
f = open(options.pidFile, 'w')
f.write("%s" % os.getpid())
f.close()
- # Robocop specific deprecated options.
- if options.robocop:
- if options.robocopIni:
- parser.error(
- "can not use deprecated --robocop and replacement --robocop-ini together")
- options.robocopIni = options.robocop
- del options.robocop
-
- if options.robocopPath:
- if options.robocopApk:
- parser.error(
- "can not use deprecated --robocop-path and replacement --robocop-apk together")
- options.robocopApk = os.path.join(
- options.robocopPath,
- 'robocop.apk')
- del options.robocopPath
-
# Robocop specific options
if options.robocopIni != "":
if not os.path.exists(options.robocopIni):
parser.error(
"Unable to find specified robocop .ini manifest '%s'" %
options.robocopIni)
options.robocopIni = os.path.abspath(options.robocopIni)
+ if not options.robocopApk and build_obj:
+ options.robocopApk = os.path.join(build_obj.topobjdir, 'build', 'mobile',
+ 'robocop', 'robocop-debug.apk')
+
if options.robocopApk != "":
if not os.path.exists(options.robocopApk):
parser.error(
"Unable to find robocop APK '%s'" %
options.robocopApk)
options.robocopApk = os.path.abspath(options.robocopApk)
if options.robocopIds != "":
@@ -1165,17 +1157,17 @@ class MochitestArgumentParser(ArgumentPa
self.app = 'android'
elif conditions.is_b2g(build_obj):
self.app = 'b2g'
if not self.app:
# platform can't be determined and app wasn't specified explicitly,
# so just use generic arguments and hope for the best
self.app = 'generic'
- if self.app not in container_map.keys():
+ if self.app not in container_map:
self.error("Unrecognized app '{}'! Must be one of: {}".format(
self.app, ', '.join(container_map.keys())))
defaults = {}
for container in self.containers:
defaults.update(container.defaults)
group = self.add_argument_group(container.__class__.__name__, container.__doc__)
--- a/testing/mochitest/runtestsremote.py
+++ b/testing/mochitest/runtestsremote.py
@@ -454,24 +454,21 @@ class MochiRemote(Mochitest):
kwargs['runSSLTunnel'] = False
if 'quiet' in kwargs:
kwargs.pop('quiet')
return self._automation.runApp(*args, **kwargs)
-def main(args):
+def run_test_harness(options):
message_logger = MessageLogger(logger=None)
process_args = {'messageLogger': message_logger}
auto = RemoteAutomation(None, "fennec", processArgs=process_args)
- parser = MochitestArgumentParser(app='android')
- options = parser.parse_args(args)
-
dm = options.dm
auto.setDeviceManager(dm)
mochitest = MochiRemote(auto, dm, options)
log = mochitest.log
message_logger.logger = log
mochitest.message_logger = message_logger
@@ -708,10 +705,17 @@ def main(args):
mochitest.printDeviceInfo(printLogcat=True)
message_logger.finish()
return retVal
+def main(args=sys.argv[1:]):
+ parser = MochitestArgumentParser(app='android')
+ options = parser.parse_args(args)
+
+ return run_test_harness(options)
+
+
if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))
+ sys.exit(main())