Bug 521457. Add debugger options to runreftest.py and runxpcshelltests.py. r=ted

--HG--
extra : rebase_source : 420b33b1d44aae7361c25d8bcc15032c303aa80d
This commit is contained in:
Jonathan Griffin 2009-10-19 16:12:09 -07:00
Родитель 3255a6f7bb
Коммит 89b487b6ff
4 изменённых файлов: 112 добавлений и 81 удалений

Просмотреть файл

@ -44,8 +44,28 @@ __all__ = [
"checkForCrashes",
"dumpLeakLog",
"processLeakLog",
"getDebuggerInfo",
"DEBUGGER_INFO",
]
# Map of debugging programs to information about them, like default arguments
# and whether or not they are interactive.
DEBUGGER_INFO = {
# gdb requires that you supply the '--args' flag in order to pass arguments
# after the executable name to the executable.
"gdb": {
"interactive": True,
"args": "-q --args"
},
# valgrind doesn't explain much about leaks unless you set the
# '--leak-check=full' flag.
"valgrind": {
"interactive": False,
"args": "--leak-check=full"
}
}
log = logging.getLogger()
def addCommonOptions(parser, defaults={}):
@ -60,6 +80,17 @@ def addCommonOptions(parser, defaults={}):
action = "store", type = "string", dest = "symbolsPath",
default = defaults['SYMBOLS_PATH'],
help = "absolute path to directory containing breakpad symbols")
parser.add_option("--debugger",
action = "store", dest = "debugger",
help = "use the given debugger to launch the application")
parser.add_option("--debugger-args",
action = "store", dest = "debuggerArgs",
help = "pass the given args to the debugger _before_ "
"the application on the command line")
parser.add_option("--debugger-interactive",
action = "store_true", dest = "debuggerInteractive",
help = "prevents the test harness from redirecting "
"stdout and stderr for interactive debuggers")
def checkForCrashes(dumpDir, symbolsPath, testName=None):
stackwalkPath = os.environ.get('MINIDUMP_STACKWALK', None)
@ -91,6 +122,57 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None):
foundCrash = True
return foundCrash
def getFullPath(directory, path):
"Get an absolute path relative to 'directory'."
return os.path.normpath(os.path.join(directory, os.path.expanduser(path)))
def searchPath(directory, path):
"Go one step beyond getFullPath and try the various folders in PATH"
# Try looking in the current working directory first.
newpath = getFullPath(directory, path)
if os.path.exists(newpath):
return newpath
# At this point we have to fail if a directory was given (to prevent cases
# like './gdb' from matching '/usr/bin/./gdb').
if not os.path.dirname(path):
for dir in os.environ['PATH'].split(os.pathsep):
newpath = os.path.join(dir, path)
if os.path.exists(newpath):
return newpath
return None
def getDebuggerInfo(directory, debugger, debuggerArgs, debuggerInteractive = False):
debuggerInfo = None
if debugger:
debuggerPath = searchPath(directory, debugger)
if not debuggerPath:
print "Error: Path %s doesn't exist." % debugger
sys.exit(1)
debuggerName = os.path.basename(debuggerPath).lower()
def getDebuggerInfo(type, default):
if debuggerName in DEBUGGER_INFO and type in DEBUGGER_INFO[debuggerName]:
return DEBUGGER_INFO[debuggerName][type]
return default
debuggerInfo = {
"path": debuggerPath,
"interactive" : getDebuggerInfo("interactive", False),
"args": getDebuggerInfo("args", "").split()
}
if debuggerArgs:
debuggerInfo["args"] = debuggerArgs.split()
if debuggerInteractive:
debuggerInfo["interactive"] = debuggerInteractive
return debuggerInfo
def dumpLeakLog(leakLogFile, filter = False):
"""Process the leak log, without parsing it.

Просмотреть файл

@ -45,7 +45,7 @@ import sys, shutil, os, os.path
SCRIPT_DIRECTORY = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
sys.path.append(SCRIPT_DIRECTORY)
import automation
from automationutils import addCommonOptions, processLeakLog
from automationutils import *
from optparse import OptionParser
from tempfile import mkdtemp
@ -127,6 +127,9 @@ Are you executing $objdir/_tests/reftest/runreftest.py?""" \
options.symbolsPath = getFullPath(options.symbolsPath)
options.utilityPath = getFullPath(options.utilityPath)
debuggerInfo = getDebuggerInfo(oldcwd, options.debugger, options.debuggerArgs,
options.debuggerInteractive);
profileDir = None
try:
profileDir = mkdtemp()
@ -165,6 +168,7 @@ Are you executing $objdir/_tests/reftest/runreftest.py?""" \
["-reftest", reftestlist],
utilityPath = options.utilityPath,
xrePath=options.xrePath,
debuggerInfo=debuggerInfo,
symbolsPath=options.symbolsPath)
processLeakLog(leakLogFile, options.leakThreshold)
automation.log.info("\nREFTEST INFO | runreftest.py | Running tests: end.")

Просмотреть файл

@ -53,7 +53,7 @@ from urllib import quote_plus as encodeURIComponent
import urllib2
import commands
import automation
from automationutils import addCommonOptions, processLeakLog
from automationutils import *
# Path to the test script on the server
TEST_SERVER_HOST = "localhost:8888"
@ -87,24 +87,6 @@ PROFILE_DIRECTORY = os.path.abspath("./mochitesttestingprofile")
LEAK_REPORT_FILE = os.path.join(PROFILE_DIRECTORY, "runtests_leaks.log")
# Map of debugging programs to information about them, like default arguments
# and whether or not they are interactive.
DEBUGGER_INFO = {
# gdb requires that you supply the '--args' flag in order to pass arguments
# after the executable name to the executable.
"gdb": {
"interactive": True,
"args": "-q --args"
},
# valgrind doesn't explain much about leaks unless you set the
# '--leak-check=full' flag.
"valgrind": {
"interactive": False,
"args": "--leak-check=full"
}
}
#######################
# COMMANDLINE OPTIONS #
#######################
@ -251,20 +233,6 @@ class MochitestOptions(optparse.OptionParser):
help = "copy specified files/dirs to testing profile")
defaults["extraProfileFiles"] = []
self.add_option("--debugger",
action = "store", dest = "debugger",
help = "use the given debugger to launch the application")
self.add_option("--debugger-args",
action = "store", dest = "debuggerArgs",
help = "pass the given args to the debugger _before_ "
"the application on the command line")
self.add_option("--debugger-interactive",
action = "store_true", dest = "debuggerInteractive",
help = "prevents the test harness from redirecting stdout "
"and stderr for interactive debuggers")
# -h, --help are automatically handled by OptionParser
self.set_defaults(**defaults)
@ -342,22 +310,6 @@ def getFullPath(path):
"Get an absolute path relative to oldcwd."
return os.path.normpath(os.path.join(oldcwd, os.path.expanduser(path)))
def searchPath(path):
"Go one step beyond getFullPath and try the various folders in PATH"
# Try looking in the current working directory first.
newpath = getFullPath(path)
if os.path.exists(newpath):
return newpath
# At this point we have to fail if a directory was given (to prevent cases
# like './gdb' from matching '/usr/bin/./gdb').
if not os.path.dirname(path):
for dir in os.environ['PATH'].split(os.pathsep):
newpath = os.path.join(dir, path)
if os.path.exists(newpath):
return newpath
return None
#################
# MAIN FUNCTION #
#################
@ -397,31 +349,8 @@ Are you executing $objdir/_tests/testing/mochitest/runtests.py?"""
options.certPath = getFullPath(options.certPath)
options.symbolsPath = getFullPath(options.symbolsPath)
debuggerInfo = None
if options.debugger:
debuggerPath = searchPath(options.debugger)
if not debuggerPath:
print "Error: Path %s doesn't exist." % options.debugger
sys.exit(1)
debuggerName = os.path.basename(debuggerPath).lower()
def getDebuggerInfo(type, default):
if debuggerName in DEBUGGER_INFO and type in DEBUGGER_INFO[debuggerName]:
return DEBUGGER_INFO[debuggerName][type]
return default
debuggerInfo = {
"path": debuggerPath,
"interactive" : getDebuggerInfo("interactive", False),
"args": getDebuggerInfo("args", "").split()
}
if options.debuggerArgs:
debuggerInfo["args"] = options.debuggerArgs.split()
if options.debuggerInteractive:
debuggerInfo["interactive"] = options.debuggerInteractive
debuggerInfo = getDebuggerInfo(oldcwd, options.debugger, options.debuggerArgs,
options.debuggerInteractive);
# browser environment
browserEnv = automation.environment(xrePath = options.xrePath)

