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
This commit is contained in:
Andrew Halberstadt
2015-02-13 14:42:02 -05:00
parent e51d78c17d
commit a729c1fa7d
6 changed files with 3299 additions and 2464 deletions

View File

@@ -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
@@ -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):

View File

@@ -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
@@ -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?')
@@ -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
@@ -332,8 +395,11 @@ class MochitestRunner(MozbuildObject):
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,7 +407,10 @@ 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 '
@@ -352,7 +421,8 @@ class MochitestRunner(MozbuildObject):
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,11 +510,15 @@ 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)
@@ -439,21 +526,33 @@ def MochitestCommand(func):
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)
@@ -461,9 +560,11 @@ def MochitestCommand(func):
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 ' \
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)
@@ -471,28 +572,40 @@ def MochitestCommand(func):
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. ' \
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)
@@ -501,19 +614,27 @@ def MochitestCommand(func):
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)
@@ -521,7 +642,9 @@ def MochitestCommand(func):
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)
@@ -529,65 +652,92 @@ def MochitestCommand(func):
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 ' \
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. ' \
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',
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,
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,
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,
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)
@@ -605,7 +755,10 @@ def B2GCommand(func):
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)
@@ -613,22 +766,31 @@ def B2GCommand(func):
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 ' \
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)
@@ -636,9 +798,11 @@ def B2GCommand(func):
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 ' \
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)
@@ -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
@@ -696,8 +874,11 @@ class MachCommands(MachCommandBase):
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
@@ -712,16 +893,22 @@ class MachCommands(MachCommandBase):
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
@@ -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,
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))
print(
ENG_BUILD_REQUIRED %
('mochitest-remote', host_webapps_dir))
return 1
from mozbuild.controller.building import BuildDriver
@@ -847,8 +1052,11 @@ 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.',
@@ -857,12 +1065,16 @@ class B2GCommands(MachCommandBase):
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,16 +1098,23 @@ 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='?',
@CommandArgument(
'test_path',
default=None,
nargs='?',
metavar='TEST',
help='Test to run. Can be specified as a Robocop test name (like "testLoad"), ' \
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:
@@ -904,13 +1123,27 @@ class AndroidCommands(MachCommandBase):
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=-',
]

View File

