Bug 771578 - Part 2: Move code to invoke a single test into its own method; r=ted

This commit is contained in:
Gregory Szorc 2013-03-26 17:15:24 -07:00
parent 5dc1c91c1f
commit ff1c58a1db

View File

@ -787,45 +787,90 @@ class XPCShellTests(object):
self.testCount += 1
xunitResult = {"name": test["name"], "classname": "xpcshell"}
keep_going, xunitResult = self.run_test(test,
tests_root_dir=testsRootDir, app_dir_key=appDirKey,
interactive=interactive, verbose=verbose, pStdout=pStdout,
pStderr=pStderr, keep_going=keepGoing)
xunitResults.append(xunitResult)
if not keep_going:
break
self.shutdownNode()
if self.testCount == 0:
self.log.error("TEST-UNEXPECTED-FAIL | runxpcshelltests.py | No tests run. Did you pass an invalid --test-path?")
self.failCount = 1
self.log.info("INFO | Result summary:")
self.log.info("INFO | Passed: %d" % self.passCount)
self.log.info("INFO | Failed: %d" % self.failCount)
self.log.info("INFO | Todo: %d" % self.todoCount)
if autolog:
self.post_to_autolog(xunitResults, xunitName)
if xunitFilename is not None:
self.writeXunitResults(filename=xunitFilename, results=xunitResults,
name=xunitName)
if gotSIGINT and not keepGoing:
self.log.error("TEST-UNEXPECTED-FAIL | Received SIGINT (control-C), so stopped run. " \
"(Use --keep-going to keep running tests after killing one with SIGINT)")
return False
return self.failCount == 0
def run_test(self, test, tests_root_dir=None, app_dir_key=None,
interactive=False, verbose=False, pStdout=None, pStderr=None,
keep_going=False):
"""Run an individual xpcshell test."""
global gotSIGINT
name = test['path']
xunit_result = {'name': test['name'], 'classname': 'xpcshell'}
# The xUnit package is defined as the path component between the root
# dir and the test with path characters replaced with '.' (using Java
# class notation).
if testsRootDir is not None:
testsRootDir = os.path.normpath(testsRootDir)
if test["here"].find(testsRootDir) != 0:
raise Exception("testsRootDir is not a parent path of %s" %
test["here"])
relpath = test["here"][len(testsRootDir):].lstrip("/\\")
xunitResult["classname"] = relpath.replace("/", ".").replace("\\", ".")
if tests_root_dir is not None:
tests_root_dir = os.path.normpath(tests_root_dir)
if test['here'].find(tests_root_dir) != 0:
raise Exception('tests_root_dir is not a parent path of %s' %
test['here'])
relpath = test['here'][len(tests_root_dir):].lstrip('/\\')
xunit_result['classname'] = relpath.replace('/', '.').replace('\\', '.')
# Check for skipped tests
if 'disabled' in test:
self.log.info("TEST-INFO | skipping %s | %s" %
self.log.info('TEST-INFO | skipping %s | %s' %
(name, test['disabled']))
xunitResult["skipped"] = True
xunitResults.append(xunitResult)
continue
xunit_result['skipped'] = True
return True, xunit_result
# Check for known-fail tests
expected = test['expected'] == 'pass'
# By default self.appPath will equal the gre dir. If specified in the
# xpcshell.ini file, set a different app dir for this test.
if appDirKey != None and appDirKey in test:
relAppDir = test[appDirKey]
relAppDir = os.path.join(self.xrePath, relAppDir)
self.appPath = os.path.abspath(relAppDir)
if app_dir_key and app_dir_key in test:
rel_app_dir = test[app_dir_key]
rel_app_dir = os.path.join(self.xrePath, rel_app_dir)
self.appPath = os.path.abspath(rel_app_dir)
else:
self.appPath = None
testdir = os.path.dirname(name)
self.buildXpcsCmd(testdir)
testHeadFiles, testTailFiles = self.getHeadAndTailFiles(test)
cmdH = self.buildCmdHead(testHeadFiles, testTailFiles, self.xpcsCmd)
test_dir = os.path.dirname(name)
self.buildXpcsCmd(test_dir)
head_files, tail_files = self.getHeadAndTailFiles(test)
cmdH = self.buildCmdHead(head_files, tail_files, self.xpcsCmd)
# create a temp dir that the JS harness can stick a profile in
# Create a temp dir that the JS harness can stick a profile in
self.profileDir = self.setupProfileDir()
self.leakLogFile = self.setupLeakLogging()
@ -839,14 +884,15 @@ class XPCShellTests(object):
completeCmd = cmdH + cmdT + args
proc = None
try:
self.log.info("TEST-INFO | %s | running test ..." % name)
if verbose:
self.logCommand(name, completeCmd, testdir)
startTime = time.time()
self.logCommand(name, completeCmd, test_dir)
startTime = time.time()
proc = self.launchProcess(completeCmd,
stdout=pStdout, stderr=pStderr, env=self.env, cwd=testdir)
stdout=pStdout, stderr=pStderr, env=self.env, cwd=test_dir)
if interactive:
self.log.info("TEST-INFO | %s | Process ID: %d" % (name, proc.pid))
@ -890,9 +936,9 @@ class XPCShellTests(object):
self.log.error(message)
print_stdout(stdout)
self.failCount += 1
xunitResult["passed"] = False
xunit_result["passed"] = False
xunitResult["failure"] = {
xunit_result["failure"] = {
"type": failureType,
"message": message,
"text": stdout
@ -900,24 +946,24 @@ class XPCShellTests(object):
else:
now = time.time()
timeTaken = (now - startTime) * 1000
xunitResult["time"] = now - startTime
xunit_result["time"] = now - startTime
self.log.info("TEST-%s | %s | test passed (time: %.3fms)" % ("PASS" if expected else "KNOWN-FAIL", name, timeTaken))
if verbose:
print_stdout(stdout)
xunitResult["passed"] = True
xunit_result["passed"] = True
if expected:
self.passCount += 1
else:
self.todoCount += 1
xunitResult["todo"] = True
xunit_result["todo"] = True
if mozcrash.check_for_crashes(testdir, self.symbolsPath, test_name=name):
if mozcrash.check_for_crashes(test_dir, self.symbolsPath, test_name=name):
message = "PROCESS-CRASH | %s | application crashed" % name
self.failCount += 1
xunitResult["passed"] = False
xunitResult["failure"] = {
xunit_result["passed"] = False
xunit_result["failure"] = {
"type": "PROCESS-CRASH",
"message": message,
"text": stdout
@ -934,6 +980,7 @@ class XPCShellTests(object):
if self.logfiles and stdout:
self.createLogFile(name, stdout, leakLogs)
finally:
# We can sometimes get here before the process has terminated, which would
# cause removeDir() to fail - so check for the process & kill it it needed.
@ -942,13 +989,15 @@ class XPCShellTests(object):
self.log.error(message)
print_stdout(stdout)
self.failCount += 1
xunitResult["passed"] = False
xunitResult["failure"] = {
xunit_result["passed"] = False
xunit_result["failure"] = {
"type": "TEST-UNEXPECTED-FAIL",
"message": message,
"text": stdout
}
self.kill(proc)
# We don't want to delete the profile when running check-interactive
# or check-one.
if self.profileDir and not self.interactive and not self.singleFile:
@ -970,55 +1019,30 @@ class XPCShellTests(object):
print_stdout(traceback.format_exc())
self.failCount += 1
xunitResult["passed"] = False
xunitResult["failure"] = {
xunit_result["passed"] = False
xunit_result["failure"] = {
"type": "TEST-UNEXPECTED-FAIL",
"message": message,
"text": "%s\n%s" % (stdout, traceback.format_exc())
}
if gotSIGINT:
xunitResult["passed"] = False
xunitResult["time"] = "0.0"
xunitResult["failure"] = {
xunit_result["passed"] = False
xunit_result["time"] = "0.0"
xunit_result["failure"] = {
"type": "SIGINT",
"message": "Received SIGINT",
"text": "Received SIGINT (control-C) during test execution."
}
self.log.error("TEST-UNEXPECTED-FAIL | Received SIGINT (control-C) during test execution")
if (keepGoing):
if (keep_going):
gotSIGINT = False
else:
xunitResults.append(xunitResult)
break
return False, xunit_result
xunitResults.append(xunitResult)
return True, xunit_result
self.shutdownNode()
if self.testCount == 0:
self.log.error("TEST-UNEXPECTED-FAIL | runxpcshelltests.py | No tests run. Did you pass an invalid --test-path?")
self.failCount = 1
self.log.info("INFO | Result summary:")
self.log.info("INFO | Passed: %d" % self.passCount)
self.log.info("INFO | Failed: %d" % self.failCount)
self.log.info("INFO | Todo: %d" % self.todoCount)
if autolog:
self.post_to_autolog(xunitResults, xunitName)
if xunitFilename is not None:
self.writeXunitResults(filename=xunitFilename, results=xunitResults,
name=xunitName)
if gotSIGINT and not keepGoing:
self.log.error("TEST-UNEXPECTED-FAIL | Received SIGINT (control-C), so stopped run. " \
"(Use --keep-going to keep running tests after killing one with SIGINT)")
return False
return self.failCount == 0
class XPCShellOptions(OptionParser):
def __init__(self):