Просмотреть файл

@ -43,7 +43,7 @@ from optparse import OptionParser
from subprocess import Popen, PIPE, STDOUT
from tempfile import mkdtemp
from automationutils import addCommonOptions, checkForCrashes, dumpLeakLog
from automationutils import *
# Init logging
log = logging.getLogger()
@ -51,6 +51,8 @@ handler = logging.StreamHandler(sys.stdout)
log.setLevel(logging.INFO)
log.addHandler(handler)
oldcwd = os.getcwd()
def readManifest(manifest):
"""Given a manifest file containing a list of test directories,
return a list of absolute paths to the directories contained within."""
@ -70,7 +72,8 @@ def readManifest(manifest):
def runTests(xpcshell, xrePath=None, symbolsPath=None,
manifest=None, testdirs=[], testPath=None,
interactive=False, logfiles=True):
interactive=False, logfiles=True,
debuggerInfo=None):
"""Run xpcshell tests.
|xpcshell|, is the xpcshell executable to use to run the tests.
@ -86,6 +89,8 @@ def runTests(xpcshell, xrePath=None, symbolsPath=None,
instead of automatically executing the test.
|logfiles|, if set to False, indicates not to save output to log files.
Non-interactive only option.
|debuggerInfo|, if set, specifies the debugger and debugger arguments
that will be used to launch xpcshell.
"""
if not testdirs and not manifest:
@ -131,17 +136,24 @@ def runTests(xpcshell, xrePath=None, symbolsPath=None,
pStderr = None
else:
xpcsRunArgs = ['-e', '_execute_test();']
if sys.platform == 'os2emx':
if (debuggerInfo and debuggerInfo["interactive"]):
pStdout = None
pStderr = None
else:
pStdout = PIPE
pStderr = STDOUT
if sys.platform == 'os2emx':
pStdout = None
else:
pStdout = PIPE
pStderr = STDOUT
# <head.js> has to be loaded by xpchell: it can't load itself.
xpcsCmd = [xpcshell, '-g', xrePath, '-j', '-s'] + \
['-e', 'const _HTTPD_JS_PATH = "%s";' % httpdJSPath,
'-f', os.path.join(testharnessdir, 'head.js')]
if debuggerInfo:
xpcsCmd = [debuggerInfo["path"]] + debuggerInfo["args"] + xpcsCmd
# |testPath| will be the optional path only, or |None|.
# |singleFile| will be the optional test only, or |None|.
singleFile = None
@ -295,6 +307,9 @@ def main():
sys.argv[0])
sys.exit(1)
debuggerInfo = getDebuggerInfo(oldcwd, options.debugger, options.debuggerArgs,
options.debuggerInteractive);
if options.interactive and not options.testPath:
print >>sys.stderr, "Error: You must specify a test filename in interactive mode!"
sys.exit(1)
@ -306,7 +321,8 @@ def main():
testdirs=args[1:],
testPath=options.testPath,
interactive=options.interactive,
logfiles=options.logfiles):
logfiles=options.logfiles,
debuggerInfo=debuggerInfo):
sys.exit(1)
if __name__ == '__main__':