testing/mochitest/mochitest_options.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4
michael@0 5 import mozinfo
michael@0 6 import moznetwork
michael@0 7 import optparse
michael@0 8 import os
michael@0 9 import tempfile
michael@0 10
michael@0 11 from automationutils import addCommonOptions, isURL
michael@0 12 from mozprofile import DEFAULT_PORTS
michael@0 13
michael@0 14 here = os.path.abspath(os.path.dirname(__file__))
michael@0 15
michael@0 16 try:
michael@0 17 from mozbuild.base import MozbuildObject
michael@0 18 build_obj = MozbuildObject.from_environment(cwd=here)
michael@0 19 except ImportError:
michael@0 20 build_obj = None
michael@0 21
michael@0 22 __all__ = ["MochitestOptions", "B2GOptions"]
michael@0 23
michael@0 24 VMWARE_RECORDING_HELPER_BASENAME = "vmwarerecordinghelper"
michael@0 25
michael@0 26 class MochitestOptions(optparse.OptionParser):
michael@0 27 """Usage instructions for runtests.py.
michael@0 28 All arguments are optional.
michael@0 29 If --chrome is specified, chrome tests will be run instead of web content tests.
michael@0 30 If --browser-chrome is specified, browser-chrome tests will be run instead of web content tests.
michael@0 31 See <http://mochikit.com/doc/html/MochiKit/Logging.html> for details on the logging levels.
michael@0 32 """
michael@0 33
michael@0 34 LOG_LEVELS = ("DEBUG", "INFO", "WARNING", "ERROR", "FATAL")
michael@0 35 LEVEL_STRING = ", ".join(LOG_LEVELS)
michael@0 36 mochitest_options = [
michael@0 37 [["--close-when-done"],
michael@0 38 { "action": "store_true",
michael@0 39 "dest": "closeWhenDone",
michael@0 40 "default": False,
michael@0 41 "help": "close the application when tests are done running",
michael@0 42 }],
michael@0 43 [["--appname"],
michael@0 44 { "action": "store",
michael@0 45 "type": "string",
michael@0 46 "dest": "app",
michael@0 47 "default": None,
michael@0 48 "help": "absolute path to application, overriding default",
michael@0 49 }],
michael@0 50 [["--utility-path"],
michael@0 51 { "action": "store",
michael@0 52 "type": "string",
michael@0 53 "dest": "utilityPath",
michael@0 54 "default": build_obj.bindir if build_obj is not None else None,
michael@0 55 "help": "absolute path to directory containing utility programs (xpcshell, ssltunnel, certutil)",
michael@0 56 }],
michael@0 57 [["--certificate-path"],
michael@0 58 { "action": "store",
michael@0 59 "type": "string",
michael@0 60 "dest": "certPath",
michael@0 61 "help": "absolute path to directory containing certificate store to use testing profile",
michael@0 62 "default": os.path.join(build_obj.topsrcdir, 'build', 'pgo', 'certs') if build_obj is not None else None,
michael@0 63 }],
michael@0 64 [["--log-file"],
michael@0 65 { "action": "store",
michael@0 66 "type": "string",
michael@0 67 "dest": "logFile",
michael@0 68 "metavar": "FILE",
michael@0 69 "help": "file to which logging occurs",
michael@0 70 "default": "",
michael@0 71 }],
michael@0 72 [["--hide-subtests"],
michael@0 73 { "action": "store_true",
michael@0 74 "dest": "hide_subtests",
michael@0 75 "help": "only show subtest log output if there was a failure",
michael@0 76 "default": False,
michael@0 77 }],
michael@0 78 [["--autorun"],
michael@0 79 { "action": "store_true",
michael@0 80 "dest": "autorun",
michael@0 81 "help": "start running tests when the application starts",
michael@0 82 "default": False,
michael@0 83 }],
michael@0 84 [["--timeout"],
michael@0 85 { "type": "int",
michael@0 86 "dest": "timeout",
michael@0 87 "help": "per-test timeout in seconds",
michael@0 88 "default": None,
michael@0 89 }],
michael@0 90 [["--total-chunks"],
michael@0 91 { "type": "int",
michael@0 92 "dest": "totalChunks",
michael@0 93 "help": "how many chunks to split the tests up into",
michael@0 94 "default": None,
michael@0 95 }],
michael@0 96 [["--this-chunk"],
michael@0 97 { "type": "int",
michael@0 98 "dest": "thisChunk",
michael@0 99 "help": "which chunk to run",
michael@0 100 "default": None,
michael@0 101 }],
michael@0 102 [["--chunk-by-dir"],
michael@0 103 { "type": "int",
michael@0 104 "dest": "chunkByDir",
michael@0 105 "help": "group tests together in the same chunk that are in the same top chunkByDir directories",
michael@0 106 "default": 0,
michael@0 107 }],
michael@0 108 [["--shuffle"],
michael@0 109 { "dest": "shuffle",
michael@0 110 "action": "store_true",
michael@0 111 "help": "randomize test order",
michael@0 112 "default": False,
michael@0 113 }],
michael@0 114 [["--console-level"],
michael@0 115 { "action": "store",
michael@0 116 "type": "choice",
michael@0 117 "dest": "consoleLevel",
michael@0 118 "choices": LOG_LEVELS,
michael@0 119 "metavar": "LEVEL",
michael@0 120 "help": "one of %s to determine the level of console "
michael@0 121 "logging" % LEVEL_STRING,
michael@0 122 "default": None,
michael@0 123 }],
michael@0 124 [["--file-level"],
michael@0 125 { "action": "store",
michael@0 126 "type": "choice",
michael@0 127 "dest": "fileLevel",
michael@0 128 "choices": LOG_LEVELS,
michael@0 129 "metavar": "LEVEL",
michael@0 130 "help": "one of %s to determine the level of file "
michael@0 131 "logging if a file has been specified, defaulting "
michael@0 132 "to INFO" % LEVEL_STRING,
michael@0 133 "default": "INFO",
michael@0 134 }],
michael@0 135 [["--chrome"],
michael@0 136 { "action": "store_true",
michael@0 137 "dest": "chrome",
michael@0 138 "help": "run chrome Mochitests",
michael@0 139 "default": False,
michael@0 140 }],
michael@0 141 [["--ipcplugins"],
michael@0 142 { "action": "store_true",
michael@0 143 "dest": "ipcplugins",
michael@0 144 "help": "run ipcplugins Mochitests",
michael@0 145 "default": False,
michael@0 146 }],
michael@0 147 [["--test-path"],
michael@0 148 { "action": "store",
michael@0 149 "type": "string",
michael@0 150 "dest": "testPath",
michael@0 151 "help": "start in the given directory's tests",
michael@0 152 "default": "",
michael@0 153 }],
michael@0 154 [["--start-at"],
michael@0 155 { "action": "store",
michael@0 156 "type": "string",
michael@0 157 "dest": "startAt",
michael@0 158 "help": "skip over tests until reaching the given test",
michael@0 159 "default": "",
michael@0 160 }],
michael@0 161 [["--end-at"],
michael@0 162 { "action": "store",
michael@0 163 "type": "string",
michael@0 164 "dest": "endAt",
michael@0 165 "help": "don't run any tests after the given one",
michael@0 166 "default": "",
michael@0 167 }],
michael@0 168 [["--browser-chrome"],
michael@0 169 { "action": "store_true",
michael@0 170 "dest": "browserChrome",
michael@0 171 "help": "run browser chrome Mochitests",
michael@0 172 "default": False,
michael@0 173 }],
michael@0 174 [["--subsuite"],
michael@0 175 { "action": "store",
michael@0 176 "dest": "subsuite",
michael@0 177 "help": "subsuite of tests to run",
michael@0 178 "default": "",
michael@0 179 }],
michael@0 180 [["--webapprt-content"],
michael@0 181 { "action": "store_true",
michael@0 182 "dest": "webapprtContent",
michael@0 183 "help": "run WebappRT content tests",
michael@0 184 "default": False,
michael@0 185 }],
michael@0 186 [["--webapprt-chrome"],
michael@0 187 { "action": "store_true",
michael@0 188 "dest": "webapprtChrome",
michael@0 189 "help": "run WebappRT chrome tests",
michael@0 190 "default": False,
michael@0 191 }],
michael@0 192 [["--a11y"],
michael@0 193 { "action": "store_true",
michael@0 194 "dest": "a11y",
michael@0 195 "help": "run accessibility Mochitests",
michael@0 196 "default": False,
michael@0 197 }],
michael@0 198 [["--setenv"],
michael@0 199 { "action": "append",
michael@0 200 "type": "string",
michael@0 201 "dest": "environment",
michael@0 202 "metavar": "NAME=VALUE",
michael@0 203 "help": "sets the given variable in the application's "
michael@0 204 "environment",
michael@0 205 "default": [],
michael@0 206 }],
michael@0 207 [["--exclude-extension"],
michael@0 208 { "action": "append",
michael@0 209 "type": "string",
michael@0 210 "dest": "extensionsToExclude",
michael@0 211 "help": "excludes the given extension from being installed "
michael@0 212 "in the test profile",
michael@0 213 "default": [],
michael@0 214 }],
michael@0 215 [["--browser-arg"],
michael@0 216 { "action": "append",
michael@0 217 "type": "string",
michael@0 218 "dest": "browserArgs",
michael@0 219 "metavar": "ARG",
michael@0 220 "help": "provides an argument to the test application",
michael@0 221 "default": [],
michael@0 222 }],
michael@0 223 [["--leak-threshold"],
michael@0 224 { "action": "store",
michael@0 225 "type": "int",
michael@0 226 "dest": "leakThreshold",
michael@0 227 "metavar": "THRESHOLD",
michael@0 228 "help": "fail if the number of bytes leaked through "
michael@0 229 "refcounted objects (or bytes in classes with "
michael@0 230 "MOZ_COUNT_CTOR and MOZ_COUNT_DTOR) is greater "
michael@0 231 "than the given number",
michael@0 232 "default": 0,
michael@0 233 }],
michael@0 234 [["--fatal-assertions"],
michael@0 235 { "action": "store_true",
michael@0 236 "dest": "fatalAssertions",
michael@0 237 "help": "abort testing whenever an assertion is hit "
michael@0 238 "(requires a debug build to be effective)",
michael@0 239 "default": False,
michael@0 240 }],
michael@0 241 [["--extra-profile-file"],
michael@0 242 { "action": "append",
michael@0 243 "dest": "extraProfileFiles",
michael@0 244 "help": "copy specified files/dirs to testing profile",
michael@0 245 "default": [],
michael@0 246 }],
michael@0 247 [["--install-extension"],
michael@0 248 { "action": "append",
michael@0 249 "dest": "extensionsToInstall",
michael@0 250 "help": "install the specified extension in the testing profile."
michael@0 251 "The extension file's name should be <id>.xpi where <id> is"
michael@0 252 "the extension's id as indicated in its install.rdf."
michael@0 253 "An optional path can be specified too.",
michael@0 254 "default": [],
michael@0 255 }],
michael@0 256 [["--profile-path"],
michael@0 257 { "action": "store",
michael@0 258 "type": "string",
michael@0 259 "dest": "profilePath",
michael@0 260 "help": "Directory where the profile will be stored."
michael@0 261 "This directory will be deleted after the tests are finished",
michael@0 262 "default": tempfile.mkdtemp(),
michael@0 263 }],
michael@0 264 [["--testing-modules-dir"],
michael@0 265 { "action": "store",
michael@0 266 "type": "string",
michael@0 267 "dest": "testingModulesDir",
michael@0 268 "help": "Directory where testing-only JS modules are located.",
michael@0 269 "default": None,
michael@0 270 }],
michael@0 271 [["--use-vmware-recording"],
michael@0 272 { "action": "store_true",
michael@0 273 "dest": "vmwareRecording",
michael@0 274 "help": "enables recording while the application is running "
michael@0 275 "inside a VMware Workstation 7.0 or later VM",
michael@0 276 "default": False,
michael@0 277 }],
michael@0 278 [["--repeat"],
michael@0 279 { "action": "store",
michael@0 280 "type": "int",
michael@0 281 "dest": "repeat",
michael@0 282 "metavar": "REPEAT",
michael@0 283 "help": "repeats the test or set of tests the given number of times, ie: repeat: 1 will run the test twice.",
michael@0 284 "default": 0,
michael@0 285 }],
michael@0 286 [["--run-until-failure"],
michael@0 287 { "action": "store_true",
michael@0 288 "dest": "runUntilFailure",
michael@0 289 "help": "Run tests repeatedly and stops on the first time a test fails. "
michael@0 290 "Default cap is 30 runs, which can be overwritten with the --repeat parameter.",
michael@0 291 "default": False,
michael@0 292 }],
michael@0 293 [["--run-only-tests"],
michael@0 294 { "action": "store",
michael@0 295 "type": "string",
michael@0 296 "dest": "runOnlyTests",
michael@0 297 "help": "JSON list of tests that we only want to run. [DEPRECATED- please use --test-manifest]",
michael@0 298 "default": None,
michael@0 299 }],
michael@0 300 [["--test-manifest"],
michael@0 301 { "action": "store",
michael@0 302 "type": "string",
michael@0 303 "dest": "testManifest",
michael@0 304 "help": "JSON list of tests to specify 'runtests'. Old format for mobile specific tests",
michael@0 305 "default": None,
michael@0 306 }],
michael@0 307 [["--manifest"],
michael@0 308 { "action": "store",
michael@0 309 "type": "string",
michael@0 310 "dest": "manifestFile",
michael@0 311 "help": ".ini format of tests to run.",
michael@0 312 "default": None,
michael@0 313 }],
michael@0 314 [["--failure-file"],
michael@0 315 { "action": "store",
michael@0 316 "type": "string",
michael@0 317 "dest": "failureFile",
michael@0 318 "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.",
michael@0 319 "default": None,
michael@0 320 }],
michael@0 321 [["--run-slower"],
michael@0 322 { "action": "store_true",
michael@0 323 "dest": "runSlower",
michael@0 324 "help": "Delay execution between test files.",
michael@0 325 "default": False,
michael@0 326 }],
michael@0 327 [["--metro-immersive"],
michael@0 328 { "action": "store_true",
michael@0 329 "dest": "immersiveMode",
michael@0 330 "help": "launches tests in immersive browser",
michael@0 331 "default": False,
michael@0 332 }],
michael@0 333 [["--httpd-path"],
michael@0 334 { "action": "store",
michael@0 335 "type": "string",
michael@0 336 "dest": "httpdPath",
michael@0 337 "default": None,
michael@0 338 "help": "path to the httpd.js file",
michael@0 339 }],
michael@0 340 [["--setpref"],
michael@0 341 { "action": "append",
michael@0 342 "type": "string",
michael@0 343 "default": [],
michael@0 344 "dest": "extraPrefs",
michael@0 345 "metavar": "PREF=VALUE",
michael@0 346 "help": "defines an extra user preference",
michael@0 347 }],
michael@0 348 [["--jsdebugger"],
michael@0 349 { "action": "store_true",
michael@0 350 "default": False,
michael@0 351 "dest": "jsdebugger",
michael@0 352 "help": "open the browser debugger",
michael@0 353 }],
michael@0 354 [["--debug-on-failure"],
michael@0 355 { "action": "store_true",
michael@0 356 "default": False,
michael@0 357 "dest": "debugOnFailure",
michael@0 358 "help": "breaks execution and enters the JS debugger on a test failure. Should be used together with --jsdebugger."
michael@0 359 }],
michael@0 360 [["--e10s"],
michael@0 361 { "action": "store_true",
michael@0 362 "default": False,
michael@0 363 "dest": "e10s",
michael@0 364 "help": "Run tests with electrolysis preferences and test filtering enabled.",
michael@0 365 }],
michael@0 366 [["--dmd-path"],
michael@0 367 { "action": "store",
michael@0 368 "default": None,
michael@0 369 "dest": "dmdPath",
michael@0 370 "help": "Specifies the path to the directory containing the shared library for DMD.",
michael@0 371 }],
michael@0 372 [["--dump-output-directory"],
michael@0 373 { "action": "store",
michael@0 374 "default": None,
michael@0 375 "dest": "dumpOutputDirectory",
michael@0 376 "help": "Specifies the directory in which to place dumped memory reports.",
michael@0 377 }],
michael@0 378 [["--dump-about-memory-after-test"],
michael@0 379 { "action": "store_true",
michael@0 380 "default": False,
michael@0 381 "dest": "dumpAboutMemoryAfterTest",
michael@0 382 "help": "Produce an about:memory dump after each test in the directory specified "
michael@0 383 "by --dump-output-directory."
michael@0 384 }],
michael@0 385 [["--dump-dmd-after-test"],
michael@0 386 { "action": "store_true",
michael@0 387 "default": False,
michael@0 388 "dest": "dumpDMDAfterTest",
michael@0 389 "help": "Produce a DMD dump after each test in the directory specified "
michael@0 390 "by --dump-output-directory."
michael@0 391 }],
michael@0 392 [["--slowscript"],
michael@0 393 { "action": "store_true",
michael@0 394 "default": False,
michael@0 395 "dest": "slowscript",
michael@0 396 "help": "Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; "
michael@0 397 "when not set, recoverable but misleading SIGSEGV instances "
michael@0 398 "may occur in Ion/Odin JIT code."
michael@0 399 }],
michael@0 400 [["--screenshot-on-fail"],
michael@0 401 { "action": "store_true",
michael@0 402 "default": False,
michael@0 403 "dest": "screenshotOnFail",
michael@0 404 "help": "Take screenshots on all test failures. Set $MOZ_UPLOAD_DIR to a directory for storing the screenshots."
michael@0 405 }],
michael@0 406 [["--quiet"],
michael@0 407 { "action": "store_true",
michael@0 408 "default": False,
michael@0 409 "dest": "quiet",
michael@0 410 "help": "Do not print test log lines unless a failure occurs."
michael@0 411 }],
michael@0 412 [["--pidfile"],
michael@0 413 { "action": "store",
michael@0 414 "type": "string",
michael@0 415 "dest": "pidFile",
michael@0 416 "help": "name of the pidfile to generate",
michael@0 417 "default": "",
michael@0 418 }],
michael@0 419 ]
michael@0 420
michael@0 421 def __init__(self, **kwargs):
michael@0 422
michael@0 423 optparse.OptionParser.__init__(self, **kwargs)
michael@0 424 for option, value in self.mochitest_options:
michael@0 425 self.add_option(*option, **value)
michael@0 426 addCommonOptions(self)
michael@0 427 self.set_usage(self.__doc__)
michael@0 428
michael@0 429 def verifyOptions(self, options, mochitest):
michael@0 430 """ verify correct options and cleanup paths """
michael@0 431
michael@0 432 mozinfo.update({"e10s": options.e10s}) # for test manifest parsing.
michael@0 433
michael@0 434 if options.app is None:
michael@0 435 if build_obj is not None:
michael@0 436 options.app = build_obj.get_binary_path()
michael@0 437 else:
michael@0 438 self.error("could not find the application path, --appname must be specified")
michael@0 439
michael@0 440 if options.totalChunks is not None and options.thisChunk is None:
michael@0 441 self.error("thisChunk must be specified when totalChunks is specified")
michael@0 442
michael@0 443 if options.totalChunks:
michael@0 444 if not 1 <= options.thisChunk <= options.totalChunks:
michael@0 445 self.error("thisChunk must be between 1 and totalChunks")
michael@0 446
michael@0 447 if options.xrePath is None:
michael@0 448 # default xrePath to the app path if not provided
michael@0 449 # but only if an app path was explicitly provided
michael@0 450 if options.app != self.defaults['app']:
michael@0 451 options.xrePath = os.path.dirname(options.app)
michael@0 452 elif build_obj is not None:
michael@0 453 # otherwise default to dist/bin
michael@0 454 options.xrePath = build_obj.bindir
michael@0 455 else:
michael@0 456 self.error("could not find xre directory, --xre-path must be specified")
michael@0 457
michael@0 458 # allow relative paths
michael@0 459 options.xrePath = mochitest.getFullPath(options.xrePath)
michael@0 460 options.profilePath = mochitest.getFullPath(options.profilePath)
michael@0 461 options.app = mochitest.getFullPath(options.app)
michael@0 462 if options.dmdPath is not None:
michael@0 463 options.dmdPath = mochitest.getFullPath(options.dmdPath)
michael@0 464
michael@0 465 if not os.path.exists(options.app):
michael@0 466 msg = """\
michael@0 467 Error: Path %(app)s doesn't exist.
michael@0 468 Are you executing $objdir/_tests/testing/mochitest/runtests.py?"""
michael@0 469 self.error(msg % {"app": options.app})
michael@0 470 return None
michael@0 471
michael@0 472 if options.utilityPath:
michael@0 473 options.utilityPath = mochitest.getFullPath(options.utilityPath)
michael@0 474
michael@0 475 if options.certPath:
michael@0 476 options.certPath = mochitest.getFullPath(options.certPath)
michael@0 477
michael@0 478 if options.symbolsPath and not isURL(options.symbolsPath):
michael@0 479 options.symbolsPath = mochitest.getFullPath(options.symbolsPath)
michael@0 480
michael@0 481 # Set server information on the options object
michael@0 482 options.webServer = '127.0.0.1'
michael@0 483 options.httpPort = DEFAULT_PORTS['http']
michael@0 484 options.sslPort = DEFAULT_PORTS['https']
michael@0 485 # options.webSocketPort = DEFAULT_PORTS['ws']
michael@0 486 options.webSocketPort = str(9988) # <- http://hg.mozilla.org/mozilla-central/file/b871dfb2186f/build/automation.py.in#l30
michael@0 487 # The default websocket port is incorrect in mozprofile; it is
michael@0 488 # set to the SSL proxy setting. See:
michael@0 489 # see https://bugzilla.mozilla.org/show_bug.cgi?id=916517
michael@0 490
michael@0 491 if options.vmwareRecording:
michael@0 492 if not mozinfo.isWin:
michael@0 493 self.error("use-vmware-recording is only supported on Windows.")
michael@0 494 mochitest.vmwareHelperPath = os.path.join(
michael@0 495 options.utilityPath, VMWARE_RECORDING_HELPER_BASENAME + ".dll")
michael@0 496 if not os.path.exists(mochitest.vmwareHelperPath):
michael@0 497 self.error("%s not found, cannot automate VMware recording." %
michael@0 498 mochitest.vmwareHelperPath)
michael@0 499
michael@0 500 if options.testManifest and options.runOnlyTests:
michael@0 501 self.error("Please use --test-manifest only and not --run-only-tests")
michael@0 502
michael@0 503 if options.runOnlyTests:
michael@0 504 if not os.path.exists(os.path.abspath(os.path.join(here, options.runOnlyTests))):
michael@0 505 self.error("unable to find --run-only-tests file '%s'" % options.runOnlyTests)
michael@0 506 options.runOnly = True
michael@0 507 options.testManifest = options.runOnlyTests
michael@0 508 options.runOnlyTests = None
michael@0 509
michael@0 510 if options.manifestFile and options.testManifest:
michael@0 511 self.error("Unable to support both --manifest and --test-manifest/--run-only-tests at the same time")
michael@0 512
michael@0 513 if options.webapprtContent and options.webapprtChrome:
michael@0 514 self.error("Only one of --webapprt-content and --webapprt-chrome may be given.")
michael@0 515
michael@0 516 if options.jsdebugger:
michael@0 517 options.extraPrefs += [
michael@0 518 "devtools.debugger.remote-enabled=true",
michael@0 519 "devtools.debugger.chrome-enabled=true",
michael@0 520 "devtools.chrome.enabled=true",
michael@0 521 "devtools.debugger.prompt-connection=false"
michael@0 522 ]
michael@0 523 options.autorun = False
michael@0 524
michael@0 525 if options.debugOnFailure and not options.jsdebugger:
michael@0 526 self.error("--debug-on-failure should be used together with --jsdebugger.")
michael@0 527
michael@0 528 # Try to guess the testing modules directory.
michael@0 529 # This somewhat grotesque hack allows the buildbot machines to find the
michael@0 530 # modules directory without having to configure the buildbot hosts. This
michael@0 531 # code should never be executed in local runs because the build system
michael@0 532 # should always set the flag that populates this variable. If buildbot ever
michael@0 533 # passes this argument, this code can be deleted.
michael@0 534 if options.testingModulesDir is None:
michael@0 535 possible = os.path.join(here, os.path.pardir, 'modules')
michael@0 536
michael@0 537 if os.path.isdir(possible):
michael@0 538 options.testingModulesDir = possible
michael@0 539
michael@0 540 # Even if buildbot is updated, we still want this, as the path we pass in
michael@0 541 # to the app must be absolute and have proper slashes.
michael@0 542 if options.testingModulesDir is not None:
michael@0 543 options.testingModulesDir = os.path.normpath(options.testingModulesDir)
michael@0 544
michael@0 545 if not os.path.isabs(options.testingModulesDir):
michael@0 546 options.testingModulesDir = os.path.abspath(options.testingModulesDir)
michael@0 547
michael@0 548 if not os.path.isdir(options.testingModulesDir):
michael@0 549 self.error('--testing-modules-dir not a directory: %s' %
michael@0 550 options.testingModulesDir)
michael@0 551
michael@0 552 options.testingModulesDir = options.testingModulesDir.replace('\\', '/')
michael@0 553 if options.testingModulesDir[-1] != '/':
michael@0 554 options.testingModulesDir += '/'
michael@0 555
michael@0 556 if options.immersiveMode:
michael@0 557 if not mozinfo.isWin:
michael@0 558 self.error("immersive is only supported on Windows 8 and up.")
michael@0 559 mochitest.immersiveHelperPath = os.path.join(
michael@0 560 options.utilityPath, "metrotestharness.exe")
michael@0 561 if not os.path.exists(mochitest.immersiveHelperPath):
michael@0 562 self.error("%s not found, cannot launch immersive tests." %
michael@0 563 mochitest.immersiveHelperPath)
michael@0 564
michael@0 565 if options.runUntilFailure:
michael@0 566 if not options.repeat:
michael@0 567 options.repeat = 29
michael@0 568
michael@0 569 if options.dumpOutputDirectory is None:
michael@0 570 options.dumpOutputDirectory = tempfile.gettempdir()
michael@0 571
michael@0 572 if options.dumpAboutMemoryAfterTest or options.dumpDMDAfterTest:
michael@0 573 if not os.path.isdir(options.dumpOutputDirectory):
michael@0 574 self.error('--dump-output-directory not a directory: %s' %
michael@0 575 options.dumpOutputDirectory)
michael@0 576
michael@0 577 return options
michael@0 578
michael@0 579
michael@0 580 class B2GOptions(MochitestOptions):
michael@0 581 b2g_options = [
michael@0 582 [["--b2gpath"],
michael@0 583 { "action": "store",
michael@0 584 "type": "string",
michael@0 585 "dest": "b2gPath",
michael@0 586 "help": "path to B2G repo or qemu dir",
michael@0 587 "default": None,
michael@0 588 }],
michael@0 589 [["--desktop"],
michael@0 590 { "action": "store_true",
michael@0 591 "dest": "desktop",
michael@0 592 "help": "Run the tests on a B2G desktop build",
michael@0 593 "default": False,
michael@0 594 }],
michael@0 595 [["--marionette"],
michael@0 596 { "action": "store",
michael@0 597 "type": "string",
michael@0 598 "dest": "marionette",
michael@0 599 "help": "host:port to use when connecting to Marionette",
michael@0 600 "default": None,
michael@0 601 }],
michael@0 602 [["--emulator"],
michael@0 603 { "action": "store",
michael@0 604 "type": "string",
michael@0 605 "dest": "emulator",
michael@0 606 "help": "Architecture of emulator to use: x86 or arm",
michael@0 607 "default": None,
michael@0 608 }],
michael@0 609 [["--wifi"],
michael@0 610 { "action": "store",
michael@0 611 "type": "string",
michael@0 612 "dest": "wifi",
michael@0 613 "help": "Devine wifi configuration for on device mochitest",
michael@0 614 "default": False,
michael@0 615 }],
michael@0 616 [["--sdcard"],
michael@0 617 { "action": "store",
michael@0 618 "type": "string",
michael@0 619 "dest": "sdcard",
michael@0 620 "help": "Define size of sdcard: 1MB, 50MB...etc",
michael@0 621 "default": "10MB",
michael@0 622 }],
michael@0 623 [["--no-window"],
michael@0 624 { "action": "store_true",
michael@0 625 "dest": "noWindow",
michael@0 626 "help": "Pass --no-window to the emulator",
michael@0 627 "default": False,
michael@0 628 }],
michael@0 629 [["--adbpath"],
michael@0 630 { "action": "store",
michael@0 631 "type": "string",
michael@0 632 "dest": "adbPath",
michael@0 633 "help": "path to adb",
michael@0 634 "default": "adb",
michael@0 635 }],
michael@0 636 [["--deviceIP"],
michael@0 637 { "action": "store",
michael@0 638 "type": "string",
michael@0 639 "dest": "deviceIP",
michael@0 640 "help": "ip address of remote device to test",
michael@0 641 "default": None,
michael@0 642 }],
michael@0 643 [["--devicePort"],
michael@0 644 { "action": "store",
michael@0 645 "type": "string",
michael@0 646 "dest": "devicePort",
michael@0 647 "help": "port of remote device to test",
michael@0 648 "default": 20701,
michael@0 649 }],
michael@0 650 [["--remote-logfile"],
michael@0 651 { "action": "store",
michael@0 652 "type": "string",
michael@0 653 "dest": "remoteLogFile",
michael@0 654 "help": "Name of log file on the device relative to the device root. \
michael@0 655 PLEASE ONLY USE A FILENAME.",
michael@0 656 "default" : None,
michael@0 657 }],
michael@0 658 [["--remote-webserver"],
michael@0 659 { "action": "store",
michael@0 660 "type": "string",
michael@0 661 "dest": "remoteWebServer",
michael@0 662 "help": "ip address where the remote web server is hosted at",
michael@0 663 "default": None,
michael@0 664 }],
michael@0 665 [["--http-port"],
michael@0 666 { "action": "store",
michael@0 667 "type": "string",
michael@0 668 "dest": "httpPort",
michael@0 669 "help": "ip address where the remote web server is hosted at",
michael@0 670 "default": None,
michael@0 671 }],
michael@0 672 [["--ssl-port"],
michael@0 673 { "action": "store",
michael@0 674 "type": "string",
michael@0 675 "dest": "sslPort",
michael@0 676 "help": "ip address where the remote web server is hosted at",
michael@0 677 "default": None,
michael@0 678 }],
michael@0 679 [["--gecko-path"],
michael@0 680 { "action": "store",
michael@0 681 "type": "string",
michael@0 682 "dest": "geckoPath",
michael@0 683 "help": "the path to a gecko distribution that should \
michael@0 684 be installed on the emulator prior to test",
michael@0 685 "default": None,
michael@0 686 }],
michael@0 687 [["--profile"],
michael@0 688 { "action": "store",
michael@0 689 "type": "string",
michael@0 690 "dest": "profile",
michael@0 691 "help": "for desktop testing, the path to the \
michael@0 692 gaia profile to use",
michael@0 693 "default": None,
michael@0 694 }],
michael@0 695 [["--logcat-dir"],
michael@0 696 { "action": "store",
michael@0 697 "type": "string",
michael@0 698 "dest": "logcat_dir",
michael@0 699 "help": "directory to store logcat dump files",
michael@0 700 "default": None,
michael@0 701 }],
michael@0 702 [['--busybox'],
michael@0 703 { "action": 'store',
michael@0 704 "type": 'string',
michael@0 705 "dest": 'busybox',
michael@0 706 "help": "Path to busybox binary to install on device",
michael@0 707 "default": None,
michael@0 708 }],
michael@0 709 [['--profile-data-dir'],
michael@0 710 { "action": 'store',
michael@0 711 "type": 'string',
michael@0 712 "dest": 'profile_data_dir',
michael@0 713 "help": "Path to a directory containing preference and other \
michael@0 714 data to be installed into the profile",
michael@0 715 "default": os.path.join(here, 'profile_data'),
michael@0 716 }],
michael@0 717 ]
michael@0 718
michael@0 719 def __init__(self):
michael@0 720 MochitestOptions.__init__(self)
michael@0 721
michael@0 722 for option in self.b2g_options:
michael@0 723 self.add_option(*option[0], **option[1])
michael@0 724
michael@0 725 defaults = {}
michael@0 726 defaults["httpPort"] = DEFAULT_PORTS['http']
michael@0 727 defaults["sslPort"] = DEFAULT_PORTS['https']
michael@0 728 defaults["remoteTestRoot"] = "/data/local/tests"
michael@0 729 defaults["logFile"] = "mochitest.log"
michael@0 730 defaults["autorun"] = True
michael@0 731 defaults["closeWhenDone"] = True
michael@0 732 defaults["testPath"] = ""
michael@0 733 defaults["extensionsToExclude"] = ["specialpowers"]
michael@0 734 self.set_defaults(**defaults)
michael@0 735
michael@0 736 def verifyRemoteOptions(self, options):
michael@0 737 if options.remoteWebServer == None:
michael@0 738 if os.name != "nt":
michael@0 739 options.remoteWebServer = moznetwork.get_ip()
michael@0 740 else:
michael@0 741 self.error("You must specify a --remote-webserver=<ip address>")
michael@0 742 options.webServer = options.remoteWebServer
michael@0 743
michael@0 744 if options.geckoPath and not options.emulator:
michael@0 745 self.error("You must specify --emulator if you specify --gecko-path")
michael@0 746
michael@0 747 if options.logcat_dir and not options.emulator:
michael@0 748 self.error("You must specify --emulator if you specify --logcat-dir")
michael@0 749
michael@0 750 if not os.path.isdir(options.xrePath):
michael@0 751 self.error("--xre-path '%s' is not a directory" % options.xrePath)
michael@0 752 xpcshell = os.path.join(options.xrePath, 'xpcshell')
michael@0 753 if not os.access(xpcshell, os.F_OK):
michael@0 754 self.error('xpcshell not found at %s' % xpcshell)
michael@0 755 if self.elf_arm(xpcshell):
michael@0 756 self.error('--xre-path points to an ARM version of xpcshell; it '
michael@0 757 'should instead point to a version that can run on '
michael@0 758 'your desktop')
michael@0 759
michael@0 760 if options.pidFile != "":
michael@0 761 f = open(options.pidFile, 'w')
michael@0 762 f.write("%s" % os.getpid())
michael@0 763 f.close()
michael@0 764
michael@0 765 return options
michael@0 766
michael@0 767 def verifyOptions(self, options, mochitest):
michael@0 768 # since we are reusing verifyOptions, it will exit if App is not found
michael@0 769 temp = options.app
michael@0 770 options.app = __file__
michael@0 771 tempPort = options.httpPort
michael@0 772 tempSSL = options.sslPort
michael@0 773 tempIP = options.webServer
michael@0 774 options = MochitestOptions.verifyOptions(self, options, mochitest)
michael@0 775 options.webServer = tempIP
michael@0 776 options.app = temp
michael@0 777 options.sslPort = tempSSL
michael@0 778 options.httpPort = tempPort
michael@0 779
michael@0 780 return options
michael@0 781
michael@0 782 def elf_arm(self, filename):
michael@0 783 data = open(filename, 'rb').read(20)
michael@0 784 return data[:4] == "\x7fELF" and ord(data[18]) == 40 # EM_ARM

mercurial