testing/mochitest/mochitest_options.py

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial