--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -37,17 +37,16 @@ from threading import (
)
try:
import psutil
HAVE_PSUTIL = True
except Exception:
HAVE_PSUTIL = False
-from automation import Automation
from xpcshellcommandline import parser_desktop
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
HARNESS_TIMEOUT = 5 * 60
# benchmarking on tbpl revealed that this works best for now
NUM_THREADS = int(cpu_count() * 4)
@@ -66,16 +65,17 @@ mozbase = os.path.realpath(os.path.join(
if os.path.isdir(mozbase):
for package in os.listdir(mozbase):
sys.path.append(os.path.join(mozbase, package))
from manifestparser import TestManifest
from manifestparser.filters import chunk_by_slice, tags, pathprefix
from mozlog import commandline
import mozcrash
+import mozfile
import mozinfo
from mozrunner.utils import get_stack_fixer_function
# --------------------------------------------------------------
# TODO: perhaps this should be in a more generally shared location?
# This regex matches all of the C0 and C1 control characters
# (U+0000 through U+001F; U+007F; U+0080 through U+009F),
@@ -113,16 +113,17 @@ class XPCShellTestThread(Thread):
self.daemon = True
self.test_object = test_object
self.cleanup_dir_list = cleanup_dir_list
self.retry = retry
self.appPath = kwargs.get('appPath')
self.xrePath = kwargs.get('xrePath')
+ self.utility_path = kwargs.get('utility_path')
self.testingModulesDir = kwargs.get('testingModulesDir')
self.debuggerInfo = kwargs.get('debuggerInfo')
self.jsDebuggerInfo = kwargs.get('jsDebuggerInfo')
self.pluginsPath = kwargs.get('pluginsPath')
self.httpdManifest = kwargs.get('httpdManifest')
self.httpdJSPath = kwargs.get('httpdJSPath')
self.headJSPath = kwargs.get('headJSPath')
self.testharnessdir = kwargs.get('testharnessdir')
@@ -188,17 +189,17 @@ class XPCShellTestThread(Thread):
"""
return proc.kill()
def removeDir(self, dirname):
"""
Simple wrapper to remove (recursively) a given directory.
On a remote system, we need to overload this to work on the remote filesystem.
"""
- shutil.rmtree(dirname)
+ mozfile.remove(dirname)
def poll(self, proc):
"""
Simple wrapper to check if a process has terminated.
On a remote system, this is overloaded to handle remote process communication.
"""
return proc.poll()
@@ -267,27 +268,31 @@ class XPCShellTestThread(Thread):
self.log.info("%s | current directory: %r" % (name, testdir))
# Show only those environment variables that are changed from
# the ambient environment.
changedEnv = (set("%s=%s" % i for i in self.env.iteritems())
- set("%s=%s" % i for i in os.environ.iteritems()))
self.log.info("%s | environment: %s" % (name, list(changedEnv)))
def killTimeout(self, proc):
- Automation().killAndGetStackNoScreenshot(proc.pid,
- self.appPath,
- self.debuggerInfo)
+ mozcrash.kill_and_get_minidump(proc.pid, self.tempDir, utility_path=self.utility_path)
def postCheck(self, proc):
"""Checks for a still-running test process, kills it and fails the test if found.
We can sometimes get here before the process has terminated, which would
cause removeDir() to fail - so check for the process and kill it if needed.
"""
if proc and self.poll(proc) is None:
- self.kill(proc)
+ if HAVE_PSUTIL:
+ try:
+ self.kill(proc)
+ except psutil.NoSuchProcess:
+ pass
+ else:
+ self.kill(proc)
message = "%s | Process still running after test!" % self.test_object['id']
if self.retry:
self.log.info(message)
return
self.log.error(message)
self.log_full_output()
self.failCount = 1
@@ -1176,16 +1181,17 @@ class XPCShellTests(object):
self.jsDebuggerInfo = None
if jsDebugger:
# A namedtuple let's us keep .port instead of ['port']
JSDebuggerInfo = namedtuple('JSDebuggerInfo', ['port'])
self.jsDebuggerInfo = JSDebuggerInfo(port=jsDebuggerPort)
self.xpcshell = xpcshell
self.xrePath = xrePath
+ self.utility_path = utility_path
self.appPath = appPath
self.symbolsPath = symbolsPath
self.tempDir = os.path.normpath(tempDir or tempfile.gettempdir())
self.manifest = manifest
self.dump_tests = dump_tests
self.interactive = interactive
self.verbose = verbose
self.keepGoing = keepGoing
@@ -1226,18 +1232,18 @@ class XPCShellTests(object):
if isinstance(k, unicode):
k = k.encode('ascii')
fixedInfo[k] = v
self.mozInfo = fixedInfo
mozinfo.update(self.mozInfo)
self.stack_fixer_function = None
- if utility_path and os.path.exists(utility_path):
- self.stack_fixer_function = get_stack_fixer_function(utility_path, self.symbolsPath)
+ if self.utility_path and os.path.exists(self.utility_path):
+ self.stack_fixer_function = get_stack_fixer_function(self.utility_path, self.symbolsPath)
# buildEnvironment() needs mozInfo, so we call it after mozInfo is initialized.
self.buildEnvironment()
# The appDirKey is a optional entry in either the default or individual test
# sections that defines a relative application directory for test runs. If
# defined we pass 'grePath/$appDirKey' for the -a parameter of the xpcshell
# test harness.
@@ -1259,16 +1265,17 @@ class XPCShellTests(object):
random.shuffle(self.alltests)
self.cleanup_dir_list = []
self.try_again_list = []
kwargs = {
'appPath': self.appPath,
'xrePath': self.xrePath,
+ 'utility_path': self.utility_path,
'testingModulesDir': self.testingModulesDir,
'debuggerInfo': self.debuggerInfo,
'jsDebuggerInfo': self.jsDebuggerInfo,
'pluginsPath': self.pluginsPath,
'httpdManifest': self.httpdManifest,
'httpdJSPath': self.httpdJSPath,
'headJSPath': self.headJSPath,
'tempDir': self.tempDir,