зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1127376 - PEP8-ify all mochitest .py files (auto-generated), r=ted
This change was generated using the `autopep8` module [1]. To replicate: $ pip install --upgrade autopep8 $ cd gecko $ autopep8 -i -a -a -r testing/mochitest --exclude 'testing/mochitest/pywebsocket/*' [1] https://github.com/hhatto/autopep8 --HG-- extra : rebase_source : fb127187cd488b977981338373d66cc8c735214f
This commit is contained in:
Родитель
068c4dd4fc
Коммит
7086f00c8a
|
@ -1,7 +1,9 @@
|
|||
import math
|
||||
import mozinfo
|
||||
|
||||
|
||||
class Bisect(object):
|
||||
|
||||
"Class for creating, bisecting and summarizing for --bisect-chunk option."
|
||||
|
||||
def __init__(self, harness):
|
||||
|
@ -34,23 +36,28 @@ class Bisect(object):
|
|||
if not options.totalChunks or not options.thisChunk:
|
||||
return tests
|
||||
|
||||
# The logic here is same as chunkifyTests.js, we need this for bisecting tests.
|
||||
# The logic here is same as chunkifyTests.js, we need this for
|
||||
# bisecting tests.
|
||||
if options.chunkByDir:
|
||||
tests_by_dir = {}
|
||||
test_dirs = []
|
||||
for test in tests:
|
||||
directory = test.split("/")
|
||||
directory = directory[0:min(options.chunkByDir, len(directory)-1)]
|
||||
directory = directory[
|
||||
0:min(
|
||||
options.chunkByDir,
|
||||
len(directory) -
|
||||
1)]
|
||||
directory = "/".join(directory)
|
||||
|
||||
if not directory in tests_by_dir:
|
||||
if directory not in tests_by_dir:
|
||||
tests_by_dir[directory] = [test]
|
||||
test_dirs.append(directory)
|
||||
else:
|
||||
tests_by_dir[directory].append(test)
|
||||
|
||||
tests_per_chunk = float(len(test_dirs)) / options.totalChunks
|
||||
start = int(round((options.thisChunk-1) * tests_per_chunk))
|
||||
start = int(round((options.thisChunk - 1) * tests_per_chunk))
|
||||
end = int(round((options.thisChunk) * tests_per_chunk))
|
||||
test_dirs = test_dirs[start:end]
|
||||
return_tests = []
|
||||
|
@ -59,7 +66,7 @@ class Bisect(object):
|
|||
|
||||
else:
|
||||
tests_per_chunk = float(len(tests)) / options.totalChunks
|
||||
start = int(round((options.thisChunk-1) * tests_per_chunk))
|
||||
start = int(round((options.thisChunk - 1) * tests_per_chunk))
|
||||
end = int(round(options.thisChunk * tests_per_chunk))
|
||||
return_tests = tests[start:end]
|
||||
|
||||
|
@ -83,7 +90,8 @@ class Bisect(object):
|
|||
"This method is used to call other methods for setting up variables and getting the list of tests for bisection."
|
||||
if options.bisectChunk == "default":
|
||||
return tests
|
||||
# The second condition in 'if' is required to verify that the failing test is the last one.
|
||||
# The second condition in 'if' is required to verify that the failing
|
||||
# test is the last one.
|
||||
elif 'loop' not in self.contents or not self.contents['tests'][-1].endswith(options.bisectChunk):
|
||||
tests = self.get_tests_for_bisection(options, tests)
|
||||
status = self.setup(tests)
|
||||
|
@ -97,14 +105,16 @@ class Bisect(object):
|
|||
# Check whether sanity check has to be done. Also it is necessary to check whether options.bisectChunk is present
|
||||
# in self.expectedError as we do not want to run if it is "default".
|
||||
if status == -1 and options.bisectChunk in self.expectedError:
|
||||
# In case we have a debug build, we don't want to run a sanity check, will take too much time.
|
||||
# In case we have a debug build, we don't want to run a sanity
|
||||
# check, will take too much time.
|
||||
if mozinfo.info['debug']:
|
||||
return status
|
||||
|
||||
testBleedThrough = self.contents['testsToRun'][0]
|
||||
tests = self.contents['totalTests']
|
||||
tests.remove(testBleedThrough)
|
||||
# To make sure that the failing test is dependent on some other test.
|
||||
# To make sure that the failing test is dependent on some other
|
||||
# test.
|
||||
if options.bisectChunk in testBleedThrough:
|
||||
return status
|
||||
|
||||
|
@ -133,7 +143,7 @@ class Bisect(object):
|
|||
# self.contents['result'] will be expected error only if it fails.
|
||||
elif self.contents['result'] == "FAIL":
|
||||
self.contents['tests'] = self.contents['testsToRun']
|
||||
status = 1 # for initializing
|
||||
status = 1 # for initializing
|
||||
|
||||
# initialize
|
||||
if status:
|
||||
|
@ -189,22 +199,35 @@ class Bisect(object):
|
|||
def summarize_chunk(self, options):
|
||||
"This method is used summarize the results after the list of tests is run."
|
||||
if options.bisectChunk == "default":
|
||||
# if no expectedError that means all the tests have successfully passed.
|
||||
# if no expectedError that means all the tests have successfully
|
||||
# passed.
|
||||
if len(self.expectedError) == 0:
|
||||
return -1
|
||||
options.bisectChunk = self.expectedError.keys()[0]
|
||||
self.summary.append("\tFound Error in test: %s" % options.bisectChunk)
|
||||
self.summary.append(
|
||||
"\tFound Error in test: %s" %
|
||||
options.bisectChunk)
|
||||
return 0
|
||||
|
||||
# If options.bisectChunk is not in self.result then we need to move to the next run.
|
||||
# If options.bisectChunk is not in self.result then we need to move to
|
||||
# the next run.
|
||||
if options.bisectChunk not in self.result:
|
||||
return -1
|
||||
|
||||
self.summary.append("\tPass %d:" % self.contents['loop'])
|
||||
if len(self.contents['testsToRun']) > 1:
|
||||
self.summary.append("\t\t%d test files(start,end,failing). [%s, %s, %s]" % (len(self.contents['testsToRun']), self.contents['testsToRun'][0], self.contents['testsToRun'][-2], self.contents['testsToRun'][-1]))
|
||||
self.summary.append(
|
||||
"\t\t%d test files(start,end,failing). [%s, %s, %s]" % (len(
|
||||
self.contents['testsToRun']),
|
||||
self.contents['testsToRun'][0],
|
||||
self.contents['testsToRun'][
|
||||
-2],
|
||||
self.contents['testsToRun'][
|
||||
-1]))
|
||||
else:
|
||||
self.summary.append("\t\t1 test file [%s]" % self.contents['testsToRun'][0])
|
||||
self.summary.append(
|
||||
"\t\t1 test file [%s]" %
|
||||
self.contents['testsToRun'][0])
|
||||
return self.check_for_intermittent(options)
|
||||
|
||||
if self.result[options.bisectChunk] == "PASS":
|
||||
|
@ -217,23 +240,32 @@ class Bisect(object):
|
|||
|
||||
elif self.result[options.bisectChunk] == "FAIL":
|
||||
if 'expectedError' not in self.contents:
|
||||
self.summary.append("\t\t%s failed." % self.contents['testsToRun'][-1])
|
||||
self.contents['expectedError'] = self.expectedError[options.bisectChunk]
|
||||
self.summary.append("\t\t%s failed." %
|
||||
self.contents['testsToRun'][-1])
|
||||
self.contents['expectedError'] = self.expectedError[
|
||||
options.bisectChunk]
|
||||
status = 0
|
||||
|
||||
elif self.expectedError[options.bisectChunk] == self.contents['expectedError']:
|
||||
self.summary.append("\t\t%s failed with expected error." % self.contents['testsToRun'][-1])
|
||||
self.summary.append(
|
||||
"\t\t%s failed with expected error." % self.contents['testsToRun'][-1])
|
||||
self.contents['result'] = "FAIL"
|
||||
status = 0
|
||||
|
||||
# This code checks for test-bleedthrough. Should work for any algorithm.
|
||||
# This code checks for test-bleedthrough. Should work for any
|
||||
# algorithm.
|
||||
numberOfTests = len(self.contents['testsToRun'])
|
||||
if numberOfTests < 3:
|
||||
# This means that only 2 tests are run. Since the last test is the failing test itself therefore the bleedthrough test is the first test
|
||||
self.summary.append("TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the root cause for many of the above failures" % self.contents['testsToRun'][0])
|
||||
# This means that only 2 tests are run. Since the last test
|
||||
# is the failing test itself therefore the bleedthrough
|
||||
# test is the first test
|
||||
self.summary.append(
|
||||
"TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the root cause for many of the above failures" %
|
||||
self.contents['testsToRun'][0])
|
||||
status = -1
|
||||
else:
|
||||
self.summary.append("\t\t%s failed with different error." % self.contents['testsToRun'][-1])
|
||||
self.summary.append(
|
||||
"\t\t%s failed with different error." % self.contents['testsToRun'][-1])
|
||||
status = -1
|
||||
|
||||
return status
|
||||
|
@ -241,7 +273,9 @@ class Bisect(object):
|
|||
def check_for_intermittent(self, options):
|
||||
"This method is used to check whether a test is an intermittent."
|
||||
if self.result[options.bisectChunk] == "PASS":
|
||||
self.summary.append("\t\tThe test %s passed." % self.contents['testsToRun'][0])
|
||||
self.summary.append(
|
||||
"\t\tThe test %s passed." %
|
||||
self.contents['testsToRun'][0])
|
||||
if self.repeat > 0:
|
||||
# loop is set to 1 to again run the single test.
|
||||
self.contents['loop'] = 1
|
||||
|
@ -256,7 +290,9 @@ class Bisect(object):
|
|||
self.contents['loop'] = 2
|
||||
return 1
|
||||
elif self.result[options.bisectChunk] == "FAIL":
|
||||
self.summary.append("\t\tThe test %s failed." % self.contents['testsToRun'][0])
|
||||
self.summary.append(
|
||||
"\t\tThe test %s failed." %
|
||||
self.contents['testsToRun'][0])
|
||||
self.failcount += 1
|
||||
self.contents['loop'] = 1
|
||||
self.repeat -= 1
|
||||
|
@ -269,7 +305,9 @@ class Bisect(object):
|
|||
return -1
|
||||
return 0
|
||||
else:
|
||||
self.summary.append("TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the root cause for many of the above failures" % self.contents['testsToRun'][0])
|
||||
self.summary.append(
|
||||
"TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the root cause for many of the above failures" %
|
||||
self.contents['testsToRun'][0])
|
||||
return -1
|
||||
|
||||
def print_summary(self):
|
||||
|
|
|
@ -81,6 +81,7 @@ FLAVORS = {
|
|||
|
||||
|
||||
class MochitestRunner(MozbuildObject):
|
||||
|
||||
"""Easily run mochitests.
|
||||
|
||||
This currently contains just the basics for running mochitests. We may want
|
||||
|
@ -91,8 +92,12 @@ class MochitestRunner(MozbuildObject):
|
|||
import mozinfo
|
||||
appname = 'webapprt-stub' + mozinfo.info.get('bin_suffix', '')
|
||||
if sys.platform.startswith('darwin'):
|
||||
appname = os.path.join(self.distdir, self.substs['MOZ_MACBUNDLE_NAME'],
|
||||
'Contents', 'Resources', appname)
|
||||
appname = os.path.join(
|
||||
self.distdir,
|
||||
self.substs['MOZ_MACBUNDLE_NAME'],
|
||||
'Contents',
|
||||
'Resources',
|
||||
appname)
|
||||
else:
|
||||
appname = os.path.join(self.distdir, 'bin', appname)
|
||||
return appname
|
||||
|
@ -106,12 +111,24 @@ class MochitestRunner(MozbuildObject):
|
|||
sys.path.append(build_path)
|
||||
|
||||
self.tests_dir = os.path.join(self.topobjdir, '_tests')
|
||||
self.mochitest_dir = os.path.join(self.tests_dir, 'testing', 'mochitest')
|
||||
self.mochitest_dir = os.path.join(
|
||||
self.tests_dir,
|
||||
'testing',
|
||||
'mochitest')
|
||||
self.bin_dir = os.path.join(self.topobjdir, 'dist', 'bin')
|
||||
|
||||
def run_b2g_test(self, test_paths=None, b2g_home=None, xre_path=None,
|
||||
total_chunks=None, this_chunk=None, no_window=None,
|
||||
repeat=0, run_until_failure=False, chrome=False, **kwargs):
|
||||
def run_b2g_test(
|
||||
self,
|
||||
test_paths=None,
|
||||
b2g_home=None,
|
||||
xre_path=None,
|
||||
total_chunks=None,
|
||||
this_chunk=None,
|
||||
no_window=None,
|
||||
repeat=0,
|
||||
run_until_failure=False,
|
||||
chrome=False,
|
||||
**kwargs):
|
||||
"""Runs a b2g mochitest.
|
||||
|
||||
test_paths is an enumerable of paths to tests. It can be a relative path
|
||||
|
@ -137,7 +154,7 @@ class MochitestRunner(MozbuildObject):
|
|||
path = os.path.join(self.mochitest_dir, 'runtestsb2g.py')
|
||||
with open(path, 'r') as fh:
|
||||
imp.load_module('mochitest', fh, path,
|
||||
('.py', 'r', imp.PY_SOURCE))
|
||||
('.py', 'r', imp.PY_SOURCE))
|
||||
|
||||
import mochitest
|
||||
from mochitest_options import B2GOptions
|
||||
|
@ -147,11 +164,19 @@ class MochitestRunner(MozbuildObject):
|
|||
|
||||
if test_path:
|
||||
if chrome:
|
||||
test_root_file = mozpack.path.join(self.mochitest_dir, 'chrome', test_path)
|
||||
test_root_file = mozpack.path.join(
|
||||
self.mochitest_dir,
|
||||
'chrome',
|
||||
test_path)
|
||||
else:
|
||||
test_root_file = mozpack.path.join(self.mochitest_dir, 'tests', test_path)
|
||||
test_root_file = mozpack.path.join(
|
||||
self.mochitest_dir,
|
||||
'tests',
|
||||
test_path)
|
||||
if not os.path.exists(test_root_file):
|
||||
print('Specified test path does not exist: %s' % test_root_file)
|
||||
print(
|
||||
'Specified test path does not exist: %s' %
|
||||
test_root_file)
|
||||
return 1
|
||||
options.testPath = test_path
|
||||
|
||||
|
@ -163,7 +188,9 @@ class MochitestRunner(MozbuildObject):
|
|||
options.repeat = repeat
|
||||
options.runUntilFailure = run_until_failure
|
||||
|
||||
options.symbolsPath = os.path.join(self.distdir, 'crashreporter-symbols')
|
||||
options.symbolsPath = os.path.join(
|
||||
self.distdir,
|
||||
'crashreporter-symbols')
|
||||
|
||||
options.consoleLevel = 'INFO'
|
||||
if conditions.is_b2g_desktop(self):
|
||||
|
@ -190,15 +217,46 @@ class MochitestRunner(MozbuildObject):
|
|||
options.chrome = chrome
|
||||
return mochitest.run_remote_mochitests(parser, options)
|
||||
|
||||
def run_desktop_test(self, context, suite=None, test_paths=None, debugger=None,
|
||||
debugger_args=None, slowscript=False, screenshot_on_fail = False, shuffle=False, closure_behaviour='auto',
|
||||
rerun_failures=False, no_autorun=False, repeat=0, run_until_failure=False,
|
||||
slow=False, chunk_by_dir=0, total_chunks=None, this_chunk=None, extraPrefs=[],
|
||||
jsdebugger=False, debug_on_failure=False, start_at=None, end_at=None,
|
||||
e10s=False, strict_content_sandbox=False, nested_oop=False, dmd=False, dump_output_directory=None,
|
||||
dump_about_memory_after_test=False, dump_dmd_after_test=False,
|
||||
install_extension=None, quiet=False, environment=[], app_override=None, bisectChunk=None, runByDir=False,
|
||||
useTestMediaDevices=False, timeout=None, **kwargs):
|
||||
def run_desktop_test(
|
||||
self,
|
||||
context,
|
||||
suite=None,
|
||||
test_paths=None,
|
||||
debugger=None,
|
||||
debugger_args=None,
|
||||
slowscript=False,
|
||||
screenshot_on_fail=False,
|
||||
shuffle=False,
|
||||
closure_behaviour='auto',
|
||||
rerun_failures=False,
|
||||
no_autorun=False,
|
||||
repeat=0,
|
||||
run_until_failure=False,
|
||||
slow=False,
|
||||
chunk_by_dir=0,
|
||||
total_chunks=None,
|
||||
this_chunk=None,
|
||||
extraPrefs=[],
|
||||
jsdebugger=False,
|
||||
debug_on_failure=False,
|
||||
start_at=None,
|
||||
end_at=None,
|
||||
e10s=False,
|
||||
strict_content_sandbox=False,
|
||||
nested_oop=False,
|
||||
dmd=False,
|
||||
dump_output_directory=None,
|
||||
dump_about_memory_after_test=False,
|
||||
dump_dmd_after_test=False,
|
||||
install_extension=None,
|
||||
quiet=False,
|
||||
environment=[],
|
||||
app_override=None,
|
||||
bisectChunk=None,
|
||||
runByDir=False,
|
||||
useTestMediaDevices=False,
|
||||
timeout=None,
|
||||
**kwargs):
|
||||
"""Runs a mochitest.
|
||||
|
||||
test_paths are path to tests. They can be a relative path from the
|
||||
|
@ -227,9 +285,12 @@ class MochitestRunner(MozbuildObject):
|
|||
|
||||
# Make absolute paths relative before calling os.chdir() below.
|
||||
if test_paths:
|
||||
test_paths = [self._wrap_path_argument(p).relpath() if os.path.isabs(p) else p for p in test_paths]
|
||||
test_paths = [self._wrap_path_argument(
|
||||
p).relpath() if os.path.isabs(p) else p for p in test_paths]
|
||||
|
||||
failure_file_path = os.path.join(self.statedir, 'mochitest_failures.json')
|
||||
failure_file_path = os.path.join(
|
||||
self.statedir,
|
||||
'mochitest_failures.json')
|
||||
|
||||
if rerun_failures and not os.path.exists(failure_file_path):
|
||||
print('No failure file present. Did you run mochitests before?')
|
||||
|
@ -241,7 +302,7 @@ class MochitestRunner(MozbuildObject):
|
|||
path = os.path.join(self.mochitest_dir, 'runtests.py')
|
||||
with open(path, 'r') as fh:
|
||||
imp.load_module('mochitest', fh, path,
|
||||
('.py', 'r', imp.PY_SOURCE))
|
||||
('.py', 'r', imp.PY_SOURCE))
|
||||
|
||||
import mochitest
|
||||
from manifestparser import TestManifest
|
||||
|
@ -253,7 +314,7 @@ class MochitestRunner(MozbuildObject):
|
|||
# Automation installs its own stream handler to stdout. Since we want
|
||||
# all logging to go through us, we just remove their handler.
|
||||
remove_handlers = [l for l in logging.getLogger().handlers
|
||||
if isinstance(l, logging.StreamHandler)]
|
||||
if isinstance(l, logging.StreamHandler)]
|
||||
for handler in remove_handlers:
|
||||
logging.getLogger().removeHandler(handler)
|
||||
|
||||
|
@ -308,7 +369,9 @@ class MochitestRunner(MozbuildObject):
|
|||
options.runSlower = slow
|
||||
options.testingModulesDir = os.path.join(self.tests_dir, 'modules')
|
||||
options.extraProfileFiles.append(os.path.join(self.distdir, 'plugins'))
|
||||
options.symbolsPath = os.path.join(self.distdir, 'crashreporter-symbols')
|
||||
options.symbolsPath = os.path.join(
|
||||
self.distdir,
|
||||
'crashreporter-symbols')
|
||||
options.chunkByDir = chunk_by_dir
|
||||
options.totalChunks = total_chunks
|
||||
options.thisChunk = this_chunk
|
||||
|
@ -329,11 +392,14 @@ class MochitestRunner(MozbuildObject):
|
|||
options.runByDir = runByDir
|
||||
options.useTestMediaDevices = useTestMediaDevices
|
||||
if timeout:
|
||||
options.timeout = int(timeout)
|
||||
options.timeout = int(timeout)
|
||||
|
||||
options.failureFile = failure_file_path
|
||||
if install_extension != None:
|
||||
options.extensionsToInstall = [os.path.join(self.topsrcdir,install_extension)]
|
||||
if install_extension is not None:
|
||||
options.extensionsToInstall = [
|
||||
os.path.join(
|
||||
self.topsrcdir,
|
||||
install_extension)]
|
||||
|
||||
for k, v in kwargs.iteritems():
|
||||
setattr(options, k, v)
|
||||
|
@ -341,18 +407,22 @@ class MochitestRunner(MozbuildObject):
|
|||
if test_paths:
|
||||
resolver = self._spawn(TestResolver)
|
||||
|
||||
tests = list(resolver.resolve_tests(paths=test_paths, flavor=flavor))
|
||||
tests = list(
|
||||
resolver.resolve_tests(
|
||||
paths=test_paths,
|
||||
flavor=flavor))
|
||||
|
||||
if not tests:
|
||||
print('No tests could be found in the path specified. Please '
|
||||
'specify a path that is a test file or is a directory '
|
||||
'containing tests.')
|
||||
'specify a path that is a test file or is a directory '
|
||||
'containing tests.')
|
||||
return 1
|
||||
|
||||
manifest = TestManifest()
|
||||
manifest.tests.extend(tests)
|
||||
|
||||
if len(tests) == 1 and closure_behaviour == 'auto' and suite == 'plain':
|
||||
if len(
|
||||
tests) == 1 and closure_behaviour == 'auto' and suite == 'plain':
|
||||
options.closeWhenDone = False
|
||||
|
||||
options.manifestFile = manifest
|
||||
|
@ -364,7 +434,7 @@ class MochitestRunner(MozbuildObject):
|
|||
options.debugger = debugger
|
||||
|
||||
if debugger_args:
|
||||
if options.debugger == None:
|
||||
if options.debugger is None:
|
||||
print("--debugger-args passed, but no debugger specified.")
|
||||
return 1
|
||||
options.debuggerArgs = debugger_args
|
||||
|
@ -375,14 +445,22 @@ class MochitestRunner(MozbuildObject):
|
|||
elif app_override:
|
||||
options.app = app_override
|
||||
if options.gmp_path is None:
|
||||
# Need to fix the location of gmp_fake which might not be shipped in the binary
|
||||
# Need to fix the location of gmp_fake which might not be
|
||||
# shipped in the binary
|
||||
bin_path = self.get_binary_path()
|
||||
options.gmp_path = os.path.join(os.path.dirname(bin_path), 'gmp-fake', '1.0')
|
||||
options.gmp_path = os.path.join(
|
||||
os.path.dirname(bin_path),
|
||||
'gmp-fake',
|
||||
'1.0')
|
||||
options.gmp_path += os.pathsep
|
||||
options.gmp_path += os.path.join(os.path.dirname(bin_path), 'gmp-clearkey', '0.1')
|
||||
options.gmp_path += os.path.join(
|
||||
os.path.dirname(bin_path),
|
||||
'gmp-clearkey',
|
||||
'0.1')
|
||||
|
||||
|
||||
logger_options = {key: value for key, value in vars(options).iteritems() if key.startswith('log')}
|
||||
logger_options = {
|
||||
key: value for key,
|
||||
value in vars(options).iteritems() if key.startswith('log')}
|
||||
runner = mochitest.Mochitest(logger_options)
|
||||
options = opts.verifyOptions(options, runner)
|
||||
|
||||
|
@ -414,12 +492,17 @@ def MochitestCommand(func):
|
|||
# (modified) function. Here, we chain decorators onto the passed in
|
||||
# function.
|
||||
|
||||
debugger = CommandArgument('--debugger', '-d', metavar='DEBUGGER',
|
||||
debugger = CommandArgument(
|
||||
'--debugger',
|
||||
'-d',
|
||||
metavar='DEBUGGER',
|
||||
help='Debugger binary to run test in. Program name or path.')
|
||||
func = debugger(func)
|
||||
|
||||
debugger_args = CommandArgument('--debugger-args',
|
||||
metavar='DEBUGGER_ARGS', help='Arguments to pass to the debugger.')
|
||||
debugger_args = CommandArgument(
|
||||
'--debugger-args',
|
||||
metavar='DEBUGGER_ARGS',
|
||||
help='Arguments to pass to the debugger.')
|
||||
func = debugger_args(func)
|
||||
|
||||
# Bug 933807 introduced JS_DISABLE_SLOW_SCRIPT_SIGNALS to avoid clever
|
||||
|
@ -427,219 +510,300 @@ def MochitestCommand(func):
|
|||
# code. If we don't pass this, the user will need to periodically type
|
||||
# "continue" to (safely) resume execution. There are ways to implement
|
||||
# automatic resuming; see the bug.
|
||||
slowscript = CommandArgument('--slowscript', action='store_true',
|
||||
slowscript = CommandArgument(
|
||||
'--slowscript',
|
||||
action='store_true',
|
||||
help='Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; when not set, recoverable but misleading SIGSEGV instances may occur in Ion/Odin JIT code')
|
||||
func = slowscript(func)
|
||||
|
||||
screenshot_on_fail = CommandArgument('--screenshot-on-fail', action='store_true',
|
||||
screenshot_on_fail = CommandArgument(
|
||||
'--screenshot-on-fail',
|
||||
action='store_true',
|
||||
help='Take screenshots on all test failures. Set $MOZ_UPLOAD_DIR to a directory for storing the screenshots.')
|
||||
func = screenshot_on_fail(func)
|
||||
|
||||
shuffle = CommandArgument('--shuffle', action='store_true',
|
||||
help='Shuffle execution order.')
|
||||
help='Shuffle execution order.')
|
||||
func = shuffle(func)
|
||||
|
||||
keep_open = CommandArgument('--keep-open', action='store_const',
|
||||
dest='closure_behaviour', const='open', default='auto',
|
||||
keep_open = CommandArgument(
|
||||
'--keep-open',
|
||||
action='store_const',
|
||||
dest='closure_behaviour',
|
||||
const='open',
|
||||
default='auto',
|
||||
help='Always keep the browser open after tests complete.')
|
||||
func = keep_open(func)
|
||||
|
||||
autoclose = CommandArgument('--auto-close', action='store_const',
|
||||
dest='closure_behaviour', const='close', default='auto',
|
||||
autoclose = CommandArgument(
|
||||
'--auto-close',
|
||||
action='store_const',
|
||||
dest='closure_behaviour',
|
||||
const='close',
|
||||
default='auto',
|
||||
help='Always close the browser after tests complete.')
|
||||
func = autoclose(func)
|
||||
|
||||
rerun = CommandArgument('--rerun-failures', action='store_true',
|
||||
rerun = CommandArgument(
|
||||
'--rerun-failures',
|
||||
action='store_true',
|
||||
help='Run only the tests that failed during the last test run.')
|
||||
func = rerun(func)
|
||||
|
||||
autorun = CommandArgument('--no-autorun', action='store_true',
|
||||
autorun = CommandArgument(
|
||||
'--no-autorun',
|
||||
action='store_true',
|
||||
help='Do not starting running tests automatically.')
|
||||
func = autorun(func)
|
||||
|
||||
repeat = CommandArgument('--repeat', type=int, default=0,
|
||||
help='Repeat the test the given number of times.')
|
||||
help='Repeat the test the given number of times.')
|
||||
func = repeat(func)
|
||||
|
||||
runUntilFailure = CommandArgument("--run-until-failure", action='store_true',
|
||||
help='Run tests repeatedly and stops on the first time a test fails. ' \
|
||||
'Default cap is 30 runs, which can be overwritten ' \
|
||||
'with the --repeat parameter.')
|
||||
runUntilFailure = CommandArgument(
|
||||
"--run-until-failure",
|
||||
action='store_true',
|
||||
help='Run tests repeatedly and stops on the first time a test fails. '
|
||||
'Default cap is 30 runs, which can be overwritten '
|
||||
'with the --repeat parameter.')
|
||||
func = runUntilFailure(func)
|
||||
|
||||
slow = CommandArgument('--slow', action='store_true',
|
||||
help='Delay execution between tests.')
|
||||
help='Delay execution between tests.')
|
||||
func = slow(func)
|
||||
|
||||
end_at = CommandArgument('--end-at', type=str,
|
||||
end_at = CommandArgument(
|
||||
'--end-at',
|
||||
type=str,
|
||||
help='Stop running the test sequence at this test.')
|
||||
func = end_at(func)
|
||||
|
||||
start_at = CommandArgument('--start-at', type=str,
|
||||
start_at = CommandArgument(
|
||||
'--start-at',
|
||||
type=str,
|
||||
help='Start running the test sequence at this test.')
|
||||
func = start_at(func)
|
||||
|
||||
chunk_dir = CommandArgument('--chunk-by-dir', type=int,
|
||||
chunk_dir = CommandArgument(
|
||||
'--chunk-by-dir',
|
||||
type=int,
|
||||
help='Group tests together in chunks by this many top directories.')
|
||||
func = chunk_dir(func)
|
||||
|
||||
chunk_total = CommandArgument('--total-chunks', type=int,
|
||||
chunk_total = CommandArgument(
|
||||
'--total-chunks',
|
||||
type=int,
|
||||
help='Total number of chunks to split tests into.')
|
||||
func = chunk_total(func)
|
||||
|
||||
this_chunk = CommandArgument('--this-chunk', type=int,
|
||||
this_chunk = CommandArgument(
|
||||
'--this-chunk',
|
||||
type=int,
|
||||
help='If running tests by chunks, the number of the chunk to run.')
|
||||
func = this_chunk(func)
|
||||
|
||||
debug_on_failure = CommandArgument('--debug-on-failure', action='store_true',
|
||||
help='Breaks execution and enters the JS debugger on a test failure. ' \
|
||||
'Should be used together with --jsdebugger.')
|
||||
debug_on_failure = CommandArgument(
|
||||
'--debug-on-failure',
|
||||
action='store_true',
|
||||
help='Breaks execution and enters the JS debugger on a test failure. '
|
||||
'Should be used together with --jsdebugger.')
|
||||
func = debug_on_failure(func)
|
||||
|
||||
setpref = CommandArgument('--setpref', default=[], action='append',
|
||||
metavar='PREF=VALUE', dest='extraPrefs',
|
||||
help='defines an extra user preference')
|
||||
metavar='PREF=VALUE', dest='extraPrefs',
|
||||
help='defines an extra user preference')
|
||||
func = setpref(func)
|
||||
|
||||
jsdebugger = CommandArgument('--jsdebugger', action='store_true',
|
||||
jsdebugger = CommandArgument(
|
||||
'--jsdebugger',
|
||||
action='store_true',
|
||||
help='Start the browser JS debugger before running the test. Implies --no-autorun.')
|
||||
func = jsdebugger(func)
|
||||
|
||||
e10s = CommandArgument('--e10s', action='store_true',
|
||||
e10s = CommandArgument(
|
||||
'--e10s',
|
||||
action='store_true',
|
||||
help='Run tests with electrolysis preferences and test filtering enabled.')
|
||||
func = e10s(func)
|
||||
|
||||
strict_content_sandbox = CommandArgument('--strict-content-sandbox', action='store_true',
|
||||
strict_content_sandbox = CommandArgument(
|
||||
'--strict-content-sandbox',
|
||||
action='store_true',
|
||||
help='Run tests with a more strict content sandbox (Windows only).')
|
||||
func = strict_content_sandbox(func)
|
||||
|
||||
this_chunk = CommandArgument('--nested_oop', action='store_true',
|
||||
this_chunk = CommandArgument(
|
||||
'--nested_oop',
|
||||
action='store_true',
|
||||
help='Run tests with nested oop preferences and test filtering enabled.')
|
||||
func = this_chunk(func)
|
||||
|
||||
dmd = CommandArgument('--dmd', action='store_true',
|
||||
help='Run tests with DMD active.')
|
||||
help='Run tests with DMD active.')
|
||||
func = dmd(func)
|
||||
|
||||
dumpAboutMemory = CommandArgument('--dump-about-memory-after-test', action='store_true',
|
||||
dumpAboutMemory = CommandArgument(
|
||||
'--dump-about-memory-after-test',
|
||||
action='store_true',
|
||||
help='Dump an about:memory log after every test.')
|
||||
func = dumpAboutMemory(func)
|
||||
|
||||
dumpDMD = CommandArgument('--dump-dmd-after-test', action='store_true',
|
||||
help='Dump a DMD log after every test.')
|
||||
help='Dump a DMD log after every test.')
|
||||
func = dumpDMD(func)
|
||||
|
||||
dumpOutputDirectory = CommandArgument('--dump-output-directory', action='store',
|
||||
dumpOutputDirectory = CommandArgument(
|
||||
'--dump-output-directory',
|
||||
action='store',
|
||||
help='Specifies the directory in which to place dumped memory reports.')
|
||||
func = dumpOutputDirectory(func)
|
||||
|
||||
path = CommandArgument('test_paths', default=None, nargs='*',
|
||||
path = 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.')
|
||||
help='Test to run. Can be specified as a single file, a '
|
||||
'directory, or omitted. If omitted, the entire test suite is '
|
||||
'executed.')
|
||||
func = path(func)
|
||||
|
||||
install_extension = CommandArgument('--install-extension',
|
||||
help='Install given extension before running selected tests. ' \
|
||||
'Parameter is a path to xpi file.')
|
||||
install_extension = CommandArgument(
|
||||
'--install-extension',
|
||||
help='Install given extension before running selected tests. '
|
||||
'Parameter is a path to xpi file.')
|
||||
func = install_extension(func)
|
||||
|
||||
quiet = CommandArgument('--quiet', default=False, action='store_true',
|
||||
quiet = CommandArgument(
|
||||
'--quiet',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Do not print test log lines unless a failure occurs.')
|
||||
func = quiet(func)
|
||||
|
||||
setenv = CommandArgument('--setenv', default=[], action='append',
|
||||
metavar='NAME=VALUE', dest='environment',
|
||||
help="Sets the given variable in the application's environment")
|
||||
setenv = CommandArgument(
|
||||
'--setenv',
|
||||
default=[],
|
||||
action='append',
|
||||
metavar='NAME=VALUE',
|
||||
dest='environment',
|
||||
help="Sets the given variable in the application's environment")
|
||||
func = setenv(func)
|
||||
|
||||
runbydir = CommandArgument('--run-by-dir', default=False,
|
||||
action='store_true',
|
||||
dest='runByDir',
|
||||
runbydir = CommandArgument(
|
||||
'--run-by-dir',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='runByDir',
|
||||
help='Run each directory in a single browser instance with a fresh profile.')
|
||||
func = runbydir(func)
|
||||
|
||||
bisect_chunk = CommandArgument('--bisect-chunk', type=str,
|
||||
dest='bisectChunk',
|
||||
bisect_chunk = CommandArgument(
|
||||
'--bisect-chunk',
|
||||
type=str,
|
||||
dest='bisectChunk',
|
||||
help='Specify the failing test name to find the previous tests that may be causing the failure.')
|
||||
func = bisect_chunk(func)
|
||||
|
||||
test_media = CommandArgument('--use-test-media-devices', default=False,
|
||||
action='store_true',
|
||||
dest='useTestMediaDevices',
|
||||
test_media = CommandArgument(
|
||||
'--use-test-media-devices',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='useTestMediaDevices',
|
||||
help='Use test media device drivers for media testing.')
|
||||
func = test_media(func)
|
||||
|
||||
app_override = CommandArgument('--app-override', default=None, action='store',
|
||||
help="Override the default binary used to run tests with the path you provide, e.g. " \
|
||||
" --app-override /usr/bin/firefox . " \
|
||||
"If you have run ./mach package beforehand, you can specify 'dist' to " \
|
||||
"run tests against the distribution bundle's binary.");
|
||||
app_override = CommandArgument(
|
||||
'--app-override',
|
||||
default=None,
|
||||
action='store',
|
||||
help="Override the default binary used to run tests with the path you provide, e.g. "
|
||||
" --app-override /usr/bin/firefox . "
|
||||
"If you have run ./mach package beforehand, you can specify 'dist' to "
|
||||
"run tests against the distribution bundle's binary.")
|
||||
func = app_override(func)
|
||||
|
||||
timeout = CommandArgument('--timeout', default=None,
|
||||
help='The per-test timeout time in seconds (default: 60 seconds)');
|
||||
timeout = CommandArgument(
|
||||
'--timeout',
|
||||
default=None,
|
||||
help='The per-test timeout time in seconds (default: 60 seconds)')
|
||||
func = timeout(func)
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def B2GCommand(func):
|
||||
"""Decorator that adds shared command arguments to b2g mochitest commands."""
|
||||
|
||||
busybox = CommandArgument('--busybox', default=None,
|
||||
busybox = CommandArgument(
|
||||
'--busybox',
|
||||
default=None,
|
||||
help='Path to busybox binary to install on device')
|
||||
func = busybox(func)
|
||||
|
||||
logdir = CommandArgument('--logdir', default=None,
|
||||
help='directory to store log files')
|
||||
help='directory to store log files')
|
||||
func = logdir(func)
|
||||
|
||||
profile = CommandArgument('--profile', default=None,
|
||||
help='for desktop testing, the path to the \
|
||||
help='for desktop testing, the path to the \
|
||||
gaia profile to use')
|
||||
func = profile(func)
|
||||
|
||||
geckopath = CommandArgument('--gecko-path', default=None,
|
||||
help='the path to a gecko distribution that should \
|
||||
help='the path to a gecko distribution that should \
|
||||
be installed on the emulator prior to test')
|
||||
func = geckopath(func)
|
||||
|
||||
nowindow = CommandArgument('--no-window', action='store_true', default=False,
|
||||
nowindow = CommandArgument(
|
||||
'--no-window',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Pass --no-window to the emulator')
|
||||
func = nowindow(func)
|
||||
|
||||
sdcard = CommandArgument('--sdcard', default="10MB",
|
||||
help='Define size of sdcard: 1MB, 50MB...etc')
|
||||
help='Define size of sdcard: 1MB, 50MB...etc')
|
||||
func = sdcard(func)
|
||||
|
||||
marionette = CommandArgument('--marionette', default=None,
|
||||
marionette = CommandArgument(
|
||||
'--marionette',
|
||||
default=None,
|
||||
help='host:port to use when connecting to Marionette')
|
||||
func = marionette(func)
|
||||
|
||||
chunk_total = CommandArgument('--total-chunks', type=int,
|
||||
chunk_total = CommandArgument(
|
||||
'--total-chunks',
|
||||
type=int,
|
||||
help='Total number of chunks to split tests into.')
|
||||
func = chunk_total(func)
|
||||
|
||||
this_chunk = CommandArgument('--this-chunk', type=int,
|
||||
this_chunk = CommandArgument(
|
||||
'--this-chunk',
|
||||
type=int,
|
||||
help='If running tests by chunks, the number of the chunk to run.')
|
||||
func = this_chunk(func)
|
||||
|
||||
path = CommandArgument('test_paths', default=None, nargs='*',
|
||||
path = 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.')
|
||||
help='Test to run. Can be specified as a single file, a '
|
||||
'directory, or omitted. If omitted, the entire test suite is '
|
||||
'executed.')
|
||||
func = path(func)
|
||||
|
||||
repeat = CommandArgument('--repeat', type=int, default=0,
|
||||
help='Repeat the test the given number of times.')
|
||||
help='Repeat the test the given number of times.')
|
||||
func = repeat(func)
|
||||
|
||||
runUntilFailure = CommandArgument("--run-until-failure", action='store_true',
|
||||
help='Run tests repeatedly and stops on the first time a test fails. ' \
|
||||
'Default cap is 30 runs, which can be overwritten ' \
|
||||
'with the --repeat parameter.')
|
||||
runUntilFailure = CommandArgument(
|
||||
"--run-until-failure",
|
||||
action='store_true',
|
||||
help='Run tests repeatedly and stops on the first time a test fails. '
|
||||
'Default cap is 30 runs, which can be overwritten '
|
||||
'with the --repeat parameter.')
|
||||
func = runUntilFailure(func)
|
||||
|
||||
return func
|
||||
|
@ -648,34 +812,48 @@ def B2GCommand(func):
|
|||
_st_parser = argparse.ArgumentParser()
|
||||
structured.commandline.add_logging_group(_st_parser)
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class MachCommands(MachCommandBase):
|
||||
@Command('mochitest-plain', category='testing',
|
||||
conditions=[conditions.is_firefox_or_mulet],
|
||||
|
||||
@Command(
|
||||
'mochitest-plain',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox_or_mulet],
|
||||
description='Run a plain mochitest (integration test, plain web page).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
def run_mochitest_plain(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'plain', **kwargs)
|
||||
|
||||
@Command('mochitest-chrome', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
@Command(
|
||||
'mochitest-chrome',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox],
|
||||
description='Run a chrome mochitest (integration test with some XUL).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
def run_mochitest_chrome(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'chrome', **kwargs)
|
||||
|
||||
@Command('mochitest-browser', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
@Command(
|
||||
'mochitest-browser',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox],
|
||||
description='Run a mochitest with browser chrome (integration test with a standard browser).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
def run_mochitest_browser(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'browser', **kwargs)
|
||||
|
||||
@Command('mochitest-devtools', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
@Command(
|
||||
'mochitest-devtools',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox],
|
||||
description='Run a devtools mochitest with browser chrome (integration test with a standard browser with the devtools frame).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
|
@ -683,21 +861,24 @@ class MachCommands(MachCommandBase):
|
|||
return self.run_mochitest(test_paths, 'devtools', **kwargs)
|
||||
|
||||
@Command('jetpack-package', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run a jetpack package test.')
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run a jetpack package test.')
|
||||
@MochitestCommand
|
||||
def run_mochitest_jetpack_package(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'jetpack-package', **kwargs)
|
||||
|
||||
@Command('jetpack-addon', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run a jetpack addon test.')
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run a jetpack addon test.')
|
||||
@MochitestCommand
|
||||
def run_mochitest_jetpack_addon(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'jetpack-addon', **kwargs)
|
||||
|
||||
@Command('mochitest-metro', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
@Command(
|
||||
'mochitest-metro',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox],
|
||||
description='Run a mochitest with metro browser chrome (tests for Windows touch interface).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
|
@ -705,23 +886,29 @@ class MachCommands(MachCommandBase):
|
|||
return self.run_mochitest(test_paths, 'metro', **kwargs)
|
||||
|
||||
@Command('mochitest-a11y', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run an a11y mochitest (accessibility tests).',
|
||||
parser=_st_parser)
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run an a11y mochitest (accessibility tests).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
def run_mochitest_a11y(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'a11y', **kwargs)
|
||||
|
||||
@Command('webapprt-test-chrome', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
@Command(
|
||||
'webapprt-test-chrome',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox],
|
||||
description='Run a webapprt chrome mochitest (Web App Runtime with the browser chrome).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
def run_mochitest_webapprt_chrome(self, test_paths, **kwargs):
|
||||
return self.run_mochitest(test_paths, 'webapprt-chrome', **kwargs)
|
||||
|
||||
@Command('webapprt-test-content', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
@Command(
|
||||
'webapprt-test-content',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_firefox],
|
||||
description='Run a webapprt content mochitest (Content rendering of the Web App Runtime).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
|
@ -729,14 +916,14 @@ class MachCommands(MachCommandBase):
|
|||
return self.run_mochitest(test_paths, 'webapprt-content', **kwargs)
|
||||
|
||||
@Command('mochitest', category='testing',
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run any flavor of mochitest (integration test).',
|
||||
parser=_st_parser)
|
||||
conditions=[conditions.is_firefox],
|
||||
description='Run any flavor of mochitest (integration test).',
|
||||
parser=_st_parser)
|
||||
@MochitestCommand
|
||||
@CommandArgument('-f', '--flavor', choices=FLAVORS.keys(),
|
||||
help='Only run tests of this flavor.')
|
||||
help='Only run tests of this flavor.')
|
||||
def run_mochitest_general(self, test_paths, flavor=None, test_objects=None,
|
||||
**kwargs):
|
||||
**kwargs):
|
||||
self._preruntest()
|
||||
|
||||
from mozbuild.testing import TestResolver
|
||||
|
@ -746,7 +933,7 @@ class MachCommands(MachCommandBase):
|
|||
else:
|
||||
resolver = self._spawn(TestResolver)
|
||||
tests = list(resolver.resolve_tests(paths=test_paths,
|
||||
cwd=self._mach_context.cwd))
|
||||
cwd=self._mach_context.cwd))
|
||||
|
||||
# Our current approach is to group the tests by suite and then perform
|
||||
# an invocation for each suite. Ideally, this would be done
|
||||
|
@ -773,8 +960,11 @@ class MachCommands(MachCommandBase):
|
|||
mochitest = self._spawn(MochitestRunner)
|
||||
overall = None
|
||||
for suite, tests in sorted(suites.items()):
|
||||
result = mochitest.run_desktop_test(self._mach_context,
|
||||
test_paths=[test['file_relpath'] for test in tests], suite=suite,
|
||||
result = mochitest.run_desktop_test(
|
||||
self._mach_context,
|
||||
test_paths=[
|
||||
test['file_relpath'] for test in tests],
|
||||
suite=suite,
|
||||
**kwargs)
|
||||
if result:
|
||||
overall = result
|
||||
|
@ -794,8 +984,11 @@ class MachCommands(MachCommandBase):
|
|||
|
||||
mochitest = self._spawn(MochitestRunner)
|
||||
|
||||
return mochitest.run_desktop_test(self._mach_context,
|
||||
test_paths=test_paths, suite=flavor, **kwargs)
|
||||
return mochitest.run_desktop_test(
|
||||
self._mach_context,
|
||||
test_paths=test_paths,
|
||||
suite=flavor,
|
||||
**kwargs)
|
||||
|
||||
|
||||
# TODO For now b2g commands will only work with the emulator,
|
||||
|
@ -810,27 +1003,39 @@ def is_emulator(cls):
|
|||
|
||||
@CommandProvider
|
||||
class B2GCommands(MachCommandBase):
|
||||
|
||||
"""So far these are only mochitest plain. They are
|
||||
implemented separately because their command lines
|
||||
are completely different.
|
||||
"""
|
||||
|
||||
def __init__(self, context):
|
||||
MachCommandBase.__init__(self, context)
|
||||
|
||||
for attr in ('b2g_home', 'xre_path', 'device_name', 'get_build_var'):
|
||||
setattr(self, attr, getattr(context, attr, None))
|
||||
|
||||
@Command('mochitest-remote', category='testing',
|
||||
@Command(
|
||||
'mochitest-remote',
|
||||
category='testing',
|
||||
description='Run a remote mochitest (integration test for fennec/android).',
|
||||
conditions=[conditions.is_b2g, is_emulator])
|
||||
conditions=[
|
||||
conditions.is_b2g,
|
||||
is_emulator])
|
||||
@B2GCommand
|
||||
def run_mochitest_remote(self, test_paths, **kwargs):
|
||||
if self.get_build_var:
|
||||
host_webapps_dir = os.path.join(self.get_build_var('TARGET_OUT_DATA'),
|
||||
'local', 'webapps')
|
||||
if not os.path.isdir(os.path.join(host_webapps_dir,
|
||||
'test-container.gaiamobile.org')):
|
||||
print(ENG_BUILD_REQUIRED % ('mochitest-remote', host_webapps_dir))
|
||||
host_webapps_dir = os.path.join(
|
||||
self.get_build_var('TARGET_OUT_DATA'),
|
||||
'local',
|
||||
'webapps')
|
||||
if not os.path.isdir(
|
||||
os.path.join(
|
||||
host_webapps_dir,
|
||||
'test-container.gaiamobile.org')):
|
||||
print(
|
||||
ENG_BUILD_REQUIRED %
|
||||
('mochitest-remote', host_webapps_dir))
|
||||
return 1
|
||||
|
||||
from mozbuild.controller.building import BuildDriver
|
||||
|
@ -847,22 +1052,29 @@ class B2GCommands(MachCommandBase):
|
|||
driver.install_tests(remove=False)
|
||||
|
||||
mochitest = self._spawn(MochitestRunner)
|
||||
return mochitest.run_b2g_test(b2g_home=self.b2g_home,
|
||||
xre_path=self.xre_path, test_paths=test_paths, **kwargs)
|
||||
return mochitest.run_b2g_test(
|
||||
b2g_home=self.b2g_home,
|
||||
xre_path=self.xre_path,
|
||||
test_paths=test_paths,
|
||||
**kwargs)
|
||||
|
||||
@Command('mochitest-chrome-remote', category='testing',
|
||||
description='Run a remote mochitest-chrome.',
|
||||
conditions=[conditions.is_b2g, is_emulator])
|
||||
description='Run a remote mochitest-chrome.',
|
||||
conditions=[conditions.is_b2g, is_emulator])
|
||||
@B2GCommand
|
||||
def run_mochitest_chrome_remote(self, test_paths, **kwargs):
|
||||
return self.run_mochitest_remote(test_paths, chrome=True, **kwargs)
|
||||
|
||||
@Command('mochitest-b2g-desktop', category='testing',
|
||||
conditions=[conditions.is_b2g_desktop],
|
||||
@Command(
|
||||
'mochitest-b2g-desktop',
|
||||
category='testing',
|
||||
conditions=[
|
||||
conditions.is_b2g_desktop],
|
||||
description='Run a b2g desktop mochitest (same as mochitest-plain but for b2g desktop).')
|
||||
@B2GCommand
|
||||
def run_mochitest_b2g_desktop(self, test_paths, **kwargs):
|
||||
kwargs['profile'] = kwargs.get('profile') or os.environ.get('GAIA_PROFILE')
|
||||
kwargs['profile'] = kwargs.get(
|
||||
'profile') or os.environ.get('GAIA_PROFILE')
|
||||
if not kwargs['profile'] or not os.path.isdir(kwargs['profile']):
|
||||
print(GAIA_PROFILE_NOT_FOUND % 'mochitest-b2g-desktop')
|
||||
return 1
|
||||
|
@ -886,31 +1098,52 @@ class B2GCommands(MachCommandBase):
|
|||
|
||||
@CommandProvider
|
||||
class AndroidCommands(MachCommandBase):
|
||||
|
||||
@Command('robocop', category='testing',
|
||||
conditions=[conditions.is_android],
|
||||
description='Run a Robocop test.')
|
||||
@CommandArgument('test_path', default=None, nargs='?',
|
||||
conditions=[conditions.is_android],
|
||||
description='Run a Robocop test.')
|
||||
@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.')
|
||||
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):
|
||||
self.tests_dir = os.path.join(self.topobjdir, '_tests')
|
||||
self.mochitest_dir = os.path.join(self.tests_dir, 'testing', 'mochitest')
|
||||
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))
|
||||
('.py', 'r', imp.PY_SOURCE))
|
||||
import runtestsremote
|
||||
|
||||
args = [
|
||||
'--xre-path=' + os.environ.get('MOZ_HOST_BIN'),
|
||||
'--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'),
|
||||
'--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=-',
|
||||
]
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -23,14 +23,15 @@ from mozprofile import Profile, Preferences
|
|||
from mozlog import structured
|
||||
import mozinfo
|
||||
|
||||
|
||||
class B2GMochitest(MochitestUtilsMixin):
|
||||
marionette = None
|
||||
|
||||
def __init__(self, marionette_args,
|
||||
logger_options,
|
||||
out_of_process=True,
|
||||
profile_data_dir=None,
|
||||
locations=os.path.join(here, 'server-locations.txt')):
|
||||
logger_options,
|
||||
out_of_process=True,
|
||||
profile_data_dir=None,
|
||||
locations=os.path.join(here, 'server-locations.txt')):
|
||||
super(B2GMochitest, self).__init__(logger_options)
|
||||
self.marionette_args = marionette_args
|
||||
self.out_of_process = out_of_process
|
||||
|
@ -43,10 +44,14 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
self.remote_chrome_test_dir = None
|
||||
|
||||
if profile_data_dir:
|
||||
self.preferences = [os.path.join(profile_data_dir, f)
|
||||
for f in os.listdir(profile_data_dir) if f.startswith('pref')]
|
||||
self.webapps = [os.path.join(profile_data_dir, f)
|
||||
for f in os.listdir(profile_data_dir) if f.startswith('webapp')]
|
||||
self.preferences = [
|
||||
os.path.join(
|
||||
profile_data_dir,
|
||||
f) for f in os.listdir(profile_data_dir) if f.startswith('pref')]
|
||||
self.webapps = [
|
||||
os.path.join(
|
||||
profile_data_dir,
|
||||
f) for f in os.listdir(profile_data_dir) if f.startswith('webapp')]
|
||||
|
||||
# mozinfo is populated by the parent class
|
||||
if mozinfo.info['debug']:
|
||||
|
@ -68,7 +73,12 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
|
||||
def buildTestPath(self, options, testsToFilter=None):
|
||||
if options.manifestFile != 'tests.json':
|
||||
super(B2GMochitest, self).buildTestPath(options, testsToFilter, disabled=False)
|
||||
super(
|
||||
B2GMochitest,
|
||||
self).buildTestPath(
|
||||
options,
|
||||
testsToFilter,
|
||||
disabled=False)
|
||||
return self.buildTestURL(options)
|
||||
|
||||
def build_profile(self, options):
|
||||
|
@ -85,8 +95,11 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
prefs[thispref[0]] = thispref[1]
|
||||
|
||||
# interpolate the preferences
|
||||
interpolation = { "server": "%s:%s" % (options.webServer, options.httpPort),
|
||||
"OOP": "true" if self.out_of_process else "false" }
|
||||
interpolation = {
|
||||
"server": "%s:%s" %
|
||||
(options.webServer,
|
||||
options.httpPort),
|
||||
"OOP": "true" if self.out_of_process else "false"}
|
||||
prefs = json.loads(json.dumps(prefs) % interpolation)
|
||||
for pref in prefs:
|
||||
prefs[pref] = Preferences.cast(prefs[pref])
|
||||
|
@ -138,7 +151,8 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
if message['action'] == 'test_start':
|
||||
self.runner.last_test = message['test']
|
||||
|
||||
# The logging will be handled by on_output, so we set the stream to None
|
||||
# The logging will be handled by on_output, so we set the stream to
|
||||
# None
|
||||
process_args = {'processOutputLine': on_output,
|
||||
'stream': None}
|
||||
self.marionette_args['process_args'] = process_args
|
||||
|
@ -150,23 +164,29 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
|
||||
self.remote_log = posixpath.join(self.app_ctx.remote_test_root,
|
||||
'log', 'mochitest.log')
|
||||
if not self.app_ctx.dm.dirExists(posixpath.dirname(self.remote_log)):
|
||||
if not self.app_ctx.dm.dirExists(
|
||||
posixpath.dirname(
|
||||
self.remote_log)):
|
||||
self.app_ctx.dm.mkDirs(self.remote_log)
|
||||
|
||||
if options.chrome:
|
||||
# Update chrome manifest file in profile with correct path.
|
||||
self.writeChromeManifest(options)
|
||||
|
||||
self.leak_report_file = posixpath.join(self.app_ctx.remote_test_root,
|
||||
'log', 'runtests_leaks.log')
|
||||
self.leak_report_file = posixpath.join(
|
||||
self.app_ctx.remote_test_root,
|
||||
'log',
|
||||
'runtests_leaks.log')
|
||||
|
||||
# We don't want to copy the host env onto the device, so pass in an
|
||||
# empty env.
|
||||
self.browserEnv = self.buildBrowserEnv(options, env={})
|
||||
|
||||
# B2G emulator debug tests still make external connections, so don't
|
||||
# pass MOZ_DISABLE_NONLOCAL_CONNECTIONS to them for now (bug 1039019).
|
||||
if mozinfo.info['debug'] and 'MOZ_DISABLE_NONLOCAL_CONNECTIONS' in self.browserEnv:
|
||||
# pass MOZ_DISABLE_NONLOCAL_CONNECTIONS to them for now (bug
|
||||
# 1039019).
|
||||
if mozinfo.info[
|
||||
'debug'] and 'MOZ_DISABLE_NONLOCAL_CONNECTIONS' in self.browserEnv:
|
||||
del self.browserEnv['MOZ_DISABLE_NONLOCAL_CONNECTIONS']
|
||||
self.runner.env.update(self.browserEnv)
|
||||
|
||||
|
@ -176,7 +196,6 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
self.test_script_args.append(options.wifi)
|
||||
self.test_script_args.append(options.chrome)
|
||||
|
||||
|
||||
self.runner.start(outputTimeout=timeout)
|
||||
|
||||
self.marionette.wait_for_port()
|
||||
|
@ -185,7 +204,8 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
|
||||
# Disable offline status management (bug 777145), otherwise the network
|
||||
# will be 'offline' when the mochitests start. Presumably, the network
|
||||
# won't be offline on a real device, so we only do this for emulators.
|
||||
# won't be offline on a real device, so we only do this for
|
||||
# emulators.
|
||||
self.marionette.execute_script("""
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Services.io.manageOfflineStatus = false;
|
||||
|
@ -198,16 +218,20 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
local = super(B2GMochitest, self).getChromeTestDir(options)
|
||||
local = os.path.join(local, "chrome")
|
||||
remote = self.remote_chrome_test_dir
|
||||
self.log.info("pushing %s to %s on device..." % (local, remote))
|
||||
self.log.info(
|
||||
"pushing %s to %s on device..." %
|
||||
(local, remote))
|
||||
self.app_ctx.dm.pushDir(local, remote)
|
||||
|
||||
if os.path.isfile(self.test_script):
|
||||
with open(self.test_script, 'r') as script:
|
||||
self.marionette.execute_script(script.read(),
|
||||
script_args=self.test_script_args)
|
||||
self.marionette.execute_script(
|
||||
script.read(),
|
||||
script_args=self.test_script_args)
|
||||
else:
|
||||
self.marionette.execute_script(self.test_script,
|
||||
script_args=self.test_script_args)
|
||||
self.marionette.execute_script(
|
||||
self.test_script,
|
||||
script_args=self.test_script_args)
|
||||
status = self.runner.wait()
|
||||
|
||||
if status is None:
|
||||
|
@ -215,16 +239,19 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
status = 124
|
||||
|
||||
local_leak_file = tempfile.NamedTemporaryFile()
|
||||
self.app_ctx.dm.getFile(self.leak_report_file, local_leak_file.name)
|
||||
self.app_ctx.dm.getFile(
|
||||
self.leak_report_file,
|
||||
local_leak_file.name)
|
||||
self.app_ctx.dm.removeFile(self.leak_report_file)
|
||||
|
||||
processLeakLog(local_leak_file.name, options)
|
||||
except KeyboardInterrupt:
|
||||
self.log.info("runtests.py | Received keyboard interrupt.\n");
|
||||
self.log.info("runtests.py | Received keyboard interrupt.\n")
|
||||
status = -1
|
||||
except:
|
||||
traceback.print_exc()
|
||||
self.log.error("Automation Error: Received unexpected exception while running application\n")
|
||||
self.log.error(
|
||||
"Automation Error: Received unexpected exception while running application\n")
|
||||
if hasattr(self, 'runner'):
|
||||
self.runner.check_for_crashes()
|
||||
status = 1
|
||||
|
@ -249,7 +276,9 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
# is defined; the correct directory will be returned later, over-
|
||||
# writing the dummy.
|
||||
if hasattr(self, 'app_ctx'):
|
||||
self.remote_chrome_test_dir = posixpath.join(self.app_ctx.remote_test_root, 'chrome');
|
||||
self.remote_chrome_test_dir = posixpath.join(
|
||||
self.app_ctx.remote_test_root,
|
||||
'chrome')
|
||||
return self.remote_chrome_test_dir
|
||||
return 'dummy-chrome-test-dir'
|
||||
|
||||
|
@ -257,9 +286,20 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||
class B2GDeviceMochitest(B2GMochitest, Mochitest):
|
||||
remote_log = None
|
||||
|
||||
def __init__(self, marionette_args, logger_options, profile_data_dir,
|
||||
local_binary_dir, remote_test_root=None, remote_log_file=None):
|
||||
B2GMochitest.__init__(self, marionette_args, logger_options, out_of_process=True, profile_data_dir=profile_data_dir)
|
||||
def __init__(
|
||||
self,
|
||||
marionette_args,
|
||||
logger_options,
|
||||
profile_data_dir,
|
||||
local_binary_dir,
|
||||
remote_test_root=None,
|
||||
remote_log_file=None):
|
||||
B2GMochitest.__init__(
|
||||
self,
|
||||
marionette_args,
|
||||
logger_options,
|
||||
out_of_process=True,
|
||||
profile_data_dir=profile_data_dir)
|
||||
self.local_log = None
|
||||
self.local_binary_dir = local_binary_dir
|
||||
|
||||
|
@ -314,7 +354,12 @@ class B2GDeviceMochitest(B2GMochitest, Mochitest):
|
|||
class B2GDesktopMochitest(B2GMochitest, Mochitest):
|
||||
|
||||
def __init__(self, marionette_args, logger_options, profile_data_dir):
|
||||
B2GMochitest.__init__(self, marionette_args, logger_options, out_of_process=False, profile_data_dir=profile_data_dir)
|
||||
B2GMochitest.__init__(
|
||||
self,
|
||||
marionette_args,
|
||||
logger_options,
|
||||
out_of_process=False,
|
||||
profile_data_dir=profile_data_dir)
|
||||
Mochitest.__init__(self, logger_options)
|
||||
self.certdbNew = True
|
||||
|
||||
|
@ -347,7 +392,10 @@ class B2GDesktopMochitest(B2GMochitest, Mochitest):
|
|||
self.setup_common_options(options)
|
||||
|
||||
# Copy the extensions to the B2G bundles dir.
|
||||
extensionDir = os.path.join(options.profilePath, 'extensions', 'staged')
|
||||
extensionDir = os.path.join(
|
||||
options.profilePath,
|
||||
'extensions',
|
||||
'staged')
|
||||
bundlesDir = os.path.join(os.path.dirname(options.app),
|
||||
'distribution', 'bundles')
|
||||
|
||||
|
@ -378,15 +426,19 @@ def run_remote_mochitests(parser, options):
|
|||
marionette_args['port'] = int(port)
|
||||
|
||||
options = parser.verifyRemoteOptions(options)
|
||||
if (options == None):
|
||||
if (options is None):
|
||||
print "ERROR: Invalid options specified, use --help for a list of valid options"
|
||||
sys.exit(1)
|
||||
|
||||
mochitest = B2GDeviceMochitest(marionette_args, options, options.profile_data_dir,
|
||||
options.xrePath, remote_log_file=options.remoteLogFile)
|
||||
mochitest = B2GDeviceMochitest(
|
||||
marionette_args,
|
||||
options,
|
||||
options.profile_data_dir,
|
||||
options.xrePath,
|
||||
remote_log_file=options.remoteLogFile)
|
||||
|
||||
options = parser.verifyOptions(options, mochitest)
|
||||
if (options == None):
|
||||
if (options is None):
|
||||
sys.exit(1)
|
||||
|
||||
retVal = 1
|
||||
|
@ -407,6 +459,7 @@ def run_remote_mochitests(parser, options):
|
|||
|
||||
sys.exit(retVal)
|
||||
|
||||
|
||||
def run_desktop_mochitests(parser, options):
|
||||
# create our Marionette instance
|
||||
marionette_args = {}
|
||||
|
@ -420,9 +473,12 @@ def run_desktop_mochitests(parser, options):
|
|||
if os.path.isfile("%s-bin" % options.app):
|
||||
options.app = "%s-bin" % options.app
|
||||
|
||||
mochitest = B2GDesktopMochitest(marionette_args, options, options.profile_data_dir)
|
||||
mochitest = B2GDesktopMochitest(
|
||||
marionette_args,
|
||||
options,
|
||||
options.profile_data_dir)
|
||||
options = MochitestOptions.verifyOptions(parser, options, mochitest)
|
||||
if options == None:
|
||||
if options is None:
|
||||
sys.exit(1)
|
||||
|
||||
if options.desktop and not options.profile:
|
||||
|
@ -435,6 +491,7 @@ def run_desktop_mochitests(parser, options):
|
|||
|
||||
sys.exit(retVal)
|
||||
|
||||
|
||||
def main():
|
||||
parser = B2GOptions()
|
||||
structured.commandline.add_logging_group(parser)
|
||||
|
|
|
@ -13,7 +13,10 @@ import sys
|
|||
import tempfile
|
||||
import traceback
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.realpath(os.path.dirname(__file__))))
|
||||
sys.path.insert(
|
||||
0, os.path.abspath(
|
||||
os.path.realpath(
|
||||
os.path.dirname(__file__))))
|
||||
|
||||
from automation import Automation
|
||||
from remoteautomation import RemoteAutomation, fennecLogcatFilters
|
||||
|
@ -29,6 +32,7 @@ import moznetwork
|
|||
|
||||
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
class RemoteOptions(MochitestOptions):
|
||||
|
||||
def __init__(self, automation, **kwargs):
|
||||
|
@ -36,84 +40,117 @@ class RemoteOptions(MochitestOptions):
|
|||
self._automation = automation or Automation()
|
||||
MochitestOptions.__init__(self)
|
||||
|
||||
self.add_option("--remote-app-path", action="store",
|
||||
type = "string", dest = "remoteAppPath",
|
||||
help = "Path to remote executable relative to device root using only forward slashes. Either this or app must be specified but not both")
|
||||
self.add_option(
|
||||
"--remote-app-path",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="remoteAppPath",
|
||||
help="Path to remote executable relative to device root using only forward slashes. Either this or app must be specified but not both")
|
||||
defaults["remoteAppPath"] = None
|
||||
|
||||
self.add_option("--deviceIP", action="store",
|
||||
type = "string", dest = "deviceIP",
|
||||
help = "ip address of remote device to test")
|
||||
type="string", dest="deviceIP",
|
||||
help="ip address of remote device to test")
|
||||
defaults["deviceIP"] = None
|
||||
|
||||
self.add_option("--deviceSerial", action="store",
|
||||
type = "string", dest = "deviceSerial",
|
||||
help = "ip address of remote device to test")
|
||||
type="string", dest="deviceSerial",
|
||||
help="ip address of remote device to test")
|
||||
defaults["deviceSerial"] = None
|
||||
|
||||
self.add_option("--dm_trans", action="store",
|
||||
type = "string", dest = "dm_trans",
|
||||
help = "the transport to use to communicate with device: [adb|sut]; default=sut")
|
||||
self.add_option(
|
||||
"--dm_trans",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="dm_trans",
|
||||
help="the transport to use to communicate with device: [adb|sut]; default=sut")
|
||||
defaults["dm_trans"] = "sut"
|
||||
|
||||
self.add_option("--devicePort", action="store",
|
||||
type = "string", dest = "devicePort",
|
||||
help = "port of remote device to test")
|
||||
type="string", dest="devicePort",
|
||||
help="port of remote device to test")
|
||||
defaults["devicePort"] = 20701
|
||||
|
||||
self.add_option("--remote-product-name", action="store",
|
||||
type = "string", dest = "remoteProductName",
|
||||
help = "The executable's name of remote product to test - either fennec or firefox, defaults to fennec")
|
||||
self.add_option(
|
||||
"--remote-product-name",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="remoteProductName",
|
||||
help="The executable's name of remote product to test - either fennec or firefox, defaults to fennec")
|
||||
defaults["remoteProductName"] = "fennec"
|
||||
|
||||
self.add_option("--remote-logfile", action="store",
|
||||
type = "string", dest = "remoteLogFile",
|
||||
help = "Name of log file on the device relative to the device root. PLEASE ONLY USE A FILENAME.")
|
||||
self.add_option(
|
||||
"--remote-logfile",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="remoteLogFile",
|
||||
help="Name of log file on the device relative to the device root. PLEASE ONLY USE A FILENAME.")
|
||||
defaults["remoteLogFile"] = None
|
||||
|
||||
self.add_option("--remote-webserver", action = "store",
|
||||
type = "string", dest = "remoteWebServer",
|
||||
help = "ip address where the remote web server is hosted at")
|
||||
self.add_option(
|
||||
"--remote-webserver",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="remoteWebServer",
|
||||
help="ip address where the remote web server is hosted at")
|
||||
defaults["remoteWebServer"] = None
|
||||
|
||||
self.add_option("--http-port", action = "store",
|
||||
type = "string", dest = "httpPort",
|
||||
help = "http port of the remote web server")
|
||||
self.add_option("--http-port", action="store",
|
||||
type="string", dest="httpPort",
|
||||
help="http port of the remote web server")
|
||||
defaults["httpPort"] = automation.DEFAULT_HTTP_PORT
|
||||
|
||||
self.add_option("--ssl-port", action = "store",
|
||||
type = "string", dest = "sslPort",
|
||||
help = "ssl port of the remote web server")
|
||||
self.add_option("--ssl-port", action="store",
|
||||
type="string", dest="sslPort",
|
||||
help="ssl port of the remote web server")
|
||||
defaults["sslPort"] = automation.DEFAULT_SSL_PORT
|
||||
|
||||
self.add_option("--robocop-ini", action = "store",
|
||||
type = "string", dest = "robocopIni",
|
||||
help = "name of the .ini file containing the list of tests to run")
|
||||
self.add_option(
|
||||
"--robocop-ini",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="robocopIni",
|
||||
help="name of the .ini file containing the list of tests to run")
|
||||
defaults["robocopIni"] = ""
|
||||
|
||||
self.add_option("--robocop", action = "store",
|
||||
type = "string", dest = "robocop",
|
||||
help = "name of the .ini file containing the list of tests to run. [DEPRECATED- please use --robocop-ini")
|
||||
self.add_option(
|
||||
"--robocop",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="robocop",
|
||||
help="name of the .ini file containing the list of tests to run. [DEPRECATED- please use --robocop-ini")
|
||||
defaults["robocop"] = ""
|
||||
|
||||
self.add_option("--robocop-apk", action = "store",
|
||||
type = "string", dest = "robocopApk",
|
||||
help = "name of the Robocop APK to use for ADB test running")
|
||||
self.add_option(
|
||||
"--robocop-apk",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="robocopApk",
|
||||
help="name of the Robocop APK to use for ADB test running")
|
||||
defaults["robocopApk"] = ""
|
||||
|
||||
self.add_option("--robocop-path", action = "store",
|
||||
type = "string", dest = "robocopPath",
|
||||
help = "Path to the folder where robocop.apk is located at. Primarily used for ADB test running. [DEPRECATED- please use --robocop-apk]")
|
||||
self.add_option(
|
||||
"--robocop-path",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="robocopPath",
|
||||
help="Path to the folder where robocop.apk is located at. Primarily used for ADB test running. [DEPRECATED- please use --robocop-apk]")
|
||||
defaults["robocopPath"] = ""
|
||||
|
||||
self.add_option("--robocop-ids", action = "store",
|
||||
type = "string", dest = "robocopIds",
|
||||
help = "name of the file containing the view ID map (fennec_ids.txt)")
|
||||
self.add_option(
|
||||
"--robocop-ids",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="robocopIds",
|
||||
help="name of the file containing the view ID map (fennec_ids.txt)")
|
||||
defaults["robocopIds"] = ""
|
||||
|
||||
self.add_option("--remoteTestRoot", action = "store",
|
||||
type = "string", dest = "remoteTestRoot",
|
||||
help = "remote directory to use as test root (eg. /mnt/sdcard/tests or /data/local/tests)")
|
||||
self.add_option(
|
||||
"--remoteTestRoot",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="remoteTestRoot",
|
||||
help="remote directory to use as test root (eg. /mnt/sdcard/tests or /data/local/tests)")
|
||||
defaults["remoteTestRoot"] = None
|
||||
|
||||
defaults["logFile"] = "mochitest.log"
|
||||
|
@ -131,38 +168,43 @@ class RemoteOptions(MochitestOptions):
|
|||
if not options.remoteTestRoot:
|
||||
options.remoteTestRoot = automation._devicemanager.deviceRoot
|
||||
|
||||
if options.remoteWebServer == None:
|
||||
if options.remoteWebServer is None:
|
||||
if os.name != "nt":
|
||||
options.remoteWebServer = moznetwork.get_ip()
|
||||
else:
|
||||
options_logger.error("you must specify a --remote-webserver=<ip address>")
|
||||
options_logger.error(
|
||||
"you must specify a --remote-webserver=<ip address>")
|
||||
return None
|
||||
|
||||
options.webServer = options.remoteWebServer
|
||||
|
||||
if (options.dm_trans == 'sut' and options.deviceIP == None):
|
||||
options_logger.error("If --dm_trans = sut, you must provide a device IP")
|
||||
if (options.dm_trans == 'sut' and options.deviceIP is None):
|
||||
options_logger.error(
|
||||
"If --dm_trans = sut, you must provide a device IP")
|
||||
return None
|
||||
|
||||
if (options.remoteLogFile == None):
|
||||
options.remoteLogFile = options.remoteTestRoot + '/logs/mochitest.log'
|
||||
if (options.remoteLogFile is None):
|
||||
options.remoteLogFile = options.remoteTestRoot + \
|
||||
'/logs/mochitest.log'
|
||||
|
||||
if (options.remoteLogFile.count('/') < 1):
|
||||
options.remoteLogFile = options.remoteTestRoot + '/' + options.remoteLogFile
|
||||
options.remoteLogFile = options.remoteTestRoot + \
|
||||
'/' + options.remoteLogFile
|
||||
|
||||
# remoteAppPath or app must be specified to find the product to launch
|
||||
if (options.remoteAppPath and options.app):
|
||||
options_logger.error("You cannot specify both the remoteAppPath and the app setting")
|
||||
options_logger.error(
|
||||
"You cannot specify both the remoteAppPath and the app setting")
|
||||
return None
|
||||
elif (options.remoteAppPath):
|
||||
options.app = options.remoteTestRoot + "/" + options.remoteAppPath
|
||||
elif (options.app == None):
|
||||
elif (options.app is None):
|
||||
# Neither remoteAppPath nor app are set -- error
|
||||
options_logger.error("You must specify either appPath or app")
|
||||
return None
|
||||
|
||||
# Only reset the xrePath if it wasn't provided
|
||||
if (options.xrePath == None):
|
||||
if (options.xrePath is None):
|
||||
options.xrePath = options.utilityPath
|
||||
|
||||
if (options.pidFile != ""):
|
||||
|
@ -173,38 +215,49 @@ class RemoteOptions(MochitestOptions):
|
|||
# Robocop specific deprecated options.
|
||||
if options.robocop:
|
||||
if options.robocopIni:
|
||||
options_logger.error("can not use deprecated --robocop and replacement --robocop-ini together")
|
||||
options_logger.error(
|
||||
"can not use deprecated --robocop and replacement --robocop-ini together")
|
||||
return None
|
||||
options.robocopIni = options.robocop
|
||||
del options.robocop
|
||||
|
||||
if options.robocopPath:
|
||||
if options.robocopApk:
|
||||
options_logger.error("can not use deprecated --robocop-path and replacement --robocop-apk together")
|
||||
options_logger.error(
|
||||
"can not use deprecated --robocop-path and replacement --robocop-apk together")
|
||||
return None
|
||||
options.robocopApk = os.path.join(options.robocopPath, 'robocop.apk')
|
||||
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):
|
||||
options_logger.error("Unable to find specified robocop .ini manifest '%s'" % options.robocopIni)
|
||||
options_logger.error(
|
||||
"Unable to find specified robocop .ini manifest '%s'" %
|
||||
options.robocopIni)
|
||||
return None
|
||||
options.robocopIni = os.path.abspath(options.robocopIni)
|
||||
|
||||
if options.robocopApk != "":
|
||||
if not os.path.exists(options.robocopApk):
|
||||
options_logger.error("Unable to find robocop APK '%s'" % options.robocopApk)
|
||||
options_logger.error(
|
||||
"Unable to find robocop APK '%s'" %
|
||||
options.robocopApk)
|
||||
return None
|
||||
options.robocopApk = os.path.abspath(options.robocopApk)
|
||||
|
||||
if options.robocopIds != "":
|
||||
if not os.path.exists(options.robocopIds):
|
||||
options_logger.error("Unable to find specified robocop IDs file '%s'" % options.robocopIds)
|
||||
options_logger.error(
|
||||
"Unable to find specified robocop IDs file '%s'" %
|
||||
options.robocopIds)
|
||||
return None
|
||||
options.robocopIds = os.path.abspath(options.robocopIds)
|
||||
|
||||
# allow us to keep original application around for cleanup while running robocop via 'am'
|
||||
# allow us to keep original application around for cleanup while
|
||||
# running robocop via 'am'
|
||||
options.remoteappname = options.app
|
||||
return options
|
||||
|
||||
|
@ -226,6 +279,7 @@ class RemoteOptions(MochitestOptions):
|
|||
|
||||
return options
|
||||
|
||||
|
||||
class MochiRemote(Mochitest):
|
||||
|
||||
_automation = None
|
||||
|
@ -247,20 +301,24 @@ class MochiRemote(Mochitest):
|
|||
self._automation.deleteTombstones()
|
||||
self.certdbNew = True
|
||||
self.remoteNSPR = os.path.join(options.remoteTestRoot, "nspr")
|
||||
self._dm.removeDir(self.remoteNSPR);
|
||||
self._dm.mkDir(self.remoteNSPR);
|
||||
self.remoteChromeTestDir = os.path.join(options.remoteTestRoot, "chrome")
|
||||
self._dm.removeDir(self.remoteChromeTestDir);
|
||||
self._dm.mkDir(self.remoteChromeTestDir);
|
||||
self._dm.removeDir(self.remoteNSPR)
|
||||
self._dm.mkDir(self.remoteNSPR)
|
||||
self.remoteChromeTestDir = os.path.join(
|
||||
options.remoteTestRoot,
|
||||
"chrome")
|
||||
self._dm.removeDir(self.remoteChromeTestDir)
|
||||
self._dm.mkDir(self.remoteChromeTestDir)
|
||||
|
||||
def cleanup(self, options):
|
||||
if self._dm.fileExists(self.remoteLog):
|
||||
self._dm.getFile(self.remoteLog, self.localLog)
|
||||
self._dm.removeFile(self.remoteLog)
|
||||
else:
|
||||
self.log.warning("Unable to retrieve log file (%s) from remote device" % self.remoteLog)
|
||||
self.log.warning(
|
||||
"Unable to retrieve log file (%s) from remote device" %
|
||||
self.remoteLog)
|
||||
self._dm.removeDir(self.remoteProfile)
|
||||
self._dm.removeDir(self.remoteChromeTestDir);
|
||||
self._dm.removeDir(self.remoteChromeTestDir)
|
||||
# Don't leave an old robotium.config hanging around; the
|
||||
# profile it references was just deleted!
|
||||
deviceRoot = self._dm.getDeviceRoot()
|
||||
|
@ -270,7 +328,7 @@ class MochiRemote(Mochitest):
|
|||
self._dm.getDirectory(self.remoteNSPR, blobberUploadDir)
|
||||
Mochitest.cleanup(self, options)
|
||||
|
||||
def findPath(self, paths, filename = None):
|
||||
def findPath(self, paths, filename=None):
|
||||
for path in paths:
|
||||
p = path
|
||||
if filename:
|
||||
|
@ -286,7 +344,7 @@ class MochiRemote(Mochitest):
|
|||
localAutomation.IS_MAC = False
|
||||
localAutomation.UNIXISH = False
|
||||
hostos = sys.platform
|
||||
if (hostos == 'mac' or hostos == 'darwin'):
|
||||
if (hostos == 'mac' or hostos == 'darwin'):
|
||||
localAutomation.IS_MAC = True
|
||||
elif (hostos == 'linux' or hostos == 'linux2'):
|
||||
localAutomation.IS_LINUX = True
|
||||
|
@ -315,8 +373,10 @@ class MochiRemote(Mochitest):
|
|||
os.path.join('..', self._automation._product)
|
||||
]
|
||||
options.xrePath = self.findPath(paths)
|
||||
if options.xrePath == None:
|
||||
self.log.error("unable to find xulrunner path for %s, please specify with --xre-path" % os.name)
|
||||
if options.xrePath is None:
|
||||
self.log.error(
|
||||
"unable to find xulrunner path for %s, please specify with --xre-path" %
|
||||
os.name)
|
||||
sys.exit(1)
|
||||
|
||||
xpcshell = "xpcshell"
|
||||
|
@ -329,15 +389,17 @@ class MochiRemote(Mochitest):
|
|||
paths = [options.xrePath]
|
||||
options.utilityPath = self.findPath(paths, xpcshell)
|
||||
|
||||
if options.utilityPath == None:
|
||||
self.log.error("unable to find utility path for %s, please specify with --utility-path" % os.name)
|
||||
if options.utilityPath is None:
|
||||
self.log.error(
|
||||
"unable to find utility path for %s, please specify with --utility-path" %
|
||||
os.name)
|
||||
sys.exit(1)
|
||||
|
||||
xpcshell_path = os.path.join(options.utilityPath, xpcshell)
|
||||
if localAutomation.elf_arm(xpcshell_path):
|
||||
self.log.error('xpcshell at %s is an ARM binary; please use '
|
||||
'the --utility-path argument to specify the path '
|
||||
'to a desktop version.' % xpcshell_path)
|
||||
'the --utility-path argument to specify the path '
|
||||
'to a desktop version.' % xpcshell_path)
|
||||
sys.exit(1)
|
||||
|
||||
if self.localProfile:
|
||||
|
@ -356,7 +418,11 @@ class MochiRemote(Mochitest):
|
|||
""" Create the servers on the host and start them up """
|
||||
restoreRemotePaths = self.switchToLocalPaths(options)
|
||||
# ignoreSSLTunnelExts is a workaround for bug 1109310
|
||||
Mochitest.startServers(self, options, debuggerInfo, ignoreSSLTunnelExts = True)
|
||||
Mochitest.startServers(
|
||||
self,
|
||||
options,
|
||||
debuggerInfo,
|
||||
ignoreSSLTunnelExts=True)
|
||||
restoreRemotePaths()
|
||||
|
||||
def buildProfile(self, options):
|
||||
|
@ -368,15 +434,31 @@ class MochiRemote(Mochitest):
|
|||
# we do not need this for robotium based tests, lets save a LOT of time
|
||||
if options.robocopIni:
|
||||
shutil.rmtree(os.path.join(options.profilePath, 'webapps'))
|
||||
shutil.rmtree(os.path.join(options.profilePath, 'extensions', 'staged', 'mochikit@mozilla.org'))
|
||||
shutil.rmtree(os.path.join(options.profilePath, 'extensions', 'staged', 'worker-test@mozilla.org'))
|
||||
shutil.rmtree(os.path.join(options.profilePath, 'extensions', 'staged', 'workerbootstrap-test@mozilla.org'))
|
||||
shutil.rmtree(
|
||||
os.path.join(
|
||||
options.profilePath,
|
||||
'extensions',
|
||||
'staged',
|
||||
'mochikit@mozilla.org'))
|
||||
shutil.rmtree(
|
||||
os.path.join(
|
||||
options.profilePath,
|
||||
'extensions',
|
||||
'staged',
|
||||
'worker-test@mozilla.org'))
|
||||
shutil.rmtree(
|
||||
os.path.join(
|
||||
options.profilePath,
|
||||
'extensions',
|
||||
'staged',
|
||||
'workerbootstrap-test@mozilla.org'))
|
||||
os.remove(os.path.join(options.profilePath, 'userChrome.css'))
|
||||
|
||||
try:
|
||||
self._dm.pushDir(options.profilePath, self.remoteProfile)
|
||||
except devicemanager.DMError:
|
||||
self.log.error("Automation Error: Unable to copy profile to device.")
|
||||
self.log.error(
|
||||
"Automation Error: Unable to copy profile to device.")
|
||||
raise
|
||||
|
||||
restoreRemotePaths()
|
||||
|
@ -392,11 +474,12 @@ class MochiRemote(Mochitest):
|
|||
retVal = Mochitest.buildURLOptions(self, options, env)
|
||||
|
||||
if not options.robocopIni:
|
||||
#we really need testConfig.js (for browser chrome)
|
||||
# we really need testConfig.js (for browser chrome)
|
||||
try:
|
||||
self._dm.pushDir(options.profilePath, self.remoteProfile)
|
||||
except devicemanager.DMError:
|
||||
self.log.error("Automation Error: Unable to copy profile to device.")
|
||||
self.log.error(
|
||||
"Automation Error: Unable to copy profile to device.")
|
||||
raise
|
||||
|
||||
options.profilePath = self.remoteProfile
|
||||
|
@ -416,7 +499,11 @@ class MochiRemote(Mochitest):
|
|||
# robocop tests.
|
||||
return self.buildTestURL(options)
|
||||
else:
|
||||
return super(MochiRemote, self).buildTestPath(options, testsToFilter)
|
||||
return super(
|
||||
MochiRemote,
|
||||
self).buildTestPath(
|
||||
options,
|
||||
testsToFilter)
|
||||
|
||||
def getChromeTestDir(self, options):
|
||||
local = super(MochiRemote, self).getChromeTestDir(options)
|
||||
|
@ -430,7 +517,8 @@ class MochiRemote(Mochitest):
|
|||
def getLogFilePath(self, logFile):
|
||||
return logFile
|
||||
|
||||
# In the future we could use LogParser: http://hg.mozilla.org/automation/logparser/
|
||||
# In the future we could use LogParser:
|
||||
# http://hg.mozilla.org/automation/logparser/
|
||||
def addLogData(self):
|
||||
with open(self.localLog) as currentLog:
|
||||
data = currentLog.readlines()
|
||||
|
@ -461,7 +549,8 @@ class MochiRemote(Mochitest):
|
|||
if fail_found:
|
||||
result = 1
|
||||
if not end_found:
|
||||
self.log.info("PROCESS-CRASH | Automation Error: Missing end of test marker (process crashed?)")
|
||||
self.log.info(
|
||||
"PROCESS-CRASH | Automation Error: Missing end of test marker (process crashed?)")
|
||||
result = 1
|
||||
return result
|
||||
|
||||
|
@ -494,7 +583,8 @@ class MochiRemote(Mochitest):
|
|||
incr += 1
|
||||
logFile.append("%s INFO SimpleTest FINISHED" % incr)
|
||||
|
||||
# TODO: Consider not printing to stdout because we might be duplicating output
|
||||
# TODO: Consider not printing to stdout because we might be duplicating
|
||||
# output
|
||||
print '\n'.join(logFile)
|
||||
with open(self.localLog, 'w') as localLog:
|
||||
localLog.write('\n'.join(logFile))
|
||||
|
@ -506,7 +596,9 @@ class MochiRemote(Mochitest):
|
|||
def printScreenshots(self, screenShotDir):
|
||||
# TODO: This can be re-written after completion of bug 749421
|
||||
if not self._dm.dirExists(screenShotDir):
|
||||
self.log.info("SCREENSHOT: No ScreenShots directory available: " + screenShotDir)
|
||||
self.log.info(
|
||||
"SCREENSHOT: No ScreenShots directory available: " +
|
||||
screenShotDir)
|
||||
return
|
||||
|
||||
printed = 0
|
||||
|
@ -527,8 +619,13 @@ class MochiRemote(Mochitest):
|
|||
def printDeviceInfo(self, printLogcat=False):
|
||||
try:
|
||||
if printLogcat:
|
||||
logcat = self._dm.getLogcat(filterOutRegexps=fennecLogcatFilters)
|
||||
self.log.info('\n' + ''.join(logcat).decode('utf-8', 'replace'))
|
||||
logcat = self._dm.getLogcat(
|
||||
filterOutRegexps=fennecLogcatFilters)
|
||||
self.log.info(
|
||||
'\n' +
|
||||
''.join(logcat).decode(
|
||||
'utf-8',
|
||||
'replace'))
|
||||
self.log.info("Device info: %s" % self._dm.getInfo())
|
||||
self.log.info("Test root: %s" % self._dm.deviceRoot)
|
||||
except devicemanager.DMError:
|
||||
|
@ -543,7 +640,9 @@ class MochiRemote(Mochitest):
|
|||
fHandle.write("profile=%s\n" % (self.remoteProfile))
|
||||
fHandle.write("logfile=%s\n" % (options.remoteLogFile))
|
||||
fHandle.write("host=http://mochi.test:8888/tests\n")
|
||||
fHandle.write("rawhost=http://%s:%s/tests\n" % (options.remoteWebServer, options.httpPort))
|
||||
fHandle.write(
|
||||
"rawhost=http://%s:%s/tests\n" %
|
||||
(options.remoteWebServer, options.httpPort))
|
||||
|
||||
if browserEnv:
|
||||
envstr = ""
|
||||
|
@ -551,7 +650,9 @@ class MochiRemote(Mochitest):
|
|||
for key, value in browserEnv.items():
|
||||
try:
|
||||
value.index(',')
|
||||
self.log.error("buildRobotiumConfig: browserEnv - Found a ',' in our value, unable to process value. key=%s,value=%s" % (key, value))
|
||||
self.log.error(
|
||||
"buildRobotiumConfig: browserEnv - Found a ',' in our value, unable to process value. key=%s,value=%s" %
|
||||
(key, value))
|
||||
self.log.error("browserEnv=%s" % browserEnv)
|
||||
except ValueError:
|
||||
envstr += "%s%s=%s" % (delim, key, value)
|
||||
|
@ -561,7 +662,11 @@ class MochiRemote(Mochitest):
|
|||
fHandle.close()
|
||||
|
||||
self._dm.removeFile(os.path.join(deviceRoot, "robotium.config"))
|
||||
self._dm.pushFile(fHandle.name, os.path.join(deviceRoot, "robotium.config"))
|
||||
self._dm.pushFile(
|
||||
fHandle.name,
|
||||
os.path.join(
|
||||
deviceRoot,
|
||||
"robotium.config"))
|
||||
os.unlink(fHandle.name)
|
||||
|
||||
def getGMPPluginPath(self, options):
|
||||
|
@ -569,10 +674,15 @@ class MochiRemote(Mochitest):
|
|||
return None
|
||||
|
||||
def buildBrowserEnv(self, options, debugger=False):
|
||||
browserEnv = Mochitest.buildBrowserEnv(self, options, debugger=debugger)
|
||||
browserEnv = Mochitest.buildBrowserEnv(
|
||||
self,
|
||||
options,
|
||||
debugger=debugger)
|
||||
# override nsprLogs to avoid processing in Mochitest base class
|
||||
self.nsprLogs = None
|
||||
browserEnv["NSPR_LOG_FILE"] = os.path.join(self.remoteNSPR, self.nsprLogName)
|
||||
browserEnv["NSPR_LOG_FILE"] = os.path.join(
|
||||
self.remoteNSPR,
|
||||
self.nsprLogName)
|
||||
self.buildRobotiumConfig(options, browserEnv)
|
||||
return browserEnv
|
||||
|
||||
|
@ -593,6 +703,7 @@ class MochiRemote(Mochitest):
|
|||
|
||||
return self._automation.runApp(*args, **kwargs)
|
||||
|
||||
|
||||
def main(args):
|
||||
message_logger = MessageLogger(logger=None)
|
||||
process_args = {'messageLogger': message_logger}
|
||||
|
@ -604,13 +715,23 @@ def main(args):
|
|||
|
||||
if (options.dm_trans == "adb"):
|
||||
if (options.deviceIP):
|
||||
dm = droid.DroidADB(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot)
|
||||
dm = droid.DroidADB(
|
||||
options.deviceIP,
|
||||
options.devicePort,
|
||||
deviceRoot=options.remoteTestRoot)
|
||||
elif (options.deviceSerial):
|
||||
dm = droid.DroidADB(None, None, deviceSerial=options.deviceSerial, deviceRoot=options.remoteTestRoot)
|
||||
dm = droid.DroidADB(
|
||||
None,
|
||||
None,
|
||||
deviceSerial=options.deviceSerial,
|
||||
deviceRoot=options.remoteTestRoot)
|
||||
else:
|
||||
dm = droid.DroidADB(deviceRoot=options.remoteTestRoot)
|
||||
else:
|
||||
dm = droid.DroidSUT(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot)
|
||||
dm = droid.DroidSUT(
|
||||
options.deviceIP,
|
||||
options.devicePort,
|
||||
deviceRoot=options.remoteTestRoot)
|
||||
auto.setDeviceManager(dm)
|
||||
options = parser.verifyRemoteOptions(options, auto)
|
||||
|
||||
|
@ -620,23 +741,24 @@ def main(args):
|
|||
message_logger.logger = log
|
||||
mochitest.message_logger = message_logger
|
||||
|
||||
if (options == None):
|
||||
log.error("Invalid options specified, use --help for a list of valid options")
|
||||
if (options is None):
|
||||
log.error(
|
||||
"Invalid options specified, use --help for a list of valid options")
|
||||
return 1
|
||||
|
||||
productPieces = options.remoteProductName.split('.')
|
||||
if (productPieces != None):
|
||||
if (productPieces is not None):
|
||||
auto.setProduct(productPieces[0])
|
||||
else:
|
||||
auto.setProduct(options.remoteProductName)
|
||||
auto.setAppName(options.remoteappname)
|
||||
|
||||
options = parser.verifyOptions(options, mochitest)
|
||||
if (options == None):
|
||||
if (options is None):
|
||||
return 1
|
||||
|
||||
logParent = os.path.dirname(options.remoteLogFile)
|
||||
dm.mkDir(logParent);
|
||||
dm.mkDir(logParent)
|
||||
auto.setRemoteLog(options.remoteLogFile)
|
||||
auto.setServerInfo(options.webServer, options.httpPort, options.sslPort)
|
||||
|
||||
|
@ -645,7 +767,9 @@ def main(args):
|
|||
# Add Android version (SDK level) to mozinfo so that manifest entries
|
||||
# can be conditional on android_version.
|
||||
androidVersion = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk'])
|
||||
log.info("Android sdk version '%s'; will use this to filter manifests" % str(androidVersion))
|
||||
log.info(
|
||||
"Android sdk version '%s'; will use this to filter manifests" %
|
||||
str(androidVersion))
|
||||
mozinfo.info['android_version'] = androidVersion
|
||||
|
||||
deviceRoot = dm.deviceRoot
|
||||
|
@ -677,13 +801,14 @@ def main(args):
|
|||
tests.append(test['name'])
|
||||
|
||||
if options.totalChunks:
|
||||
tests_per_chunk = math.ceil(len(tests) / (options.totalChunks * 1.0))
|
||||
start = int(round((options.thisChunk-1) * tests_per_chunk))
|
||||
tests_per_chunk = math.ceil(
|
||||
len(tests) / (options.totalChunks * 1.0))
|
||||
start = int(round((options.thisChunk - 1) * tests_per_chunk))
|
||||
end = int(round(options.thisChunk * tests_per_chunk))
|
||||
if end > len(tests):
|
||||
end = len(tests)
|
||||
my_tests = tests[start:end]
|
||||
log.info("Running tests %d-%d/%d" % (start+1, end, len(tests)))
|
||||
log.info("Running tests %d-%d/%d" % (start + 1, end, len(tests)))
|
||||
|
||||
options.extraPrefs.append('browser.search.suggest.enabled=true')
|
||||
options.extraPrefs.append('browser.search.suggest.prompted=true')
|
||||
|
@ -706,7 +831,9 @@ def main(args):
|
|||
continue
|
||||
|
||||
if 'disabled' in test:
|
||||
log.info('TEST-INFO | skipping %s | %s' % (test['name'], test['disabled']))
|
||||
log.info(
|
||||
'TEST-INFO | skipping %s | %s' %
|
||||
(test['name'], test['disabled']))
|
||||
continue
|
||||
|
||||
active_tests.append(test)
|
||||
|
@ -714,7 +841,8 @@ def main(args):
|
|||
log.suite_start([t['name'] for t in active_tests])
|
||||
|
||||
for test in active_tests:
|
||||
# When running in a loop, we need to create a fresh profile for each cycle
|
||||
# When running in a loop, we need to create a fresh profile for
|
||||
# each cycle
|
||||
if mochitest.localProfile:
|
||||
options.profilePath = mochitest.localProfile
|
||||
os.system("rm -Rf %s" % options.profilePath)
|
||||
|
@ -722,34 +850,75 @@ def main(args):
|
|||
mochitest.localProfile = options.profilePath
|
||||
|
||||
options.app = "am"
|
||||
options.browserArgs = ["instrument", "-w", "-e", "deviceroot", deviceRoot, "-e", "class"]
|
||||
options.browserArgs.append("org.mozilla.gecko.tests.%s" % test['name'])
|
||||
options.browserArgs.append("org.mozilla.roboexample.test/org.mozilla.gecko.FennecInstrumentationTestRunner")
|
||||
options.browserArgs = [
|
||||
"instrument",
|
||||
"-w",
|
||||
"-e",
|
||||
"deviceroot",
|
||||
deviceRoot,
|
||||
"-e",
|
||||
"class"]
|
||||
options.browserArgs.append(
|
||||
"org.mozilla.gecko.tests.%s" %
|
||||
test['name'])
|
||||
options.browserArgs.append(
|
||||
"org.mozilla.roboexample.test/org.mozilla.gecko.FennecInstrumentationTestRunner")
|
||||
mochitest.nsprLogName = "nspr-%s.log" % test['name']
|
||||
|
||||
# If the test is for checking the import from bookmarks then make sure there is data to import
|
||||
# If the test is for checking the import from bookmarks then make
|
||||
# sure there is data to import
|
||||
if test['name'] == "testImportFromAndroid":
|
||||
|
||||
# Get the OS so we can run the insert in the apropriate database and following the correct table schema
|
||||
# Get the OS so we can run the insert in the apropriate
|
||||
# database and following the correct table schema
|
||||
osInfo = dm.getInfo("os")
|
||||
devOS = " ".join(osInfo['os'])
|
||||
|
||||
if ("pandaboard" in devOS):
|
||||
delete = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"]
|
||||
delete = [
|
||||
'execsu',
|
||||
'sqlite3',
|
||||
"/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"]
|
||||
else:
|
||||
delete = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"]
|
||||
delete = [
|
||||
'execsu',
|
||||
'sqlite3',
|
||||
"/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"]
|
||||
if (options.dm_trans == "sut"):
|
||||
dm._runCmds([{"cmd": " ".join(delete)}])
|
||||
|
||||
# Insert the bookmarks
|
||||
log.info("Insert bookmarks in the default android browser database")
|
||||
log.info(
|
||||
"Insert bookmarks in the default android browser database")
|
||||
for i in range(20):
|
||||
if ("pandaboard" in devOS):
|
||||
cmd = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db 'insert or replace into bookmarks(_id,title,url,folder,parent,position) values (" + str(30 + i) + ",\"Bookmark"+ str(i) + "\",\"http://www.bookmark" + str(i) + ".com\",0,1," + str(100 + i) + ");'"]
|
||||
else:
|
||||
cmd = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db 'insert into bookmarks(title,url,bookmark) values (\"Bookmark"+ str(i) + "\",\"http://www.bookmark" + str(i) + ".com\",1);'"]
|
||||
if (options.dm_trans == "sut"):
|
||||
dm._runCmds([{"cmd": " ".join(cmd)}])
|
||||
if ("pandaboard" in devOS):
|
||||
cmd = [
|
||||
'execsu',
|
||||
'sqlite3',
|
||||
"/data/data/com.android.browser/databases/browser2.db 'insert or replace into bookmarks(_id,title,url,folder,parent,position) values (" +
|
||||
str(
|
||||
30 +
|
||||
i) +
|
||||
",\"Bookmark" +
|
||||
str(i) +
|
||||
"\",\"http://www.bookmark" +
|
||||
str(i) +
|
||||
".com\",0,1," +
|
||||
str(
|
||||
100 +
|
||||
i) +
|
||||
");'"]
|
||||
else:
|
||||
cmd = [
|
||||
'execsu',
|
||||
'sqlite3',
|
||||
"/data/data/com.android.browser/databases/browser.db 'insert into bookmarks(title,url,bookmark) values (\"Bookmark" +
|
||||
str(i) +
|
||||
"\",\"http://www.bookmark" +
|
||||
str(i) +
|
||||
".com\",1);'"]
|
||||
if (options.dm_trans == "sut"):
|
||||
dm._runCmds([{"cmd": " ".join(cmd)}])
|
||||
try:
|
||||
screenShotDir = "/mnt/sdcard/Robotium-Screenshots"
|
||||
dm.removeDir(screenShotDir)
|
||||
|
@ -761,11 +930,13 @@ def main(args):
|
|||
if result != 0 or log_result != 0:
|
||||
mochitest.printDeviceInfo(printLogcat=True)
|
||||
mochitest.printScreenshots(screenShotDir)
|
||||
# Ensure earlier failures aren't overwritten by success on this run
|
||||
# Ensure earlier failures aren't overwritten by success on this
|
||||
# run
|
||||
if retVal is None or retVal == 0:
|
||||
retVal = result
|
||||
except:
|
||||
log.error("Automation Error: Exception caught while running tests")
|
||||
log.error(
|
||||
"Automation Error: Exception caught while running tests")
|
||||
traceback.print_exc()
|
||||
mochitest.stopServers()
|
||||
try:
|
||||
|
@ -779,9 +950,15 @@ def main(args):
|
|||
# Clean-up added bookmarks
|
||||
if test['name'] == "testImportFromAndroid":
|
||||
if ("pandaboard" in devOS):
|
||||
cmd_del = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"]
|
||||
cmd_del = [
|
||||
'execsu',
|
||||
'sqlite3',
|
||||
"/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"]
|
||||
else:
|
||||
cmd_del = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"]
|
||||
cmd_del = [
|
||||
'execsu',
|
||||
'sqlite3',
|
||||
"/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"]
|
||||
if (options.dm_trans == "sut"):
|
||||
dm._runCmds([{"cmd": " ".join(cmd_del)}])
|
||||
if retVal is None:
|
||||
|
|
Загрузка…
Ссылка в новой задаче