1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mochitest/mochitest_options.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,784 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +import mozinfo 1.9 +import moznetwork 1.10 +import optparse 1.11 +import os 1.12 +import tempfile 1.13 + 1.14 +from automationutils import addCommonOptions, isURL 1.15 +from mozprofile import DEFAULT_PORTS 1.16 + 1.17 +here = os.path.abspath(os.path.dirname(__file__)) 1.18 + 1.19 +try: 1.20 + from mozbuild.base import MozbuildObject 1.21 + build_obj = MozbuildObject.from_environment(cwd=here) 1.22 +except ImportError: 1.23 + build_obj = None 1.24 + 1.25 +__all__ = ["MochitestOptions", "B2GOptions"] 1.26 + 1.27 +VMWARE_RECORDING_HELPER_BASENAME = "vmwarerecordinghelper" 1.28 + 1.29 +class MochitestOptions(optparse.OptionParser): 1.30 + """Usage instructions for runtests.py. 1.31 + All arguments are optional. 1.32 + If --chrome is specified, chrome tests will be run instead of web content tests. 1.33 + If --browser-chrome is specified, browser-chrome tests will be run instead of web content tests. 1.34 + See <http://mochikit.com/doc/html/MochiKit/Logging.html> for details on the logging levels. 1.35 + """ 1.36 + 1.37 + LOG_LEVELS = ("DEBUG", "INFO", "WARNING", "ERROR", "FATAL") 1.38 + LEVEL_STRING = ", ".join(LOG_LEVELS) 1.39 + mochitest_options = [ 1.40 + [["--close-when-done"], 1.41 + { "action": "store_true", 1.42 + "dest": "closeWhenDone", 1.43 + "default": False, 1.44 + "help": "close the application when tests are done running", 1.45 + }], 1.46 + [["--appname"], 1.47 + { "action": "store", 1.48 + "type": "string", 1.49 + "dest": "app", 1.50 + "default": None, 1.51 + "help": "absolute path to application, overriding default", 1.52 + }], 1.53 + [["--utility-path"], 1.54 + { "action": "store", 1.55 + "type": "string", 1.56 + "dest": "utilityPath", 1.57 + "default": build_obj.bindir if build_obj is not None else None, 1.58 + "help": "absolute path to directory containing utility programs (xpcshell, ssltunnel, certutil)", 1.59 + }], 1.60 + [["--certificate-path"], 1.61 + { "action": "store", 1.62 + "type": "string", 1.63 + "dest": "certPath", 1.64 + "help": "absolute path to directory containing certificate store to use testing profile", 1.65 + "default": os.path.join(build_obj.topsrcdir, 'build', 'pgo', 'certs') if build_obj is not None else None, 1.66 + }], 1.67 + [["--log-file"], 1.68 + { "action": "store", 1.69 + "type": "string", 1.70 + "dest": "logFile", 1.71 + "metavar": "FILE", 1.72 + "help": "file to which logging occurs", 1.73 + "default": "", 1.74 + }], 1.75 + [["--hide-subtests"], 1.76 + { "action": "store_true", 1.77 + "dest": "hide_subtests", 1.78 + "help": "only show subtest log output if there was a failure", 1.79 + "default": False, 1.80 + }], 1.81 + [["--autorun"], 1.82 + { "action": "store_true", 1.83 + "dest": "autorun", 1.84 + "help": "start running tests when the application starts", 1.85 + "default": False, 1.86 + }], 1.87 + [["--timeout"], 1.88 + { "type": "int", 1.89 + "dest": "timeout", 1.90 + "help": "per-test timeout in seconds", 1.91 + "default": None, 1.92 + }], 1.93 + [["--total-chunks"], 1.94 + { "type": "int", 1.95 + "dest": "totalChunks", 1.96 + "help": "how many chunks to split the tests up into", 1.97 + "default": None, 1.98 + }], 1.99 + [["--this-chunk"], 1.100 + { "type": "int", 1.101 + "dest": "thisChunk", 1.102 + "help": "which chunk to run", 1.103 + "default": None, 1.104 + }], 1.105 + [["--chunk-by-dir"], 1.106 + { "type": "int", 1.107 + "dest": "chunkByDir", 1.108 + "help": "group tests together in the same chunk that are in the same top chunkByDir directories", 1.109 + "default": 0, 1.110 + }], 1.111 + [["--shuffle"], 1.112 + { "dest": "shuffle", 1.113 + "action": "store_true", 1.114 + "help": "randomize test order", 1.115 + "default": False, 1.116 + }], 1.117 + [["--console-level"], 1.118 + { "action": "store", 1.119 + "type": "choice", 1.120 + "dest": "consoleLevel", 1.121 + "choices": LOG_LEVELS, 1.122 + "metavar": "LEVEL", 1.123 + "help": "one of %s to determine the level of console " 1.124 + "logging" % LEVEL_STRING, 1.125 + "default": None, 1.126 + }], 1.127 + [["--file-level"], 1.128 + { "action": "store", 1.129 + "type": "choice", 1.130 + "dest": "fileLevel", 1.131 + "choices": LOG_LEVELS, 1.132 + "metavar": "LEVEL", 1.133 + "help": "one of %s to determine the level of file " 1.134 + "logging if a file has been specified, defaulting " 1.135 + "to INFO" % LEVEL_STRING, 1.136 + "default": "INFO", 1.137 + }], 1.138 + [["--chrome"], 1.139 + { "action": "store_true", 1.140 + "dest": "chrome", 1.141 + "help": "run chrome Mochitests", 1.142 + "default": False, 1.143 + }], 1.144 + [["--ipcplugins"], 1.145 + { "action": "store_true", 1.146 + "dest": "ipcplugins", 1.147 + "help": "run ipcplugins Mochitests", 1.148 + "default": False, 1.149 + }], 1.150 + [["--test-path"], 1.151 + { "action": "store", 1.152 + "type": "string", 1.153 + "dest": "testPath", 1.154 + "help": "start in the given directory's tests", 1.155 + "default": "", 1.156 + }], 1.157 + [["--start-at"], 1.158 + { "action": "store", 1.159 + "type": "string", 1.160 + "dest": "startAt", 1.161 + "help": "skip over tests until reaching the given test", 1.162 + "default": "", 1.163 + }], 1.164 + [["--end-at"], 1.165 + { "action": "store", 1.166 + "type": "string", 1.167 + "dest": "endAt", 1.168 + "help": "don't run any tests after the given one", 1.169 + "default": "", 1.170 + }], 1.171 + [["--browser-chrome"], 1.172 + { "action": "store_true", 1.173 + "dest": "browserChrome", 1.174 + "help": "run browser chrome Mochitests", 1.175 + "default": False, 1.176 + }], 1.177 + [["--subsuite"], 1.178 + { "action": "store", 1.179 + "dest": "subsuite", 1.180 + "help": "subsuite of tests to run", 1.181 + "default": "", 1.182 + }], 1.183 + [["--webapprt-content"], 1.184 + { "action": "store_true", 1.185 + "dest": "webapprtContent", 1.186 + "help": "run WebappRT content tests", 1.187 + "default": False, 1.188 + }], 1.189 + [["--webapprt-chrome"], 1.190 + { "action": "store_true", 1.191 + "dest": "webapprtChrome", 1.192 + "help": "run WebappRT chrome tests", 1.193 + "default": False, 1.194 + }], 1.195 + [["--a11y"], 1.196 + { "action": "store_true", 1.197 + "dest": "a11y", 1.198 + "help": "run accessibility Mochitests", 1.199 + "default": False, 1.200 + }], 1.201 + [["--setenv"], 1.202 + { "action": "append", 1.203 + "type": "string", 1.204 + "dest": "environment", 1.205 + "metavar": "NAME=VALUE", 1.206 + "help": "sets the given variable in the application's " 1.207 + "environment", 1.208 + "default": [], 1.209 + }], 1.210 + [["--exclude-extension"], 1.211 + { "action": "append", 1.212 + "type": "string", 1.213 + "dest": "extensionsToExclude", 1.214 + "help": "excludes the given extension from being installed " 1.215 + "in the test profile", 1.216 + "default": [], 1.217 + }], 1.218 + [["--browser-arg"], 1.219 + { "action": "append", 1.220 + "type": "string", 1.221 + "dest": "browserArgs", 1.222 + "metavar": "ARG", 1.223 + "help": "provides an argument to the test application", 1.224 + "default": [], 1.225 + }], 1.226 + [["--leak-threshold"], 1.227 + { "action": "store", 1.228 + "type": "int", 1.229 + "dest": "leakThreshold", 1.230 + "metavar": "THRESHOLD", 1.231 + "help": "fail if the number of bytes leaked through " 1.232 + "refcounted objects (or bytes in classes with " 1.233 + "MOZ_COUNT_CTOR and MOZ_COUNT_DTOR) is greater " 1.234 + "than the given number", 1.235 + "default": 0, 1.236 + }], 1.237 + [["--fatal-assertions"], 1.238 + { "action": "store_true", 1.239 + "dest": "fatalAssertions", 1.240 + "help": "abort testing whenever an assertion is hit " 1.241 + "(requires a debug build to be effective)", 1.242 + "default": False, 1.243 + }], 1.244 + [["--extra-profile-file"], 1.245 + { "action": "append", 1.246 + "dest": "extraProfileFiles", 1.247 + "help": "copy specified files/dirs to testing profile", 1.248 + "default": [], 1.249 + }], 1.250 + [["--install-extension"], 1.251 + { "action": "append", 1.252 + "dest": "extensionsToInstall", 1.253 + "help": "install the specified extension in the testing profile." 1.254 + "The extension file's name should be <id>.xpi where <id> is" 1.255 + "the extension's id as indicated in its install.rdf." 1.256 + "An optional path can be specified too.", 1.257 + "default": [], 1.258 + }], 1.259 + [["--profile-path"], 1.260 + { "action": "store", 1.261 + "type": "string", 1.262 + "dest": "profilePath", 1.263 + "help": "Directory where the profile will be stored." 1.264 + "This directory will be deleted after the tests are finished", 1.265 + "default": tempfile.mkdtemp(), 1.266 + }], 1.267 + [["--testing-modules-dir"], 1.268 + { "action": "store", 1.269 + "type": "string", 1.270 + "dest": "testingModulesDir", 1.271 + "help": "Directory where testing-only JS modules are located.", 1.272 + "default": None, 1.273 + }], 1.274 + [["--use-vmware-recording"], 1.275 + { "action": "store_true", 1.276 + "dest": "vmwareRecording", 1.277 + "help": "enables recording while the application is running " 1.278 + "inside a VMware Workstation 7.0 or later VM", 1.279 + "default": False, 1.280 + }], 1.281 + [["--repeat"], 1.282 + { "action": "store", 1.283 + "type": "int", 1.284 + "dest": "repeat", 1.285 + "metavar": "REPEAT", 1.286 + "help": "repeats the test or set of tests the given number of times, ie: repeat: 1 will run the test twice.", 1.287 + "default": 0, 1.288 + }], 1.289 + [["--run-until-failure"], 1.290 + { "action": "store_true", 1.291 + "dest": "runUntilFailure", 1.292 + "help": "Run tests repeatedly and stops on the first time a test fails. " 1.293 + "Default cap is 30 runs, which can be overwritten with the --repeat parameter.", 1.294 + "default": False, 1.295 + }], 1.296 + [["--run-only-tests"], 1.297 + { "action": "store", 1.298 + "type": "string", 1.299 + "dest": "runOnlyTests", 1.300 + "help": "JSON list of tests that we only want to run. [DEPRECATED- please use --test-manifest]", 1.301 + "default": None, 1.302 + }], 1.303 + [["--test-manifest"], 1.304 + { "action": "store", 1.305 + "type": "string", 1.306 + "dest": "testManifest", 1.307 + "help": "JSON list of tests to specify 'runtests'. Old format for mobile specific tests", 1.308 + "default": None, 1.309 + }], 1.310 + [["--manifest"], 1.311 + { "action": "store", 1.312 + "type": "string", 1.313 + "dest": "manifestFile", 1.314 + "help": ".ini format of tests to run.", 1.315 + "default": None, 1.316 + }], 1.317 + [["--failure-file"], 1.318 + { "action": "store", 1.319 + "type": "string", 1.320 + "dest": "failureFile", 1.321 + "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.", 1.322 + "default": None, 1.323 + }], 1.324 + [["--run-slower"], 1.325 + { "action": "store_true", 1.326 + "dest": "runSlower", 1.327 + "help": "Delay execution between test files.", 1.328 + "default": False, 1.329 + }], 1.330 + [["--metro-immersive"], 1.331 + { "action": "store_true", 1.332 + "dest": "immersiveMode", 1.333 + "help": "launches tests in immersive browser", 1.334 + "default": False, 1.335 + }], 1.336 + [["--httpd-path"], 1.337 + { "action": "store", 1.338 + "type": "string", 1.339 + "dest": "httpdPath", 1.340 + "default": None, 1.341 + "help": "path to the httpd.js file", 1.342 + }], 1.343 + [["--setpref"], 1.344 + { "action": "append", 1.345 + "type": "string", 1.346 + "default": [], 1.347 + "dest": "extraPrefs", 1.348 + "metavar": "PREF=VALUE", 1.349 + "help": "defines an extra user preference", 1.350 + }], 1.351 + [["--jsdebugger"], 1.352 + { "action": "store_true", 1.353 + "default": False, 1.354 + "dest": "jsdebugger", 1.355 + "help": "open the browser debugger", 1.356 + }], 1.357 + [["--debug-on-failure"], 1.358 + { "action": "store_true", 1.359 + "default": False, 1.360 + "dest": "debugOnFailure", 1.361 + "help": "breaks execution and enters the JS debugger on a test failure. Should be used together with --jsdebugger." 1.362 + }], 1.363 + [["--e10s"], 1.364 + { "action": "store_true", 1.365 + "default": False, 1.366 + "dest": "e10s", 1.367 + "help": "Run tests with electrolysis preferences and test filtering enabled.", 1.368 + }], 1.369 + [["--dmd-path"], 1.370 + { "action": "store", 1.371 + "default": None, 1.372 + "dest": "dmdPath", 1.373 + "help": "Specifies the path to the directory containing the shared library for DMD.", 1.374 + }], 1.375 + [["--dump-output-directory"], 1.376 + { "action": "store", 1.377 + "default": None, 1.378 + "dest": "dumpOutputDirectory", 1.379 + "help": "Specifies the directory in which to place dumped memory reports.", 1.380 + }], 1.381 + [["--dump-about-memory-after-test"], 1.382 + { "action": "store_true", 1.383 + "default": False, 1.384 + "dest": "dumpAboutMemoryAfterTest", 1.385 + "help": "Produce an about:memory dump after each test in the directory specified " 1.386 + "by --dump-output-directory." 1.387 + }], 1.388 + [["--dump-dmd-after-test"], 1.389 + { "action": "store_true", 1.390 + "default": False, 1.391 + "dest": "dumpDMDAfterTest", 1.392 + "help": "Produce a DMD dump after each test in the directory specified " 1.393 + "by --dump-output-directory." 1.394 + }], 1.395 + [["--slowscript"], 1.396 + { "action": "store_true", 1.397 + "default": False, 1.398 + "dest": "slowscript", 1.399 + "help": "Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; " 1.400 + "when not set, recoverable but misleading SIGSEGV instances " 1.401 + "may occur in Ion/Odin JIT code." 1.402 + }], 1.403 + [["--screenshot-on-fail"], 1.404 + { "action": "store_true", 1.405 + "default": False, 1.406 + "dest": "screenshotOnFail", 1.407 + "help": "Take screenshots on all test failures. Set $MOZ_UPLOAD_DIR to a directory for storing the screenshots." 1.408 + }], 1.409 + [["--quiet"], 1.410 + { "action": "store_true", 1.411 + "default": False, 1.412 + "dest": "quiet", 1.413 + "help": "Do not print test log lines unless a failure occurs." 1.414 + }], 1.415 + [["--pidfile"], 1.416 + { "action": "store", 1.417 + "type": "string", 1.418 + "dest": "pidFile", 1.419 + "help": "name of the pidfile to generate", 1.420 + "default": "", 1.421 + }], 1.422 + ] 1.423 + 1.424 + def __init__(self, **kwargs): 1.425 + 1.426 + optparse.OptionParser.__init__(self, **kwargs) 1.427 + for option, value in self.mochitest_options: 1.428 + self.add_option(*option, **value) 1.429 + addCommonOptions(self) 1.430 + self.set_usage(self.__doc__) 1.431 + 1.432 + def verifyOptions(self, options, mochitest): 1.433 + """ verify correct options and cleanup paths """ 1.434 + 1.435 + mozinfo.update({"e10s": options.e10s}) # for test manifest parsing. 1.436 + 1.437 + if options.app is None: 1.438 + if build_obj is not None: 1.439 + options.app = build_obj.get_binary_path() 1.440 + else: 1.441 + self.error("could not find the application path, --appname must be specified") 1.442 + 1.443 + if options.totalChunks is not None and options.thisChunk is None: 1.444 + self.error("thisChunk must be specified when totalChunks is specified") 1.445 + 1.446 + if options.totalChunks: 1.447 + if not 1 <= options.thisChunk <= options.totalChunks: 1.448 + self.error("thisChunk must be between 1 and totalChunks") 1.449 + 1.450 + if options.xrePath is None: 1.451 + # default xrePath to the app path if not provided 1.452 + # but only if an app path was explicitly provided 1.453 + if options.app != self.defaults['app']: 1.454 + options.xrePath = os.path.dirname(options.app) 1.455 + elif build_obj is not None: 1.456 + # otherwise default to dist/bin 1.457 + options.xrePath = build_obj.bindir 1.458 + else: 1.459 + self.error("could not find xre directory, --xre-path must be specified") 1.460 + 1.461 + # allow relative paths 1.462 + options.xrePath = mochitest.getFullPath(options.xrePath) 1.463 + options.profilePath = mochitest.getFullPath(options.profilePath) 1.464 + options.app = mochitest.getFullPath(options.app) 1.465 + if options.dmdPath is not None: 1.466 + options.dmdPath = mochitest.getFullPath(options.dmdPath) 1.467 + 1.468 + if not os.path.exists(options.app): 1.469 + msg = """\ 1.470 + Error: Path %(app)s doesn't exist. 1.471 + Are you executing $objdir/_tests/testing/mochitest/runtests.py?""" 1.472 + self.error(msg % {"app": options.app}) 1.473 + return None 1.474 + 1.475 + if options.utilityPath: 1.476 + options.utilityPath = mochitest.getFullPath(options.utilityPath) 1.477 + 1.478 + if options.certPath: 1.479 + options.certPath = mochitest.getFullPath(options.certPath) 1.480 + 1.481 + if options.symbolsPath and not isURL(options.symbolsPath): 1.482 + options.symbolsPath = mochitest.getFullPath(options.symbolsPath) 1.483 + 1.484 + # Set server information on the options object 1.485 + options.webServer = '127.0.0.1' 1.486 + options.httpPort = DEFAULT_PORTS['http'] 1.487 + options.sslPort = DEFAULT_PORTS['https'] 1.488 + # options.webSocketPort = DEFAULT_PORTS['ws'] 1.489 + options.webSocketPort = str(9988) # <- http://hg.mozilla.org/mozilla-central/file/b871dfb2186f/build/automation.py.in#l30 1.490 + # The default websocket port is incorrect in mozprofile; it is 1.491 + # set to the SSL proxy setting. See: 1.492 + # see https://bugzilla.mozilla.org/show_bug.cgi?id=916517 1.493 + 1.494 + if options.vmwareRecording: 1.495 + if not mozinfo.isWin: 1.496 + self.error("use-vmware-recording is only supported on Windows.") 1.497 + mochitest.vmwareHelperPath = os.path.join( 1.498 + options.utilityPath, VMWARE_RECORDING_HELPER_BASENAME + ".dll") 1.499 + if not os.path.exists(mochitest.vmwareHelperPath): 1.500 + self.error("%s not found, cannot automate VMware recording." % 1.501 + mochitest.vmwareHelperPath) 1.502 + 1.503 + if options.testManifest and options.runOnlyTests: 1.504 + self.error("Please use --test-manifest only and not --run-only-tests") 1.505 + 1.506 + if options.runOnlyTests: 1.507 + if not os.path.exists(os.path.abspath(os.path.join(here, options.runOnlyTests))): 1.508 + self.error("unable to find --run-only-tests file '%s'" % options.runOnlyTests) 1.509 + options.runOnly = True 1.510 + options.testManifest = options.runOnlyTests 1.511 + options.runOnlyTests = None 1.512 + 1.513 + if options.manifestFile and options.testManifest: 1.514 + self.error("Unable to support both --manifest and --test-manifest/--run-only-tests at the same time") 1.515 + 1.516 + if options.webapprtContent and options.webapprtChrome: 1.517 + self.error("Only one of --webapprt-content and --webapprt-chrome may be given.") 1.518 + 1.519 + if options.jsdebugger: 1.520 + options.extraPrefs += [ 1.521 + "devtools.debugger.remote-enabled=true", 1.522 + "devtools.debugger.chrome-enabled=true", 1.523 + "devtools.chrome.enabled=true", 1.524 + "devtools.debugger.prompt-connection=false" 1.525 + ] 1.526 + options.autorun = False 1.527 + 1.528 + if options.debugOnFailure and not options.jsdebugger: 1.529 + self.error("--debug-on-failure should be used together with --jsdebugger.") 1.530 + 1.531 + # Try to guess the testing modules directory. 1.532 + # This somewhat grotesque hack allows the buildbot machines to find the 1.533 + # modules directory without having to configure the buildbot hosts. This 1.534 + # code should never be executed in local runs because the build system 1.535 + # should always set the flag that populates this variable. If buildbot ever 1.536 + # passes this argument, this code can be deleted. 1.537 + if options.testingModulesDir is None: 1.538 + possible = os.path.join(here, os.path.pardir, 'modules') 1.539 + 1.540 + if os.path.isdir(possible): 1.541 + options.testingModulesDir = possible 1.542 + 1.543 + # Even if buildbot is updated, we still want this, as the path we pass in 1.544 + # to the app must be absolute and have proper slashes. 1.545 + if options.testingModulesDir is not None: 1.546 + options.testingModulesDir = os.path.normpath(options.testingModulesDir) 1.547 + 1.548 + if not os.path.isabs(options.testingModulesDir): 1.549 + options.testingModulesDir = os.path.abspath(options.testingModulesDir) 1.550 + 1.551 + if not os.path.isdir(options.testingModulesDir): 1.552 + self.error('--testing-modules-dir not a directory: %s' % 1.553 + options.testingModulesDir) 1.554 + 1.555 + options.testingModulesDir = options.testingModulesDir.replace('\\', '/') 1.556 + if options.testingModulesDir[-1] != '/': 1.557 + options.testingModulesDir += '/' 1.558 + 1.559 + if options.immersiveMode: 1.560 + if not mozinfo.isWin: 1.561 + self.error("immersive is only supported on Windows 8 and up.") 1.562 + mochitest.immersiveHelperPath = os.path.join( 1.563 + options.utilityPath, "metrotestharness.exe") 1.564 + if not os.path.exists(mochitest.immersiveHelperPath): 1.565 + self.error("%s not found, cannot launch immersive tests." % 1.566 + mochitest.immersiveHelperPath) 1.567 + 1.568 + if options.runUntilFailure: 1.569 + if not options.repeat: 1.570 + options.repeat = 29 1.571 + 1.572 + if options.dumpOutputDirectory is None: 1.573 + options.dumpOutputDirectory = tempfile.gettempdir() 1.574 + 1.575 + if options.dumpAboutMemoryAfterTest or options.dumpDMDAfterTest: 1.576 + if not os.path.isdir(options.dumpOutputDirectory): 1.577 + self.error('--dump-output-directory not a directory: %s' % 1.578 + options.dumpOutputDirectory) 1.579 + 1.580 + return options 1.581 + 1.582 + 1.583 +class B2GOptions(MochitestOptions): 1.584 + b2g_options = [ 1.585 + [["--b2gpath"], 1.586 + { "action": "store", 1.587 + "type": "string", 1.588 + "dest": "b2gPath", 1.589 + "help": "path to B2G repo or qemu dir", 1.590 + "default": None, 1.591 + }], 1.592 + [["--desktop"], 1.593 + { "action": "store_true", 1.594 + "dest": "desktop", 1.595 + "help": "Run the tests on a B2G desktop build", 1.596 + "default": False, 1.597 + }], 1.598 + [["--marionette"], 1.599 + { "action": "store", 1.600 + "type": "string", 1.601 + "dest": "marionette", 1.602 + "help": "host:port to use when connecting to Marionette", 1.603 + "default": None, 1.604 + }], 1.605 + [["--emulator"], 1.606 + { "action": "store", 1.607 + "type": "string", 1.608 + "dest": "emulator", 1.609 + "help": "Architecture of emulator to use: x86 or arm", 1.610 + "default": None, 1.611 + }], 1.612 + [["--wifi"], 1.613 + { "action": "store", 1.614 + "type": "string", 1.615 + "dest": "wifi", 1.616 + "help": "Devine wifi configuration for on device mochitest", 1.617 + "default": False, 1.618 + }], 1.619 + [["--sdcard"], 1.620 + { "action": "store", 1.621 + "type": "string", 1.622 + "dest": "sdcard", 1.623 + "help": "Define size of sdcard: 1MB, 50MB...etc", 1.624 + "default": "10MB", 1.625 + }], 1.626 + [["--no-window"], 1.627 + { "action": "store_true", 1.628 + "dest": "noWindow", 1.629 + "help": "Pass --no-window to the emulator", 1.630 + "default": False, 1.631 + }], 1.632 + [["--adbpath"], 1.633 + { "action": "store", 1.634 + "type": "string", 1.635 + "dest": "adbPath", 1.636 + "help": "path to adb", 1.637 + "default": "adb", 1.638 + }], 1.639 + [["--deviceIP"], 1.640 + { "action": "store", 1.641 + "type": "string", 1.642 + "dest": "deviceIP", 1.643 + "help": "ip address of remote device to test", 1.644 + "default": None, 1.645 + }], 1.646 + [["--devicePort"], 1.647 + { "action": "store", 1.648 + "type": "string", 1.649 + "dest": "devicePort", 1.650 + "help": "port of remote device to test", 1.651 + "default": 20701, 1.652 + }], 1.653 + [["--remote-logfile"], 1.654 + { "action": "store", 1.655 + "type": "string", 1.656 + "dest": "remoteLogFile", 1.657 + "help": "Name of log file on the device relative to the device root. \ 1.658 + PLEASE ONLY USE A FILENAME.", 1.659 + "default" : None, 1.660 + }], 1.661 + [["--remote-webserver"], 1.662 + { "action": "store", 1.663 + "type": "string", 1.664 + "dest": "remoteWebServer", 1.665 + "help": "ip address where the remote web server is hosted at", 1.666 + "default": None, 1.667 + }], 1.668 + [["--http-port"], 1.669 + { "action": "store", 1.670 + "type": "string", 1.671 + "dest": "httpPort", 1.672 + "help": "ip address where the remote web server is hosted at", 1.673 + "default": None, 1.674 + }], 1.675 + [["--ssl-port"], 1.676 + { "action": "store", 1.677 + "type": "string", 1.678 + "dest": "sslPort", 1.679 + "help": "ip address where the remote web server is hosted at", 1.680 + "default": None, 1.681 + }], 1.682 + [["--gecko-path"], 1.683 + { "action": "store", 1.684 + "type": "string", 1.685 + "dest": "geckoPath", 1.686 + "help": "the path to a gecko distribution that should \ 1.687 + be installed on the emulator prior to test", 1.688 + "default": None, 1.689 + }], 1.690 + [["--profile"], 1.691 + { "action": "store", 1.692 + "type": "string", 1.693 + "dest": "profile", 1.694 + "help": "for desktop testing, the path to the \ 1.695 + gaia profile to use", 1.696 + "default": None, 1.697 + }], 1.698 + [["--logcat-dir"], 1.699 + { "action": "store", 1.700 + "type": "string", 1.701 + "dest": "logcat_dir", 1.702 + "help": "directory to store logcat dump files", 1.703 + "default": None, 1.704 + }], 1.705 + [['--busybox'], 1.706 + { "action": 'store', 1.707 + "type": 'string', 1.708 + "dest": 'busybox', 1.709 + "help": "Path to busybox binary to install on device", 1.710 + "default": None, 1.711 + }], 1.712 + [['--profile-data-dir'], 1.713 + { "action": 'store', 1.714 + "type": 'string', 1.715 + "dest": 'profile_data_dir', 1.716 + "help": "Path to a directory containing preference and other \ 1.717 + data to be installed into the profile", 1.718 + "default": os.path.join(here, 'profile_data'), 1.719 + }], 1.720 + ] 1.721 + 1.722 + def __init__(self): 1.723 + MochitestOptions.__init__(self) 1.724 + 1.725 + for option in self.b2g_options: 1.726 + self.add_option(*option[0], **option[1]) 1.727 + 1.728 + defaults = {} 1.729 + defaults["httpPort"] = DEFAULT_PORTS['http'] 1.730 + defaults["sslPort"] = DEFAULT_PORTS['https'] 1.731 + defaults["remoteTestRoot"] = "/data/local/tests" 1.732 + defaults["logFile"] = "mochitest.log" 1.733 + defaults["autorun"] = True 1.734 + defaults["closeWhenDone"] = True 1.735 + defaults["testPath"] = "" 1.736 + defaults["extensionsToExclude"] = ["specialpowers"] 1.737 + self.set_defaults(**defaults) 1.738 + 1.739 + def verifyRemoteOptions(self, options): 1.740 + if options.remoteWebServer == None: 1.741 + if os.name != "nt": 1.742 + options.remoteWebServer = moznetwork.get_ip() 1.743 + else: 1.744 + self.error("You must specify a --remote-webserver=<ip address>") 1.745 + options.webServer = options.remoteWebServer 1.746 + 1.747 + if options.geckoPath and not options.emulator: 1.748 + self.error("You must specify --emulator if you specify --gecko-path") 1.749 + 1.750 + if options.logcat_dir and not options.emulator: 1.751 + self.error("You must specify --emulator if you specify --logcat-dir") 1.752 + 1.753 + if not os.path.isdir(options.xrePath): 1.754 + self.error("--xre-path '%s' is not a directory" % options.xrePath) 1.755 + xpcshell = os.path.join(options.xrePath, 'xpcshell') 1.756 + if not os.access(xpcshell, os.F_OK): 1.757 + self.error('xpcshell not found at %s' % xpcshell) 1.758 + if self.elf_arm(xpcshell): 1.759 + self.error('--xre-path points to an ARM version of xpcshell; it ' 1.760 + 'should instead point to a version that can run on ' 1.761 + 'your desktop') 1.762 + 1.763 + if options.pidFile != "": 1.764 + f = open(options.pidFile, 'w') 1.765 + f.write("%s" % os.getpid()) 1.766 + f.close() 1.767 + 1.768 + return options 1.769 + 1.770 + def verifyOptions(self, options, mochitest): 1.771 + # since we are reusing verifyOptions, it will exit if App is not found 1.772 + temp = options.app 1.773 + options.app = __file__ 1.774 + tempPort = options.httpPort 1.775 + tempSSL = options.sslPort 1.776 + tempIP = options.webServer 1.777 + options = MochitestOptions.verifyOptions(self, options, mochitest) 1.778 + options.webServer = tempIP 1.779 + options.app = temp 1.780 + options.sslPort = tempSSL 1.781 + options.httpPort = tempPort 1.782 + 1.783 + return options 1.784 + 1.785 + def elf_arm(self, filename): 1.786 + data = open(filename, 'rb').read(20) 1.787 + return data[:4] == "\x7fELF" and ord(data[18]) == 40 # EM_ARM