@@ -23,7 +23,9 @@ __all__ = ["MochitestOptions", "B2GOptions"]
VMWARE_RECORDING_HELPER_BASENAME = "vmwarerecordinghelper"
class MochitestOptions(optparse.OptionParser):
"""Usage instructions for runtests.py.
All arguments are optional.
If --chrome is specified, chrome tests will be run instead of web content tests.
@@ -35,76 +37,76 @@ class MochitestOptions(optparse.OptionParser):
LEVEL_STRING = ", ".join(LOG_LEVELS)
mochitest_options = [
[["--close-when-done"],
{ "action": "store_true",
{"action": "store_true",
"dest": "closeWhenDone",
"default": False,
"help": "close the application when tests are done running",
}],
[["--appname"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "app",
"default": None,
"help": "absolute path to application, overriding default",
}],
[["--utility-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "utilityPath",
"default": build_obj.bindir if build_obj is not None else None,
"help": "absolute path to directory containing utility programs (xpcshell, ssltunnel, certutil)",
}],
[["--certificate-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "certPath",
"help": "absolute path to directory containing certificate store to use testing profile",
"default": os.path.join(build_obj.topsrcdir, 'build', 'pgo', 'certs') if build_obj is not None else None,
}],
[["--autorun"],
{ "action": "store_true",
{"action": "store_true",
"dest": "autorun",
"help": "start running tests when the application starts",
"default": False,
}],
[["--timeout"],
{ "type": "int",
{"type": "int",
"dest": "timeout",
"help": "per-test timeout in seconds",
"default": None,
}],
[["--total-chunks"],
{ "type": "int",
{"type": "int",
"dest": "totalChunks",
"help": "how many chunks to split the tests up into",
"default": None,
}],
[["--this-chunk"],
{ "type": "int",
{"type": "int",
"dest": "thisChunk",
"help": "which chunk to run",
"default": None,
}],
[["--chunk-by-dir"],
{ "type": "int",
{"type": "int",
"dest": "chunkByDir",
"help": "group tests together in the same chunk that are in the same top chunkByDir directories",
"default": 0,
}],
[["--run-by-dir"],
{ "action": "store_true",
{"action": "store_true",
"dest": "runByDir",
"help": "Run each directory in a single browser instance with a fresh profile",
"default": False,
}],
[["--shuffle"],
{ "dest": "shuffle",
{"dest": "shuffle",
"action": "store_true",
"help": "randomize test order",
"default": False,
}],
[["--console-level"],
{ "action": "store",
{"action": "store",
"type": "choice",
"dest": "consoleLevel",
"choices": LOG_LEVELS,
@@ -114,89 +116,89 @@ class MochitestOptions(optparse.OptionParser):
"default": None,
}],
[["--chrome"],
{ "action": "store_true",
{"action": "store_true",
"dest": "chrome",
"help": "run chrome Mochitests",
"default": False,
}],
[["--ipcplugins"],
{ "action": "store_true",
{"action": "store_true",
"dest": "ipcplugins",
"help": "run ipcplugins Mochitests",
"default": False,
}],
[["--test-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "testPath",
"help": "start in the given directory's tests",
"default": "",
}],
[["--bisect-chunk"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "bisectChunk",
"help": "Specify the failing test name to find the previous tests that may be causing the failure.",
"default": None,
}],
[["--start-at"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "startAt",
"help": "skip over tests until reaching the given test",
"default": "",
}],
[["--end-at"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "endAt",
"help": "don't run any tests after the given one",
"default": "",
}],
[["--browser-chrome"],
{ "action": "store_true",
{"action": "store_true",
"dest": "browserChrome",
"help": "run browser chrome Mochitests",
"default": False,
}],
[["--subsuite"],
{ "action": "store",
{"action": "store",
"dest": "subsuite",
"help": "subsuite of tests to run",
"default": None,
}],
[["--jetpack-package"],
{ "action": "store_true",
{"action": "store_true",
"dest": "jetpackPackage",
"help": "run jetpack package tests",
"default": False,
}],
[["--jetpack-addon"],
{ "action": "store_true",
{"action": "store_true",
"dest": "jetpackAddon",
"help": "run jetpack addon tests",
"default": False,
}],
[["--webapprt-content"],
{ "action": "store_true",
{"action": "store_true",
"dest": "webapprtContent",
"help": "run WebappRT content tests",
"default": False,
}],
[["--webapprt-chrome"],
{ "action": "store_true",
{"action": "store_true",
"dest": "webapprtChrome",
"help": "run WebappRT chrome tests",
"default": False,
}],
[["--a11y"],
{ "action": "store_true",
{"action": "store_true",
"dest": "a11y",
"help": "run accessibility Mochitests",
"default": False,
}],
[["--setenv"],
{ "action": "append",
{"action": "append",
"type": "string",
"dest": "environment",
"metavar": "NAME=VALUE",
@@ -205,7 +207,7 @@ class MochitestOptions(optparse.OptionParser):
"default": [],
}],
[["--exclude-extension"],
{ "action": "append",
{"action": "append",
"type": "string",
"dest": "extensionsToExclude",
"help": "excludes the given extension from being installed "
@@ -213,7 +215,7 @@ class MochitestOptions(optparse.OptionParser):
"default": [],
}],
[["--browser-arg"],
{ "action": "append",
{"action": "append",
"type": "string",
"dest": "browserArgs",
"metavar": "ARG",
@@ -221,7 +223,7 @@ class MochitestOptions(optparse.OptionParser):
"default": [],
}],
[["--leak-threshold"],
{ "action": "store",
{"action": "store",
"type": "int",
"dest": "defaultLeakThreshold",
"metavar": "THRESHOLD",
@@ -232,20 +234,20 @@ class MochitestOptions(optparse.OptionParser):
"default": 0,
}],
[["--fatal-assertions"],
{ "action": "store_true",
{"action": "store_true",
"dest": "fatalAssertions",
"help": "abort testing whenever an assertion is hit "
"(requires a debug build to be effective)",
"default": False,
}],
[["--extra-profile-file"],
{ "action": "append",
{"action": "append",
"dest": "extraProfileFiles",
"help": "copy specified files/dirs to testing profile",
"default": [],
}],
[["--install-extension"],
{ "action": "append",
{"action": "append",
"dest": "extensionsToInstall",
"help": "install the specified extension in the testing profile."
"The extension file's name should be <id>.xpi where <id> is"
@@ -254,7 +256,7 @@ class MochitestOptions(optparse.OptionParser):
"default": [],
}],
[["--profile-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "profilePath",
"help": "Directory where the profile will be stored."
@@ -262,21 +264,21 @@ class MochitestOptions(optparse.OptionParser):
"default": None,
}],
[["--testing-modules-dir"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "testingModulesDir",
"help": "Directory where testing-only JS modules are located.",
"default": None,
}],
[["--use-vmware-recording"],
{ "action": "store_true",
{"action": "store_true",
"dest": "vmwareRecording",
"help": "enables recording while the application is running "
"inside a VMware Workstation 7.0 or later VM",
"default": False,
}],
[["--repeat"],
{ "action": "store",
{"action": "store",
"type": "int",
"dest": "repeat",
"metavar": "REPEAT",
@@ -284,68 +286,68 @@ class MochitestOptions(optparse.OptionParser):
"default": 0,
}],
[["--run-until-failure"],
{ "action": "store_true",
{"action": "store_true",
"dest": "runUntilFailure",
"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.",
"default": False,
}],
[["--run-only-tests"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "runOnlyTests",
"help": "JSON list of tests that we only want to run. [DEPRECATED- please use --test-manifest]",
"default": None,
}],
[["--test-manifest"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "testManifest",
"help": "JSON list of tests to specify 'runtests'. Old format for mobile specific tests",
"default": None,
}],
[["--manifest"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "manifestFile",
"help": ".ini format of tests to run.",
"default": None,
}],
[["--testrun-manifest-file"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "testRunManifestFile",
"help": "Overrides the default filename of the tests.json manifest file that is created from the manifest and used by the test runners to run the tests. Only useful when running multiple test runs simulatenously on the same machine.",
"default": 'tests.json',
}],
[["--failure-file"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "failureFile",
"help": "Filename of the output file where we can store a .json list of failures to be run in the future with --run-only-tests.",
"default": None,
}],
[["--run-slower"],
{ "action": "store_true",
{"action": "store_true",
"dest": "runSlower",
"help": "Delay execution between test files.",
"default": False,
}],
[["--metro-immersive"],
{ "action": "store_true",
{"action": "store_true",
"dest": "immersiveMode",
"help": "launches tests in immersive browser",
"default": False,
}],
[["--httpd-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "httpdPath",
"default": None,
"help": "path to the httpd.js file",
}],
[["--setpref"],
{ "action": "append",
{"action": "append",
"type": "string",
"default": [],
"dest": "extraPrefs",
@@ -353,63 +355,63 @@ class MochitestOptions(optparse.OptionParser):
"help": "defines an extra user preference",
}],
[["--jsdebugger"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "jsdebugger",
"help": "open the browser debugger",
}],
[["--debug-on-failure"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "debugOnFailure",
"help": "breaks execution and enters the JS debugger on a test failure. Should be used together with --jsdebugger."
}],
[["--e10s"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "e10s",
"help": "Run tests with electrolysis preferences and test filtering enabled.",
}],
[["--strict-content-sandbox"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "strictContentSandbox",
"help": "Run tests with a more strict content sandbox (Windows only).",
}],
[["--nested_oop"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "nested_oop",
"help": "Run tests with nested_oop preferences and test filtering enabled.",
}],
[["--dmd-path"],
{ "action": "store",
{"action": "store",
"default": None,
"dest": "dmdPath",
"help": "Specifies the path to the directory containing the shared library for DMD.",
}],
[["--dump-output-directory"],
{ "action": "store",
{"action": "store",
"default": None,
"dest": "dumpOutputDirectory",
"help": "Specifies the directory in which to place dumped memory reports.",
}],
[["--dump-about-memory-after-test"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "dumpAboutMemoryAfterTest",
"help": "Produce an about:memory dump after each test in the directory specified "
"by --dump-output-directory."
}],
[["--dump-dmd-after-test"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "dumpDMDAfterTest",
"help": "Produce a DMD dump after each test in the directory specified "
"by --dump-output-directory."
}],
[["--slowscript"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "slowscript",
"help": "Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; "
@@ -417,62 +419,62 @@ class MochitestOptions(optparse.OptionParser):
"may occur in Ion/Odin JIT code."
}],
[["--screenshot-on-fail"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "screenshotOnFail",
"help": "Take screenshots on all test failures. Set $MOZ_UPLOAD_DIR to a directory for storing the screenshots."
}],
[["--quiet"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "quiet",
"help": "Do not print test log lines unless a failure occurs."
}],
[["--pidfile"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "pidFile",
"help": "name of the pidfile to generate",
"default": "",
}],
[["--use-test-media-devices"],
{ "action": "store_true",
{"action": "store_true",
"default": False,
"dest": "useTestMediaDevices",
"help": "Use test media device drivers for media testing.",
}],
[["--gmp-path"],
{ "action": "store",
{"action": "store",
"default": None,
"dest": "gmp_path",
"help": "Path to fake GMP plugin. Will be deduced from the binary if not passed.",
}],
[["--xre-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "xrePath",
"default": None, # individual scripts will set a sane default
"help": "absolute path to directory containing XRE (probably xulrunner)",
}],
[["--symbols-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "symbolsPath",
"default": None,
"help": "absolute path to directory containing breakpad symbols, or the URL of a zip file containing symbols",
}],
[["--debugger"],
{ "action": "store",
{"action": "store",
"dest": "debugger",
"help": "use the given debugger to launch the application",
}],
[["--debugger-args"],
{ "action": "store",
{"action": "store",
"dest": "debuggerArgs",
"help": "pass the given args to the debugger _before_ the application on the command line",
}],
[["--debugger-interactive"],
{ "action": "store_true",
{"action": "store_true",
"dest": "debuggerInteractive",
"help": "prevents the test harness from redirecting stdout and stderr for interactive debuggers",
}],
@@ -493,17 +495,21 @@ class MochitestOptions(optparse.OptionParser):
""" verify correct options and cleanup paths """
mozinfo.update({"e10s": options.e10s}) # for test manifest parsing.
mozinfo.update({"strictContentSandbox": options.strictContentSandbox}) # for test manifest parsing.
mozinfo.update({"nested_oop": options.nested_oop}) # for test manifest parsing.
# for test manifest parsing.
mozinfo.update({"strictContentSandbox": options.strictContentSandbox})
# for test manifest parsing.
mozinfo.update({"nested_oop": options.nested_oop})
if options.app is None:
if build_obj is not None:
options.app = build_obj.get_binary_path()
else:
self.error("could not find the application path, --appname must be specified")
self.error(
"could not find the application path, --appname must be specified")
if options.totalChunks is not None and options.thisChunk is None:
self.error("thisChunk must be specified when totalChunks is specified")
self.error(
"thisChunk must be specified when totalChunks is specified")
if options.totalChunks:
if not 1 <= options.thisChunk <= options.totalChunks:
@@ -515,12 +521,16 @@ class MochitestOptions(optparse.OptionParser):
if options.app != self.defaults['app']:
options.xrePath = os.path.dirname(options.app)
if mozinfo.isMac:
options.xrePath = os.path.join(os.path.dirname(options.xrePath), "Resources")
options.xrePath = os.path.join(
os.path.dirname(
options.xrePath),
"Resources")
elif build_obj is not None:
# otherwise default to dist/bin
options.xrePath = build_obj.bindir
else:
self.error("could not find xre directory, --xre-path must be specified")
self.error(
"could not find xre directory, --xre-path must be specified")
# allow relative paths
options.xrePath = mochitest.getFullPath(options.xrePath)
@@ -543,7 +553,9 @@ class MochitestOptions(optparse.OptionParser):
if options.certPath:
options.certPath = mochitest.getFullPath(options.certPath)
if options.symbolsPath and len(urlparse(options.symbolsPath).scheme) < 2:
if options.symbolsPath and len(
urlparse(
options.symbolsPath).scheme) < 2:
options.symbolsPath = mochitest.getFullPath(options.symbolsPath)
# Set server information on the options object
@@ -551,14 +563,16 @@ class MochitestOptions(optparse.OptionParser):
options.httpPort = DEFAULT_PORTS['http']
options.sslPort = DEFAULT_PORTS['https']
# options.webSocketPort = DEFAULT_PORTS['ws']
options.webSocketPort = str(9988) # <- http://hg.mozilla.org/mozilla-central/file/b871dfb2186f/build/automation.py.in#l30
# <- http://hg.mozilla.org/mozilla-central/file/b871dfb2186f/build/automation.py.in#l30
options.webSocketPort = str(9988)
# The default websocket port is incorrect in mozprofile; it is
# set to the SSL proxy setting. See:
# see https://bugzilla.mozilla.org/show_bug.cgi?id=916517
if options.vmwareRecording:
if not mozinfo.isWin:
self.error("use-vmware-recording is only supported on Windows.")
self.error(
"use-vmware-recording is only supported on Windows.")
mochitest.vmwareHelperPath = os.path.join(
options.utilityPath, VMWARE_RECORDING_HELPER_BASENAME + ".dll")
if not os.path.exists(mochitest.vmwareHelperPath):
@@ -566,20 +580,29 @@ class MochitestOptions(optparse.OptionParser):
mochitest.vmwareHelperPath)
if options.testManifest and options.runOnlyTests:
self.error("Please use --test-manifest only and not --run-only-tests")
self.error(
"Please use --test-manifest only and not --run-only-tests")
if options.runOnlyTests:
if not os.path.exists(os.path.abspath(os.path.join(here, options.runOnlyTests))):
self.error("unable to find --run-only-tests file '%s'" % options.runOnlyTests)
if not os.path.exists(
os.path.abspath(
os.path.join(
here,
options.runOnlyTests))):
self.error(
"unable to find --run-only-tests file '%s'" %
options.runOnlyTests)
options.runOnly = True
options.testManifest = options.runOnlyTests
options.runOnlyTests = None
if options.manifestFile and options.testManifest:
self.error("Unable to support both --manifest and --test-manifest/--run-only-tests at the same time")
self.error(
"Unable to support both --manifest and --test-manifest/--run-only-tests at the same time")
if options.webapprtContent and options.webapprtChrome:
self.error("Only one of --webapprt-content and --webapprt-chrome may be given.")
self.error(
"Only one of --webapprt-content and --webapprt-chrome may be given.")
if options.jsdebugger:
options.extraPrefs += [
@@ -591,7 +614,8 @@ class MochitestOptions(optparse.OptionParser):
options.autorun = False
if options.debugOnFailure and not options.jsdebugger:
self.error("--debug-on-failure should be used together with --jsdebugger.")
self.error(
"--debug-on-failure should be used together with --jsdebugger.")
# Try to guess the testing modules directory.
# This somewhat grotesque hack allows the buildbot machines to find the
@@ -608,16 +632,20 @@ class MochitestOptions(optparse.OptionParser):
# Even if buildbot is updated, we still want this, as the path we pass in
# to the app must be absolute and have proper slashes.
if options.testingModulesDir is not None:
options.testingModulesDir = os.path.normpath(options.testingModulesDir)
options.testingModulesDir = os.path.normpath(
options.testingModulesDir)
if not os.path.isabs(options.testingModulesDir):
options.testingModulesDir = os.path.abspath(options.testingModulesDir)
options.testingModulesDir = os.path.abspath(
options.testingModulesDir)
if not os.path.isdir(options.testingModulesDir):
self.error('--testing-modules-dir not a directory: %s' %
options.testingModulesDir)
options.testingModulesDir = options.testingModulesDir.replace('\\', '/')
options.testingModulesDir = options.testingModulesDir.replace(
'\\',
'/')
if options.testingModulesDir[-1] != '/':
options.testingModulesDir += '/'
@@ -644,10 +672,12 @@ class MochitestOptions(optparse.OptionParser):
if options.useTestMediaDevices:
if not mozinfo.isLinux:
self.error('--use-test-media-devices is only supported on Linux currently')
self.error(
'--use-test-media-devices is only supported on Linux currently')
for f in ['/usr/bin/gst-launch-0.10', '/usr/bin/pactl']:
if not os.path.isfile(f):
self.error('Missing binary %s required for --use-test-media-devices')
self.error(
'Missing binary %s required for --use-test-media-devices')
if options.nested_oop:
if not options.e10s:
@@ -656,13 +686,16 @@ class MochitestOptions(optparse.OptionParser):
options.leakThresholds = {
"default": options.defaultLeakThreshold,
"tab": 25000, # See dependencies of bug 1051230.
"geckomediaplugin": 20000, # GMP rarely gets a log, but when it does, it leaks a little.
# GMP rarely gets a log, but when it does, it leaks a little.
"geckomediaplugin": 20000,
}
# Bug 1065098 - The geckomediaplugin process fails to produce a leak log for some reason.
# Bug 1065098 - The geckomediaplugin process fails to produce a leak
# log for some reason.
options.ignoreMissingLeaks = ["geckomediaplugin"]
# Bug 1091917 - We exit early in tab processes on Windows, so we don't get leak logs yet.
# Bug 1091917 - We exit early in tab processes on Windows, so we don't
# get leak logs yet.
if mozinfo.isWin:
options.ignoreMissingLeaks.append("tab")
@@ -676,104 +709,104 @@ class MochitestOptions(optparse.OptionParser):
class B2GOptions(MochitestOptions):
b2g_options = [
[["--b2gpath"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "b2gPath",
"help": "path to B2G repo or qemu dir",
"default": None,
}],
[["--desktop"],
{ "action": "store_true",
{"action": "store_true",
"dest": "desktop",
"help": "Run the tests on a B2G desktop build",
"default": False,
}],
[["--marionette"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "marionette",
"help": "host:port to use when connecting to Marionette",
"default": None,
}],
[["--emulator"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "emulator",
"help": "Architecture of emulator to use: x86 or arm",
"default": None,
}],
[["--wifi"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "wifi",
"help": "Devine wifi configuration for on device mochitest",
"default": False,
}],
[["--sdcard"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "sdcard",
"help": "Define size of sdcard: 1MB, 50MB...etc",
"default": "10MB",
}],
[["--no-window"],
{ "action": "store_true",
{"action": "store_true",
"dest": "noWindow",
"help": "Pass --no-window to the emulator",
"default": False,
}],
[["--adbpath"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "adbPath",
"help": "path to adb",
"default": "adb",
}],
[["--deviceIP"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "deviceIP",
"help": "ip address of remote device to test",
"default": None,
}],
[["--devicePort"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "devicePort",
"help": "port of remote device to test",
"default": 20701,
}],
[["--remote-logfile"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "remoteLogFile",
"help": "Name of log file on the device relative to the device root. \
PLEASE ONLY USE A FILENAME.",
"default" : None,
"default": None,
}],
[["--remote-webserver"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "remoteWebServer",
"help": "ip address where the remote web server is hosted at",
"default": None,
}],
[["--http-port"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "httpPort",
"help": "ip address where the remote web server is hosted at",
"default": None,
}],
[["--ssl-port"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "sslPort",
"help": "ip address where the remote web server is hosted at",
"default": None,
}],
[["--gecko-path"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "geckoPath",
"help": "the path to a gecko distribution that should \
@@ -781,7 +814,7 @@ class B2GOptions(MochitestOptions):
"default": None,
}],
[["--profile"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "profile",
"help": "for desktop testing, the path to the \
@@ -789,21 +822,21 @@ class B2GOptions(MochitestOptions):
"default": None,
}],
[["--logdir"],
{ "action": "store",
{"action": "store",
"type": "string",
"dest": "logdir",
"help": "directory to store log files",
"default": None,
}],
[['--busybox'],
{ "action": 'store',
{"action": 'store',
"type": 'string',
"dest": 'busybox',
"help": "Path to busybox binary to install on device",
"default": None,
}],
[['--profile-data-dir'],
{ "action": 'store',
{"action": 'store',
"type": 'string',
"dest": 'profile_data_dir',
"help": "Path to a directory containing preference and other \
@@ -831,15 +864,17 @@ class B2GOptions(MochitestOptions):
self.set_defaults(**defaults)
def verifyRemoteOptions(self, options):
if options.remoteWebServer == None:
if options.remoteWebServer is None:
if os.name != "nt":
options.remoteWebServer = moznetwork.get_ip()
else:
self.error("You must specify a --remote-webserver=<ip address>")
self.error(
"You must specify a --remote-webserver=<ip address>")
options.webServer = options.remoteWebServer
if options.geckoPath and not options.emulator:
self.error("You must specify --emulator if you specify --gecko-path")
self.error(
"You must specify --emulator if you specify --gecko-path")
if options.logdir and not options.emulator:
self.error("You must specify --emulator if you specify --logdir")

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,7 @@ from mozprofile import Profile, Preferences
from mozlog import structured
import mozinfo
class B2GMochitest(MochitestUtilsMixin):
marionette = None
@@ -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,15 +218,19 @@ 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(),
self.marionette.execute_script(
script.read(),
script_args=self.test_script_args)
else:
self.marionette.execute_script(self.test_script,
self.marionette.execute_script(
self.test_script,
script_args=self.test_script_args)
status = self.runner.wait()
@@ -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)

View File

@@ -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:
@@ -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,8 +389,10 @@ 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)
@@ -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,32 +850,73 @@ 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) + ");'"]
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);'"]
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:
@@ -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: