2012-09-26 20:43:53 +04:00
# This Source Code Form is subject to the terms of the Mozilla Public
2012-10-10 22:08:09 +04:00
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
2012-09-26 20:43:53 +04:00
from __future__ import unicode_literals
2014-08-13 20:03:00 +04:00
import argparse
2013-04-05 02:17:23 +04:00
import logging
2013-03-28 20:23:03 +04:00
import mozpack . path
2012-10-03 01:03:31 +04:00
import os
2013-03-27 02:00:43 +04:00
import sys
2013-09-19 22:43:44 +04:00
import warnings
2013-08-29 22:23:07 +04:00
import which
2012-10-03 01:03:31 +04:00
2012-11-07 04:57:41 +04:00
from mozbuild . base import (
MachCommandBase ,
2013-08-28 18:08:50 +04:00
MachCommandConditions as conditions ,
2012-11-07 04:57:41 +04:00
MozbuildObject ,
)
2012-10-10 22:08:09 +04:00
2012-11-07 04:57:41 +04:00
from mach . decorators import (
2012-10-10 22:08:09 +04:00
CommandArgument ,
CommandProvider ,
Command ,
)
2013-04-05 02:17:23 +04:00
2014-08-13 20:03:00 +04:00
from mozlog import structured
2013-09-19 22:43:44 +04:00
ADB_NOT_FOUND = '''
The % s command requires the adb binary to be on your path .
If you have a B2G build , this can be found in
' %s /out/host/<platform>/bin ' .
''' .lstrip()
GAIA_PROFILE_NOT_FOUND = '''
The % s command requires a non - debug gaia profile . Either pass in - - profile ,
or set the GAIA_PROFILE environment variable .
If you do not have a non - debug gaia profile , you can build one :
$ git clone https : / / github . com / mozilla - b2g / gaia
$ cd gaia
$ make
The profile should be generated in a directory called ' profile ' .
''' .lstrip()
GAIA_PROFILE_IS_DEBUG = '''
The % s command requires a non - debug gaia profile . The specified profile ,
% s , is a debug profile .
If you do not have a non - debug gaia profile , you can build one :
$ git clone https : / / github . com / mozilla - b2g / gaia
$ cd gaia
$ make
The profile should be generated in a directory called ' profile ' .
''' .lstrip()
2014-07-17 21:38:20 +04:00
ENG_BUILD_REQUIRED = '''
The % s command requires an engineering build . It may be the case that
VARIANT = user or PRODUCTION = 1 were set . Try re - building with VARIANT = eng :
$ VARIANT = eng . / build . sh
There should be an app called ' test-container.gaiamobile.org ' located in
% s .
''' .lstrip()
2014-06-18 02:42:08 +04:00
# Maps test flavors to mochitest suite type.
FLAVORS = {
' mochitest ' : ' plain ' ,
' chrome ' : ' chrome ' ,
' browser-chrome ' : ' browser ' ,
2014-09-22 22:08:06 +04:00
' jetpack-package ' : ' jetpack-package ' ,
' jetpack-addon ' : ' jetpack-addon ' ,
2014-06-18 02:42:08 +04:00
' a11y ' : ' a11y ' ,
' webapprt-chrome ' : ' webapprt-chrome ' ,
}
2013-04-05 02:17:23 +04:00
2012-10-10 22:08:09 +04:00
2012-10-10 22:08:09 +04:00
class MochitestRunner ( MozbuildObject ) :
2015-02-13 22:42:02 +03:00
2012-09-26 20:43:53 +04:00
""" Easily run mochitests.
This currently contains just the basics for running mochitests . We may want
to hook up result parsing , etc .
"""
2013-08-28 18:08:50 +04:00
2013-09-23 18:47:48 +04:00
def get_webapp_runtime_path ( self ) :
2013-09-25 00:44:23 +04:00
import mozinfo
2013-09-23 18:47:48 +04:00
appname = ' webapprt-stub ' + mozinfo . info . get ( ' bin_suffix ' , ' ' )
if sys . platform . startswith ( ' darwin ' ) :
2015-02-13 22:42:02 +03:00
appname = os . path . join (
self . distdir ,
self . substs [ ' MOZ_MACBUNDLE_NAME ' ] ,
' Contents ' ,
' Resources ' ,
appname )
2013-09-23 18:47:48 +04:00
else :
appname = os . path . join ( self . distdir , ' bin ' , appname )
return appname
2013-08-28 18:08:50 +04:00
def __init__ ( self , * args , * * kwargs ) :
MozbuildObject . __init__ ( self , * args , * * kwargs )
# TODO Bug 794506 remove once mach integrates with virtualenv.
build_path = os . path . join ( self . topobjdir , ' build ' )
if build_path not in sys . path :
sys . path . append ( build_path )
self . tests_dir = os . path . join ( self . topobjdir , ' _tests ' )
2015-02-13 22:42:02 +03:00
self . mochitest_dir = os . path . join (
self . tests_dir ,
' testing ' ,
' mochitest ' )
2014-01-16 21:23:32 +04:00
self . bin_dir = os . path . join ( self . topobjdir , ' dist ' , ' bin ' )
2013-08-28 18:08:50 +04:00
2015-02-13 22:42:02 +03:00
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 ) :
2013-08-28 18:08:50 +04:00
""" Runs a b2g mochitest.
2014-03-25 03:19:57 +04:00
test_paths is an enumerable of paths to tests . It can be a relative path
from the top source directory , an absolute filename , or a directory
containing test files .
2013-08-28 18:08:50 +04:00
"""
2013-09-11 22:53:47 +04:00
# Need to call relpath before os.chdir() below.
test_path = ' '
2014-03-25 03:19:57 +04:00
if test_paths :
if len ( test_paths ) > 1 :
print ( ' Warning: Only the first test path will be used. ' )
test_path = self . _wrap_path_argument ( test_paths [ 0 ] ) . relpath ( )
2013-09-11 22:53:47 +04:00
2013-08-28 18:08:50 +04:00
# TODO without os.chdir, chained imports fail below
os . chdir ( self . mochitest_dir )
2013-09-19 22:43:44 +04:00
# The imp module can spew warnings if the modules below have
# already been imported, ignore them.
with warnings . catch_warnings ( ) :
warnings . simplefilter ( ' ignore ' )
2013-08-28 18:08:50 +04:00
2013-09-19 22:43:44 +04:00
import imp
path = os . path . join ( self . mochitest_dir , ' runtestsb2g.py ' )
with open ( path , ' r ' ) as fh :
imp . load_module ( ' mochitest ' , fh , path ,
2015-02-13 22:42:02 +03:00
( ' .py ' , ' r ' , imp . PY_SOURCE ) )
2013-09-19 22:43:44 +04:00
import mochitest
from mochitest_options import B2GOptions
2013-08-28 18:08:50 +04:00
parser = B2GOptions ( )
options = parser . parse_args ( [ ] ) [ 0 ]
2013-09-11 22:53:47 +04:00
if test_path :
2014-12-24 00:17:39 +03:00
if chrome :
2015-02-13 22:42:02 +03:00
test_root_file = mozpack . path . join (
self . mochitest_dir ,
' chrome ' ,
test_path )
2014-12-24 00:17:39 +03:00
else :
2015-02-13 22:42:02 +03:00
test_root_file = mozpack . path . join (
self . mochitest_dir ,
' tests ' ,
test_path )
2013-09-11 22:53:47 +04:00
if not os . path . exists ( test_root_file ) :
2015-02-13 22:42:02 +03:00
print (
' Specified test path does not exist: %s ' %
test_root_file )
2013-09-11 22:53:47 +04:00
return 1
options . testPath = test_path
2014-02-11 00:58:46 +04:00
2013-08-28 18:08:50 +04:00
for k , v in kwargs . iteritems ( ) :
setattr ( options , k , v )
2013-11-25 18:12:50 +04:00
options . noWindow = no_window
options . totalChunks = total_chunks
options . thisChunk = this_chunk
2014-08-05 07:29:00 +04:00
options . repeat = repeat
options . runUntilFailure = run_until_failure
2013-08-28 18:08:50 +04:00
2015-02-13 22:42:02 +03:00
options . symbolsPath = os . path . join (
self . distdir ,
' crashreporter-symbols ' )
2013-11-27 02:25:25 +04:00
2013-09-19 22:43:44 +04:00
options . consoleLevel = ' INFO '
if conditions . is_b2g_desktop ( self ) :
options . desktop = True
options . app = self . get_binary_path ( )
if not options . app . endswith ( ' -bin ' ) :
options . app = ' %s -bin ' % options . app
if not os . path . isfile ( options . app ) :
options . app = options . app [ : - len ( ' -bin ' ) ]
return mochitest . run_desktop_mochitests ( parser , options )
try :
which . which ( ' adb ' )
except which . WhichError :
# TODO Find adb automatically if it isn't on the path
print ( ADB_NOT_FOUND % ( ' mochitest-remote ' , b2g_home ) )
return 1
options . b2gPath = b2g_home
2014-06-19 22:17:26 +04:00
options . logdir = self . mochitest_dir
2013-09-19 22:43:44 +04:00
options . httpdPath = self . mochitest_dir
options . xrePath = xre_path
2014-12-24 00:17:39 +03:00
options . chrome = chrome
2013-09-19 22:43:44 +04:00
return mochitest . run_remote_mochitests ( parser , options )
2013-08-28 18:08:50 +04:00
2015-02-13 22:42:02 +03:00
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 ) :
2012-09-26 20:43:53 +04:00
""" Runs a mochitest.
2014-03-25 03:19:57 +04:00
test_paths are path to tests . They can be a relative path from the
2012-09-26 20:43:53 +04:00
top source directory , an absolute filename , or a directory containing
test files .
suite is the type of mochitest to run . It can be one of ( ' plain ' ,
2014-09-22 22:08:06 +04:00
' chrome ' , ' browser ' , ' metro ' , ' a11y ' , ' jetpack-package ' , ' jetpack-addon ' ) .
2012-12-06 02:27:54 +04:00
debugger is a program name or path to a binary ( presumably a debugger )
to run the test in . e . g . ' gdb '
2013-03-27 02:00:43 +04:00
2013-05-30 19:00:46 +04:00
debugger_args are the arguments passed to the debugger .
2014-02-08 08:25:45 +04:00
slowscript is true if the user has requested the SIGSEGV mechanism of
invoking the slow script dialog .
2013-03-27 02:00:43 +04:00
shuffle is whether test order should be shuffled ( defaults to false ) .
2014-09-11 18:29:57 +04:00
closure_behaviour denotes whether to keep the browser open after tests
2013-03-27 02:00:43 +04:00
complete .
2012-09-26 20:43:53 +04:00
"""
2014-03-25 03:19:57 +04:00
if rerun_failures and test_paths :
2013-03-27 02:00:43 +04:00
print ( ' Cannot specify both --rerun-failures and a test path. ' )
return 1
2014-09-03 15:06:00 +04:00
# Make absolute paths relative before calling os.chdir() below.
2014-03-25 03:19:57 +04:00
if test_paths :
2015-02-13 22:42:02 +03:00
test_paths = [ self . _wrap_path_argument (
p ) . relpath ( ) if os . path . isabs ( p ) else p for p in test_paths ]
2013-03-27 02:00:43 +04:00
2015-02-13 22:42:02 +03:00
failure_file_path = os . path . join (
self . statedir ,
' mochitest_failures.json ' )
2013-03-27 02:00:43 +04:00
if rerun_failures and not os . path . exists ( failure_file_path ) :
print ( ' No failure file present. Did you run mochitests before? ' )
return 1
# runtests.py is ambiguous, so we load the file/module manually.
if ' mochitest ' not in sys . modules :
import imp
2013-08-28 18:08:50 +04:00
path = os . path . join ( self . mochitest_dir , ' runtests.py ' )
2013-03-27 02:00:43 +04:00
with open ( path , ' r ' ) as fh :
imp . load_module ( ' mochitest ' , fh , path ,
2015-02-13 22:42:02 +03:00
( ' .py ' , ' r ' , imp . PY_SOURCE ) )
2013-03-27 02:00:43 +04:00
import mochitest
2014-03-25 01:35:06 +04:00
from manifestparser import TestManifest
from mozbuild . testing import TestResolver
2013-03-27 02:00:43 +04:00
# This is required to make other components happy. Sad, isn't it?
os . chdir ( self . topobjdir )
2013-04-05 02:17:23 +04:00
# Automation installs its own stream handler to stdout. Since we want
# all logging to go through us, we just remove their handler.
remove_handlers = [ l for l in logging . getLogger ( ) . handlers
2015-02-13 22:42:02 +03:00
if isinstance ( l , logging . StreamHandler ) ]
2013-04-05 02:17:23 +04:00
for handler in remove_handlers :
logging . getLogger ( ) . removeHandler ( handler )
2013-09-23 18:47:48 +04:00
opts = mochitest . MochitestOptions ( )
2013-03-27 02:00:43 +04:00
options , args = opts . parse_args ( [ ] )
2014-03-25 20:52:53 +04:00
options . subsuite = ' '
2014-03-25 01:35:06 +04:00
flavor = suite
2013-08-23 18:06:16 +04:00
2013-03-28 20:23:03 +04:00
# Need to set the suite options before verifyOptions below.
if suite == ' plain ' :
# Don't need additional options for plain.
2014-03-25 01:35:06 +04:00
flavor = ' mochitest '
2013-03-28 20:23:03 +04:00
elif suite == ' chrome ' :
options . chrome = True
elif suite == ' browser ' :
options . browserChrome = True
2014-03-25 01:35:06 +04:00
flavor = ' browser-chrome '
2014-03-25 20:52:53 +04:00
elif suite == ' devtools ' :
options . browserChrome = True
options . subsuite = ' devtools '
2014-09-22 22:08:06 +04:00
elif suite == ' jetpack-package ' :
options . jetpackPackage = True
elif suite == ' jetpack-addon ' :
options . jetpackAddon = True
2013-03-28 20:23:03 +04:00
elif suite == ' metro ' :
options . immersiveMode = True
options . browserChrome = True
elif suite == ' a11y ' :
options . a11y = True
2013-08-23 18:06:16 +04:00
elif suite == ' webapprt-content ' :
options . webapprtContent = True
2013-09-23 18:47:48 +04:00
options . app = self . get_webapp_runtime_path ( )
2013-08-23 18:06:16 +04:00
elif suite == ' webapprt-chrome ' :
options . webapprtChrome = True
2013-09-23 18:47:48 +04:00
options . app = self . get_webapp_runtime_path ( )
2013-08-23 18:06:16 +04:00
options . browserArgs . append ( " -test-mode " )
2013-03-28 20:23:03 +04:00
else :
raise Exception ( ' None or unrecognized mochitest suite type. ' )
2013-11-13 23:48:29 +04:00
if dmd :
2014-01-16 21:23:32 +04:00
options . dmdPath = self . bin_dir
2013-11-13 23:48:29 +04:00
2013-03-27 02:00:43 +04:00
options . autorun = not no_autorun
2014-09-11 18:29:57 +04:00
options . closeWhenDone = closure_behaviour != ' open '
2014-02-08 08:25:45 +04:00
options . slowscript = slowscript
2014-04-12 06:23:00 +04:00
options . screenshotOnFail = screenshot_on_fail
2013-03-27 02:00:43 +04:00
options . shuffle = shuffle
options . consoleLevel = ' INFO '
options . repeat = repeat
2013-05-24 23:03:50 +04:00
options . runUntilFailure = run_until_failure
2013-03-27 02:00:43 +04:00
options . runSlower = slow
2013-08-28 18:08:50 +04:00
options . testingModulesDir = os . path . join ( self . tests_dir , ' modules ' )
2013-03-27 02:00:43 +04:00
options . extraProfileFiles . append ( os . path . join ( self . distdir , ' plugins ' ) )
2015-02-13 22:42:02 +03:00
options . symbolsPath = os . path . join (
self . distdir ,
' crashreporter-symbols ' )
2013-09-09 23:36:03 +04:00
options . chunkByDir = chunk_by_dir
options . totalChunks = total_chunks
options . thisChunk = this_chunk
2013-10-21 20:12:12 +04:00
options . jsdebugger = jsdebugger
2013-11-01 23:23:34 +04:00
options . debugOnFailure = debug_on_failure
2013-10-28 23:24:55 +04:00
options . startAt = start_at
options . endAt = end_at
2013-11-04 03:07:49 +04:00
options . e10s = e10s
2014-12-10 12:34:03 +03:00
options . strictContentSandbox = strict_content_sandbox
2015-01-13 04:07:00 +03:00
options . nested_oop = nested_oop
2013-11-20 00:12:00 +04:00
options . dumpAboutMemoryAfterTest = dump_about_memory_after_test
options . dumpDMDAfterTest = dump_dmd_after_test
options . dumpOutputDirectory = dump_output_directory
2014-03-07 20:42:07 +04:00
options . quiet = quiet
2014-04-22 17:09:47 +04:00
options . environment = environment
2014-07-13 12:04:00 +04:00
options . extraPrefs = extraPrefs
2014-07-04 15:55:00 +04:00
options . bisectChunk = bisectChunk
2014-06-03 19:19:28 +04:00
options . runByDir = runByDir
2014-05-01 15:18:00 +04:00
options . useTestMediaDevices = useTestMediaDevices
2014-11-17 19:52:24 +03:00
if timeout :
2015-02-13 22:42:02 +03:00
options . timeout = int ( timeout )
2013-03-27 02:00:43 +04:00
options . failureFile = failure_file_path
2015-02-13 22:42:02 +03:00
if install_extension is not None :
options . extensionsToInstall = [
os . path . join (
self . topsrcdir ,
install_extension ) ]
2013-03-27 02:00:43 +04:00
2014-01-10 19:45:52 +04:00
for k , v in kwargs . iteritems ( ) :
setattr ( options , k , v )
2014-03-25 03:19:57 +04:00
if test_paths :
2014-03-25 01:35:06 +04:00
resolver = self . _spawn ( TestResolver )
2015-02-13 22:42:02 +03:00
tests = list (
resolver . resolve_tests (
paths = test_paths ,
flavor = flavor ) )
2014-03-25 01:35:06 +04:00
if not tests :
print ( ' No tests could be found in the path specified. Please '
2015-02-13 22:42:02 +03:00
' specify a path that is a test file or is a directory '
' containing tests. ' )
2013-03-28 20:23:03 +04:00
return 1
2014-03-25 01:35:06 +04:00
manifest = TestManifest ( )
manifest . tests . extend ( tests )
2015-02-13 22:42:02 +03:00
if len (
tests ) == 1 and closure_behaviour == ' auto ' and suite == ' plain ' :
2014-05-22 23:09:21 +04:00
options . closeWhenDone = False
2014-03-25 01:35:06 +04:00
options . manifestFile = manifest
2012-09-26 20:43:53 +04:00
2013-03-27 02:00:43 +04:00
if rerun_failures :
options . testManifest = failure_file_path
2012-12-06 02:27:54 +04:00
if debugger :
2013-03-27 02:00:43 +04:00
options . debugger = debugger
2013-05-30 19:00:46 +04:00
if debugger_args :
2015-02-13 22:42:02 +03:00
if options . debugger is None :
2013-05-30 19:00:46 +04:00
print ( " --debugger-args passed, but no debugger specified. " )
return 1
options . debuggerArgs = debugger_args
2014-08-22 18:28:04 +04:00
if app_override :
if app_override == " dist " :
options . app = self . get_binary_path ( where = ' staged-package ' )
elif app_override :
options . app = app_override
if options . gmp_path is None :
2015-02-13 22:42:02 +03:00
# Need to fix the location of gmp_fake which might not be
# shipped in the binary
2014-08-22 18:28:04 +04:00
bin_path = self . get_binary_path ( )
2015-02-13 22:42:02 +03:00
options . gmp_path = os . path . join (
os . path . dirname ( bin_path ) ,
' gmp-fake ' ,
' 1.0 ' )
2014-09-24 02:04:49 +04:00
options . gmp_path + = os . pathsep
2015-02-13 22:42:02 +03:00
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 ' ) }
2014-08-13 20:03:00 +04:00
runner = mochitest . Mochitest ( logger_options )
2013-05-24 23:03:50 +04:00
options = opts . verifyOptions ( options , runner )
if options is None :
raise Exception ( ' mochitest option validator failed. ' )
2013-04-05 02:17:23 +04:00
# We need this to enable colorization of output.
self . log_manager . enable_unstructured ( )
result = runner . runTests ( options )
self . log_manager . disable_unstructured ( )
2014-07-22 13:56:00 +04:00
if runner . message_logger . errors :
2013-05-23 21:13:54 +04:00
result = 1
2014-07-22 13:56:00 +04:00
runner . message_logger . logger . warning ( " The following tests failed: " )
for error in runner . message_logger . errors :
runner . message_logger . logger . log_raw ( error )
2013-04-05 02:17:23 +04:00
2014-07-29 16:11:00 +04:00
runner . message_logger . finish ( )
2013-04-05 02:17:23 +04:00
return result
2013-03-27 02:00:43 +04:00
def MochitestCommand ( func ) :
""" Decorator that adds shared command arguments to mochitest commands. """
2012-12-06 02:27:54 +04:00
2013-03-27 02:00:43 +04:00
# This employs light Python magic. Keep in mind a decorator is just a
# function that takes a function, does something with it, then returns a
# (modified) function. Here, we chain decorators onto the passed in
# function.
2015-02-13 22:42:02 +03:00
debugger = CommandArgument (
' --debugger ' ,
' -d ' ,
metavar = ' DEBUGGER ' ,
2013-03-27 02:00:43 +04:00
help = ' Debugger binary to run test in. Program name or path. ' )
func = debugger ( func )
2015-02-13 22:42:02 +03:00
debugger_args = CommandArgument (
' --debugger-args ' ,
metavar = ' DEBUGGER_ARGS ' ,
help = ' Arguments to pass to the debugger. ' )
2013-05-30 19:00:46 +04:00
func = debugger_args ( func )
2014-02-08 08:25:45 +04:00
# Bug 933807 introduced JS_DISABLE_SLOW_SCRIPT_SIGNALS to avoid clever
# segfaults induced by the slow-script-detecting logic for Ion/Odin JITted
# 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.
2015-02-13 22:42:02 +03:00
slowscript = CommandArgument (
' --slowscript ' ,
action = ' store_true ' ,
2014-02-08 08:25:45 +04:00
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 )
2015-02-13 22:42:02 +03:00
screenshot_on_fail = CommandArgument (
' --screenshot-on-fail ' ,
action = ' store_true ' ,
2014-04-12 06:23:00 +04:00
help = ' Take screenshots on all test failures. Set $MOZ_UPLOAD_DIR to a directory for storing the screenshots. ' )
func = screenshot_on_fail ( func )
2013-03-27 02:00:43 +04:00
shuffle = CommandArgument ( ' --shuffle ' , action = ' store_true ' ,
2015-02-13 22:42:02 +03:00
help = ' Shuffle execution order. ' )
2013-03-27 02:00:43 +04:00
func = shuffle ( func )
2015-02-13 22:42:02 +03:00
keep_open = CommandArgument (
' --keep-open ' ,
action = ' store_const ' ,
dest = ' closure_behaviour ' ,
const = ' open ' ,
default = ' auto ' ,
2014-09-11 18:29:57 +04:00
help = ' Always keep the browser open after tests complete. ' )
2013-03-27 02:00:43 +04:00
func = keep_open ( func )
2015-02-13 22:42:02 +03:00
autoclose = CommandArgument (
' --auto-close ' ,
action = ' store_const ' ,
dest = ' closure_behaviour ' ,
const = ' close ' ,
default = ' auto ' ,
2014-09-11 18:29:57 +04:00
help = ' Always close the browser after tests complete. ' )
func = autoclose ( func )
2015-02-13 22:42:02 +03:00
rerun = CommandArgument (
' --rerun-failures ' ,
action = ' store_true ' ,
2013-08-23 18:06:16 +04:00
help = ' Run only the tests that failed during the last test run. ' )
2013-03-27 02:00:43 +04:00
func = rerun ( func )
2015-02-13 22:42:02 +03:00
autorun = CommandArgument (
' --no-autorun ' ,
action = ' store_true ' ,
2013-03-27 02:00:43 +04:00
help = ' Do not starting running tests automatically. ' )
func = autorun ( func )
repeat = CommandArgument ( ' --repeat ' , type = int , default = 0 ,
2015-02-13 22:42:02 +03:00
help = ' Repeat the test the given number of times. ' )
2013-03-27 02:00:43 +04:00
func = repeat ( func )
2015-02-13 22:42:02 +03:00
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. ' )
2013-05-24 23:03:50 +04:00
func = runUntilFailure ( func )
2013-03-27 02:00:43 +04:00
slow = CommandArgument ( ' --slow ' , action = ' store_true ' ,
2015-02-13 22:42:02 +03:00
help = ' Delay execution between tests. ' )
2013-03-27 02:00:43 +04:00
func = slow ( func )
2015-02-13 22:42:02 +03:00
end_at = CommandArgument (
' --end-at ' ,
type = str ,
2013-11-01 23:23:32 +04:00
help = ' Stop running the test sequence at this test. ' )
func = end_at ( func )
2015-02-13 22:42:02 +03:00
start_at = CommandArgument (
' --start-at ' ,
type = str ,
2013-11-01 23:23:32 +04:00
help = ' Start running the test sequence at this test. ' )
func = start_at ( func )
2015-02-13 22:42:02 +03:00
chunk_dir = CommandArgument (
' --chunk-by-dir ' ,
type = int ,
2013-09-09 23:36:03 +04:00
help = ' Group tests together in chunks by this many top directories. ' )
func = chunk_dir ( func )
2015-02-13 22:42:02 +03:00
chunk_total = CommandArgument (
' --total-chunks ' ,
type = int ,
2013-09-09 23:36:03 +04:00
help = ' Total number of chunks to split tests into. ' )
func = chunk_total ( func )
2015-02-13 22:42:02 +03:00
this_chunk = CommandArgument (
' --this-chunk ' ,
type = int ,
2013-09-09 23:36:03 +04:00
help = ' If running tests by chunks, the number of the chunk to run. ' )
func = this_chunk ( func )
2015-02-13 22:42:02 +03:00
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. ' )
2013-11-01 23:23:34 +04:00
func = debug_on_failure ( func )
2014-07-13 12:04:00 +04:00
setpref = CommandArgument ( ' --setpref ' , default = [ ] , action = ' append ' ,
2015-02-13 22:42:02 +03:00
metavar = ' PREF=VALUE ' , dest = ' extraPrefs ' ,
help = ' defines an extra user preference ' )
2014-07-13 12:04:00 +04:00
func = setpref ( func )
2015-02-13 22:42:02 +03:00
jsdebugger = CommandArgument (
' --jsdebugger ' ,
action = ' store_true ' ,
2013-10-21 20:12:12 +04:00
help = ' Start the browser JS debugger before running the test. Implies --no-autorun. ' )
func = jsdebugger ( func )
2015-02-13 22:42:02 +03:00
e10s = CommandArgument (
' --e10s ' ,
action = ' store_true ' ,
2013-11-04 03:07:49 +04:00
help = ' Run tests with electrolysis preferences and test filtering enabled. ' )
2014-12-10 12:34:03 +03:00
func = e10s ( func )
2013-11-04 03:07:49 +04:00
2015-02-13 22:42:02 +03:00
strict_content_sandbox = CommandArgument (
' --strict-content-sandbox ' ,
action = ' store_true ' ,
2014-12-10 12:34:03 +03:00
help = ' Run tests with a more strict content sandbox (Windows only). ' )
func = strict_content_sandbox ( func )
2014-09-16 11:20:07 +04:00
2015-02-13 22:42:02 +03:00
this_chunk = CommandArgument (
' --nested_oop ' ,
action = ' store_true ' ,
2015-01-13 04:07:00 +03:00
help = ' Run tests with nested oop preferences and test filtering enabled. ' )
func = this_chunk ( func )
2013-11-13 23:48:29 +04:00
dmd = CommandArgument ( ' --dmd ' , action = ' store_true ' ,
2015-02-13 22:42:02 +03:00
help = ' Run tests with DMD active. ' )
2013-11-13 23:48:29 +04:00
func = dmd ( func )
2015-02-13 22:42:02 +03:00
dumpAboutMemory = CommandArgument (
' --dump-about-memory-after-test ' ,
action = ' store_true ' ,
2013-11-20 00:12:00 +04:00
help = ' Dump an about:memory log after every test. ' )
func = dumpAboutMemory ( func )
dumpDMD = CommandArgument ( ' --dump-dmd-after-test ' , action = ' store_true ' ,
2015-02-13 22:42:02 +03:00
help = ' Dump a DMD log after every test. ' )
2013-11-20 00:12:00 +04:00
func = dumpDMD ( func )
2015-02-13 22:42:02 +03:00
dumpOutputDirectory = CommandArgument (
' --dump-output-directory ' ,
action = ' store ' ,
2013-11-20 00:12:00 +04:00
help = ' Specifies the directory in which to place dumped memory reports. ' )
func = dumpOutputDirectory ( func )
2015-02-13 22:42:02 +03:00
path = CommandArgument (
' test_paths ' ,
default = None ,
nargs = ' * ' ,
2013-03-27 02:00:43 +04:00
metavar = ' TEST ' ,
2015-02-13 22:42:02 +03:00
help = ' Test to run. Can be specified as a single file, a '
' directory, or omitted. If omitted, the entire test suite is '
' executed. ' )
2013-03-27 02:00:43 +04:00
func = path ( func )
2015-02-13 22:42:02 +03:00
install_extension = CommandArgument (
' --install-extension ' ,
help = ' Install given extension before running selected tests. '
' Parameter is a path to xpi file. ' )
2013-12-17 19:56:29 +04:00
func = install_extension ( func )
2015-02-13 22:42:02 +03:00
quiet = CommandArgument (
' --quiet ' ,
default = False ,
action = ' store_true ' ,
2014-03-07 20:42:07 +04:00
help = ' Do not print test log lines unless a failure occurs. ' )
func = quiet ( func )
2015-02-13 22:42:02 +03:00
setenv = CommandArgument (
' --setenv ' ,
default = [ ] ,
action = ' append ' ,
metavar = ' NAME=VALUE ' ,
dest = ' environment ' ,
help = " Sets the given variable in the application ' s environment " )
2014-04-22 17:09:47 +04:00
func = setenv ( func )
2015-02-13 22:42:02 +03:00
runbydir = CommandArgument (
' --run-by-dir ' ,
default = False ,
action = ' store_true ' ,
dest = ' runByDir ' ,
2014-06-03 19:19:28 +04:00
help = ' Run each directory in a single browser instance with a fresh profile. ' )
func = runbydir ( func )
2015-02-13 22:42:02 +03:00
bisect_chunk = CommandArgument (
' --bisect-chunk ' ,
type = str ,
dest = ' bisectChunk ' ,
2014-07-04 15:55:00 +04:00
help = ' Specify the failing test name to find the previous tests that may be causing the failure. ' )
func = bisect_chunk ( func )
2015-02-13 22:42:02 +03:00
test_media = CommandArgument (
' --use-test-media-devices ' ,
default = False ,
action = ' store_true ' ,
dest = ' useTestMediaDevices ' ,
2014-05-01 15:18:00 +04:00
help = ' Use test media device drivers for media testing. ' )
func = test_media ( func )
2015-02-13 22:42:02 +03:00
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. " )
2014-05-01 14:05:36 +04:00
func = app_override ( func )
2015-02-13 22:42:02 +03:00
timeout = CommandArgument (
' --timeout ' ,
default = None ,
help = ' The per-test timeout time in seconds (default: 60 seconds) ' )
2014-11-17 19:52:24 +03:00
func = timeout ( func )
2013-03-27 02:00:43 +04:00
return func
2012-10-10 22:08:09 +04:00
2015-02-13 22:42:02 +03:00
2013-08-28 18:08:50 +04:00
def B2GCommand ( func ) :
""" Decorator that adds shared command arguments to b2g mochitest commands. """
2015-02-13 22:42:02 +03:00
busybox = CommandArgument (
' --busybox ' ,
default = None ,
2013-08-28 18:08:50 +04:00
help = ' Path to busybox binary to install on device ' )
func = busybox ( func )
2014-06-19 22:17:26 +04:00
logdir = CommandArgument ( ' --logdir ' , default = None ,
2015-02-13 22:42:02 +03:00
help = ' directory to store log files ' )
2014-06-19 22:17:26 +04:00
func = logdir ( func )
2013-08-28 18:08:50 +04:00
profile = CommandArgument ( ' --profile ' , default = None ,
2015-02-13 22:42:02 +03:00
help = ' for desktop testing, the path to the \
2013-08-28 18:08:50 +04:00
gaia profile to use ' )
func = profile ( func )
geckopath = CommandArgument ( ' --gecko-path ' , default = None ,
2015-02-13 22:42:02 +03:00
help = ' the path to a gecko distribution that should \
2013-08-28 18:08:50 +04:00
be installed on the emulator prior to test ' )
func = geckopath ( func )
2015-02-13 22:42:02 +03:00
nowindow = CommandArgument (
' --no-window ' ,
action = ' store_true ' ,
default = False ,
2013-08-28 18:08:50 +04:00
help = ' Pass --no-window to the emulator ' )
func = nowindow ( func )
sdcard = CommandArgument ( ' --sdcard ' , default = " 10MB " ,
2015-02-13 22:42:02 +03:00
help = ' Define size of sdcard: 1MB, 50MB...etc ' )
2013-08-28 18:08:50 +04:00
func = sdcard ( func )
2015-02-13 22:42:02 +03:00
marionette = CommandArgument (
' --marionette ' ,
default = None ,
2013-08-28 18:08:50 +04:00
help = ' host:port to use when connecting to Marionette ' )
func = marionette ( func )
2015-02-13 22:42:02 +03:00
chunk_total = CommandArgument (
' --total-chunks ' ,
type = int ,
2013-09-19 22:43:44 +04:00
help = ' Total number of chunks to split tests into. ' )
func = chunk_total ( func )
2015-02-13 22:42:02 +03:00
this_chunk = CommandArgument (
' --this-chunk ' ,
type = int ,
2013-09-19 22:43:44 +04:00
help = ' If running tests by chunks, the number of the chunk to run. ' )
func = this_chunk ( func )
2015-02-13 22:42:02 +03:00
path = CommandArgument (
' test_paths ' ,
default = None ,
nargs = ' * ' ,
2013-08-28 18:08:50 +04:00
metavar = ' TEST ' ,
2015-02-13 22:42:02 +03:00
help = ' Test to run. Can be specified as a single file, a '
' directory, or omitted. If omitted, the entire test suite is '
' executed. ' )
2013-08-28 18:08:50 +04:00
func = path ( func )
2014-08-05 07:29:00 +04:00
repeat = CommandArgument ( ' --repeat ' , type = int , default = 0 ,
2015-02-13 22:42:02 +03:00
help = ' Repeat the test the given number of times. ' )
2014-08-05 07:29:00 +04:00
func = repeat ( func )
2015-02-13 22:42:02 +03:00
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. ' )
2014-08-05 07:29:00 +04:00
func = runUntilFailure ( func )
2013-08-28 18:08:50 +04:00
return func
2012-10-10 22:08:09 +04:00
2014-08-13 20:03:00 +04:00
_st_parser = argparse . ArgumentParser ( )
structured . commandline . add_logging_group ( _st_parser )
2013-09-19 22:43:44 +04:00
2015-02-13 22:42:02 +03:00
2012-10-10 22:08:09 +04:00
@CommandProvider
2012-11-07 04:57:41 +04:00
class MachCommands ( MachCommandBase ) :
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-plain ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox_or_mulet ] ,
2014-08-13 20:03:00 +04:00
description = ' Run a plain mochitest (integration test, plain web page). ' ,
parser = _st_parser )
2013-03-27 02:00:43 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_plain ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' plain ' , * * kwargs )
2012-10-10 22:08:09 +04:00
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-chrome ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox ] ,
2014-08-25 20:32:00 +04:00
description = ' Run a chrome mochitest (integration test with some XUL). ' ,
parser = _st_parser )
2013-03-27 02:00:43 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_chrome ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' chrome ' , * * kwargs )
2012-10-10 22:08:09 +04:00
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-browser ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox ] ,
2014-08-25 20:32:00 +04:00
description = ' Run a mochitest with browser chrome (integration test with a standard browser). ' ,
parser = _st_parser )
2013-03-27 02:00:43 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_browser ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' browser ' , * * kwargs )
2012-10-10 22:08:09 +04:00
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-devtools ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox ] ,
2014-08-25 20:32:00 +04:00
description = ' Run a devtools mochitest with browser chrome (integration test with a standard browser with the devtools frame). ' ,
parser = _st_parser )
2014-03-25 20:52:53 +04:00
@MochitestCommand
def run_mochitest_devtools ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' devtools ' , * * kwargs )
2014-09-22 22:08:06 +04:00
@Command ( ' jetpack-package ' , category = ' testing ' ,
2015-02-13 22:42:02 +03:00
conditions = [ conditions . is_firefox ] ,
description = ' Run a jetpack package test. ' )
2014-09-22 22:08:06 +04:00
@MochitestCommand
def run_mochitest_jetpack_package ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' jetpack-package ' , * * kwargs )
@Command ( ' jetpack-addon ' , category = ' testing ' ,
2015-02-13 22:42:02 +03:00
conditions = [ conditions . is_firefox ] ,
description = ' Run a jetpack addon test. ' )
2014-09-22 22:08:06 +04:00
@MochitestCommand
def run_mochitest_jetpack_addon ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' jetpack-addon ' , * * kwargs )
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-metro ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox ] ,
2014-08-25 20:32:00 +04:00
description = ' Run a mochitest with metro browser chrome (tests for Windows touch interface). ' ,
parser = _st_parser )
2013-03-27 02:00:43 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_metro ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' metro ' , * * kwargs )
2013-02-13 00:51:24 +04:00
2013-05-09 04:56:30 +04:00
@Command ( ' mochitest-a11y ' , category = ' testing ' ,
2015-02-13 22:42:02 +03:00
conditions = [ conditions . is_firefox ] ,
description = ' Run an a11y mochitest (accessibility tests). ' ,
parser = _st_parser )
2013-03-27 02:00:43 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_a11y ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' a11y ' , * * kwargs )
2013-03-27 02:00:43 +04:00
2015-02-13 22:42:02 +03:00
@Command (
' webapprt-test-chrome ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox ] ,
2014-08-25 20:32:00 +04:00
description = ' Run a webapprt chrome mochitest (Web App Runtime with the browser chrome). ' ,
parser = _st_parser )
2013-08-23 18:06:16 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_webapprt_chrome ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' webapprt-chrome ' , * * kwargs )
2013-08-23 18:06:16 +04:00
2015-02-13 22:42:02 +03:00
@Command (
' webapprt-test-content ' ,
category = ' testing ' ,
conditions = [
conditions . is_firefox ] ,
2014-08-25 20:32:00 +04:00
description = ' Run a webapprt content mochitest (Content rendering of the Web App Runtime). ' ,
parser = _st_parser )
2013-08-23 18:06:16 +04:00
@MochitestCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_webapprt_content ( self , test_paths , * * kwargs ) :
return self . run_mochitest ( test_paths , ' webapprt-content ' , * * kwargs )
2013-08-23 18:06:16 +04:00
2014-06-18 02:42:08 +04:00
@Command ( ' mochitest ' , category = ' testing ' ,
2015-02-13 22:42:02 +03:00
conditions = [ conditions . is_firefox ] ,
description = ' Run any flavor of mochitest (integration test). ' ,
parser = _st_parser )
2014-06-18 02:42:08 +04:00
@MochitestCommand
2014-06-18 02:49:41 +04:00
@CommandArgument ( ' -f ' , ' --flavor ' , choices = FLAVORS . keys ( ) ,
2015-02-13 22:42:02 +03:00
help = ' Only run tests of this flavor. ' )
2014-06-18 22:19:45 +04:00
def run_mochitest_general ( self , test_paths , flavor = None , test_objects = None ,
2015-02-13 22:42:02 +03:00
* * kwargs ) :
2014-06-18 02:42:08 +04:00
self . _preruntest ( )
from mozbuild . testing import TestResolver
2014-06-18 22:19:45 +04:00
if test_objects :
tests = test_objects
else :
resolver = self . _spawn ( TestResolver )
tests = list ( resolver . resolve_tests ( paths = test_paths ,
2015-02-13 22:42:02 +03:00
cwd = self . _mach_context . cwd ) )
2014-06-18 02:42:08 +04:00
# Our current approach is to group the tests by suite and then perform
# an invocation for each suite. Ideally, this would be done
# automatically inside of core mochitest code. But it wasn't designed
# to do that.
#
# This does mean our output is less than ideal. When running tests from
# multiple suites, we see redundant summary lines. Hopefully once we
# have better machine readable output coming from mochitest land we can
# aggregate that here and improve the output formatting.
suites = { }
for test in tests :
2014-06-18 02:49:41 +04:00
# Filter out non-mochitests.
2014-06-18 02:42:08 +04:00
if test [ ' flavor ' ] not in FLAVORS :
continue
2014-06-18 02:49:41 +04:00
if flavor and test [ ' flavor ' ] != flavor :
continue
2014-06-18 02:42:08 +04:00
suite = FLAVORS [ test [ ' flavor ' ] ]
suites . setdefault ( suite , [ ] ) . append ( test )
mochitest = self . _spawn ( MochitestRunner )
overall = None
for suite , tests in sorted ( suites . items ( ) ) :
2015-02-13 22:42:02 +03:00
result = mochitest . run_desktop_test (
self . _mach_context ,
test_paths = [
test [ ' file_relpath ' ] for test in tests ] ,
suite = suite ,
2014-06-18 02:42:08 +04:00
* * kwargs )
if result :
overall = result
return overall
def _preruntest ( self ) :
2013-10-01 20:36:44 +04:00
from mozbuild . controller . building import BuildDriver
2012-11-02 21:32:40 +04:00
self . _ensure_state_subdir_exists ( ' . ' )
2013-10-01 20:36:44 +04:00
driver = self . _spawn ( BuildDriver )
driver . install_tests ( remove = False )
2014-06-18 02:42:08 +04:00
def run_mochitest ( self , test_paths , flavor , * * kwargs ) :
self . _preruntest ( )
2012-10-10 22:08:09 +04:00
mochitest = self . _spawn ( MochitestRunner )
2013-09-19 22:43:44 +04:00
2015-02-13 22:42:02 +03:00
return mochitest . run_desktop_test (
self . _mach_context ,
test_paths = test_paths ,
suite = flavor ,
* * kwargs )
2013-08-28 18:08:50 +04:00
# TODO For now b2g commands will only work with the emulator,
# they should be modified to work with all devices.
def is_emulator ( cls ) :
""" Emulator needs to be configured. """
2014-06-24 21:47:19 +04:00
try :
return cls . device_name . startswith ( ' emulator ' )
except AttributeError :
return False
2013-08-28 18:08:50 +04:00
@CommandProvider
class B2GCommands ( MachCommandBase ) :
2015-02-13 22:42:02 +03:00
2013-09-19 22:43:44 +04:00
""" So far these are only mochitest plain. They are
implemented separately because their command lines
are completely different .
"""
2015-02-13 22:42:02 +03:00
2013-08-28 18:08:50 +04:00
def __init__ ( self , context ) :
MachCommandBase . __init__ ( self , context )
2014-07-17 21:38:20 +04:00
for attr in ( ' b2g_home ' , ' xre_path ' , ' device_name ' , ' get_build_var ' ) :
2013-08-28 18:08:50 +04:00
setattr ( self , attr , getattr ( context , attr , None ) )
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-remote ' ,
category = ' testing ' ,
2014-08-09 17:37:29 +04:00
description = ' Run a remote mochitest (integration test for fennec/android). ' ,
2015-02-13 22:42:02 +03:00
conditions = [
conditions . is_b2g ,
is_emulator ] )
2013-08-28 18:08:50 +04:00
@B2GCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_remote ( self , test_paths , * * kwargs ) :
2014-07-17 21:38:20 +04:00
if self . get_build_var :
2015-02-13 22:42:02 +03:00
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 ) )
2014-07-17 21:38:20 +04:00
return 1
2013-10-01 20:36:44 +04:00
from mozbuild . controller . building import BuildDriver
2014-04-30 20:57:39 +04:00
if self . device_name . startswith ( ' emulator ' ) :
emulator = ' arm '
if ' x86 ' in self . device_name :
emulator = ' x86 '
kwargs [ ' emulator ' ] = emulator
2013-08-28 18:08:50 +04:00
self . _ensure_state_subdir_exists ( ' . ' )
2013-10-01 20:36:44 +04:00
driver = self . _spawn ( BuildDriver )
driver . install_tests ( remove = False )
2013-08-28 18:08:50 +04:00
mochitest = self . _spawn ( MochitestRunner )
2015-02-13 22:42:02 +03:00
return mochitest . run_b2g_test (
b2g_home = self . b2g_home ,
xre_path = self . xre_path ,
test_paths = test_paths ,
* * kwargs )
2013-09-19 22:43:44 +04:00
2014-12-24 00:17:39 +03:00
@Command ( ' mochitest-chrome-remote ' , category = ' testing ' ,
2015-02-13 22:42:02 +03:00
description = ' Run a remote mochitest-chrome. ' ,
conditions = [ conditions . is_b2g , is_emulator ] )
2014-12-24 00:17:39 +03:00
@B2GCommand
def run_mochitest_chrome_remote ( self , test_paths , * * kwargs ) :
return self . run_mochitest_remote ( test_paths , chrome = True , * * kwargs )
2015-02-13 22:42:02 +03:00
@Command (
' mochitest-b2g-desktop ' ,
category = ' testing ' ,
conditions = [
conditions . is_b2g_desktop ] ,
2014-08-09 17:37:29 +04:00
description = ' Run a b2g desktop mochitest (same as mochitest-plain but for b2g desktop). ' )
2013-09-19 22:43:44 +04:00
@B2GCommand
2014-03-25 03:19:57 +04:00
def run_mochitest_b2g_desktop ( self , test_paths , * * kwargs ) :
2015-02-13 22:42:02 +03:00
kwargs [ ' profile ' ] = kwargs . get (
' profile ' ) or os . environ . get ( ' GAIA_PROFILE ' )
2014-07-17 21:38:20 +04:00
if not kwargs [ ' profile ' ] or not os . path . isdir ( kwargs [ ' profile ' ] ) :
print ( GAIA_PROFILE_NOT_FOUND % ' mochitest-b2g-desktop ' )
return 1
if os . path . isfile ( os . path . join ( kwargs [ ' profile ' ] , ' extensions ' ,
' httpd@gaiamobile.org ' ) ) :
print ( GAIA_PROFILE_IS_DEBUG % ( ' mochitest-b2g-desktop ' ,
kwargs [ ' profile ' ] ) )
return 1
2013-10-01 20:36:44 +04:00
from mozbuild . controller . building import BuildDriver
2013-09-19 22:43:44 +04:00
self . _ensure_state_subdir_exists ( ' . ' )
2013-10-01 20:36:44 +04:00
driver = self . _spawn ( BuildDriver )
driver . install_tests ( remove = False )
2013-09-19 22:43:44 +04:00
mochitest = self . _spawn ( MochitestRunner )
2014-03-25 03:19:57 +04:00
return mochitest . run_b2g_test ( test_paths = test_paths , * * kwargs )
2014-09-09 03:23:12 +04:00
@CommandProvider
class AndroidCommands ( MachCommandBase ) :
2015-02-13 22:42:02 +03:00
2014-09-09 03:23:12 +04:00
@Command ( ' robocop ' , category = ' testing ' ,
2015-02-13 22:42:02 +03:00
conditions = [ conditions . is_android ] ,
description = ' Run a Robocop test. ' )
@CommandArgument (
' test_path ' ,
default = None ,
nargs = ' ? ' ,
2014-09-09 03:23:12 +04:00
metavar = ' TEST ' ,
2015-02-13 22:42:02 +03:00
help = ' Test to run. Can be specified as a Robocop test name (like " testLoad " ), '
' or omitted. If omitted, the entire test suite is executed. ' )
2014-09-09 03:23:12 +04:00
def run_robocop ( self , test_path ) :
self . tests_dir = os . path . join ( self . topobjdir , ' _tests ' )
2015-02-13 22:42:02 +03:00
self . mochitest_dir = os . path . join (
self . tests_dir ,
' testing ' ,
' mochitest ' )
2014-09-09 03:23:12 +04:00
import imp
path = os . path . join ( self . mochitest_dir , ' runtestsremote.py ' )
with open ( path , ' r ' ) as fh :
imp . load_module ( ' runtestsremote ' , fh , path ,
2015-02-13 22:42:02 +03:00
( ' .py ' , ' r ' , imp . PY_SOURCE ) )
2014-09-09 03:23:12 +04:00
import runtestsremote
args = [
2015-02-13 22:42:02 +03:00
' --xre-path= ' +
os . environ . get ( ' MOZ_HOST_BIN ' ) ,
2014-09-09 03:23:12 +04:00
' --dm_trans=adb ' ,
' --deviceIP= ' ,
' --console-level=INFO ' ,
2015-02-13 22:42:02 +03:00
' --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 ' ) ,
2014-09-09 03:23:12 +04:00
' --log-mach=- ' ,
]
if test_path :
args . append ( ' --test-path= %s ' % test_path )
sys . exit ( runtestsremote . main ( args ) )