зеркало из https://github.com/mozilla/gecko-dev.git
Bug 652501 - Part 1: Allow reftests to clean up plugin and IPC process crash dumps. r=roc
This commit is contained in:
Родитель
68454aca67
Коммит
76f0cc3edd
|
@ -396,6 +396,7 @@ so 60/zoom is an integer.
|
|||
|
||||
Printing Tests
|
||||
==============
|
||||
|
||||
Now that the patch for bug 374050 has landed
|
||||
(https://bugzilla.mozilla.org/show_bug.cgi?id=374050), it is possible to
|
||||
create reftests that run in a paginated context.
|
||||
|
@ -421,3 +422,23 @@ doesn't use exactly the same codepath as real print preview/print. In
|
|||
particular, scripting and frames are likely to cause problems; it is untested,
|
||||
though. That said, it should be sufficient for testing layout issues related
|
||||
to pagination.
|
||||
|
||||
Plugin and IPC Process Crash Tests
|
||||
==================================
|
||||
|
||||
If you are running a test that causes an out-of-process plugin or IPC process
|
||||
under Electrolysis to crash as part of a reftest, this will cause process
|
||||
crash minidump files to be left in the profile directory. The test
|
||||
infrastructure that runs the reftests will notice these minidump files and
|
||||
dump out information from them, and these additional error messages in the logs
|
||||
can end up erroneously being associated with other errors from the reftest run.
|
||||
They are also confusing, since the appearance of "PROCESS-CRASH" messages in
|
||||
the test run output can seem like a real problem, when in fact it is the
|
||||
expected behavior.
|
||||
|
||||
To indicate to the reftest framework that a test is expecting a plugin or
|
||||
IPC process crash, have the test include "reftest-expect-process-crash" as
|
||||
one of the root element's classes by the time the test has finished. This will
|
||||
cause any minidump files that are generated while running the test to be removed
|
||||
and they won't cause any error messages in the test run output.
|
||||
|
||||
|
|
|
@ -464,6 +464,7 @@ function WaitForTestEnd(contentRootElement, inPrintMode) {
|
|||
state = STATE_COMPLETED;
|
||||
gFailureReason = "timed out while taking snapshot (bug in harness?)";
|
||||
RemoveListeners();
|
||||
CheckForProcessCrashExpectation();
|
||||
setTimeout(RecordResult, 0);
|
||||
return;
|
||||
}
|
||||
|
@ -527,6 +528,7 @@ function OnDocumentLoad(event)
|
|||
// Go into reftest-wait mode belatedly.
|
||||
WaitForTestEnd(contentRootElement, inPrintMode);
|
||||
} else {
|
||||
CheckForProcessCrashExpectation();
|
||||
RecordResult();
|
||||
}
|
||||
}
|
||||
|
@ -555,6 +557,17 @@ function OnDocumentLoad(event)
|
|||
}
|
||||
}
|
||||
|
||||
function CheckForProcessCrashExpectation()
|
||||
{
|
||||
var contentRootElement = content.document.documentElement;
|
||||
if (contentRootElement &&
|
||||
contentRootElement.hasAttribute('class') &&
|
||||
contentRootElement.getAttribute('class').split(/\s+/)
|
||||
.indexOf("reftest-expect-process-crash") != -1) {
|
||||
SendExpectProcessCrash();
|
||||
}
|
||||
}
|
||||
|
||||
function RecordResult()
|
||||
{
|
||||
LogInfo("RecordResult fired");
|
||||
|
@ -764,11 +777,16 @@ function SendInitCanvasWithSnapshot()
|
|||
}
|
||||
|
||||
function SendScriptResults(runtimeMs, error, results)
|
||||
{
|
||||
{
|
||||
sendAsyncMessage("reftest:ScriptResults",
|
||||
{ runtimeMs: runtimeMs, error: error, results: results });
|
||||
}
|
||||
|
||||
function SendExpectProcessCrash(runtimeMs)
|
||||
{
|
||||
sendAsyncMessage("reftest:ExpectProcessCrash");
|
||||
}
|
||||
|
||||
function SendTestDone(runtimeMs)
|
||||
{
|
||||
sendAsyncMessage("reftest:TestDone", { runtimeMs: runtimeMs });
|
||||
|
|
|
@ -57,6 +57,10 @@ const NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX =
|
|||
"@mozilla.org/network/protocol;1?name=";
|
||||
const NS_XREAPPINFO_CONTRACTID =
|
||||
"@mozilla.org/xre/app-info;1";
|
||||
const NS_DIRECTORY_SERVICE_CONTRACTID =
|
||||
"@mozilla.org/file/directory_service;1";
|
||||
const NS_OBSERVER_SERVICE_CONTRACTID =
|
||||
"@mozilla.org/observer-service;1";
|
||||
|
||||
var gLoadTimeout = 0;
|
||||
var gTimeoutHook = null;
|
||||
|
@ -115,6 +119,11 @@ var gSlowestTestURL;
|
|||
|
||||
var gDrawWindowFlags;
|
||||
|
||||
var gExpectingProcessCrash = false;
|
||||
var gExpectedCrashDumpFiles = [];
|
||||
var gUnexpectedCrashDumpFiles = { };
|
||||
var gCrashDumpDir;
|
||||
|
||||
const TYPE_REFTEST_EQUAL = '==';
|
||||
const TYPE_REFTEST_NOTEQUAL = '!=';
|
||||
const TYPE_LOAD = 'load'; // test without a reference (just test that it does
|
||||
|
@ -205,6 +214,11 @@ function IDForEventTarget(event)
|
|||
|
||||
function OnRefTestLoad()
|
||||
{
|
||||
gCrashDumpDir = CC[NS_DIRECTORY_SERVICE_CONTRACTID]
|
||||
.getService(CI.nsIProperties)
|
||||
.get("ProfD", CI.nsIFile);
|
||||
gCrashDumpDir.append("minidumps");
|
||||
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch2);
|
||||
try {
|
||||
|
@ -278,7 +292,9 @@ function InitAndStartRefTests()
|
|||
|
||||
gIOService = CC[IO_SERVICE_CONTRACTID].getService(CI.nsIIOService);
|
||||
gDebug = CC[DEBUG_CONTRACTID].getService(CI.nsIDebug2);
|
||||
|
||||
|
||||
RegisterProcessCrashObservers();
|
||||
|
||||
if (gRemote) {
|
||||
gServer = null;
|
||||
} else {
|
||||
|
@ -1141,6 +1157,7 @@ function RecordResult(testRunTime, errorMsg, scriptResults)
|
|||
// First document has been loaded.
|
||||
// Proceed to load the second document.
|
||||
|
||||
CleanUpCrashDumpFiles();
|
||||
StartCurrentURI(2);
|
||||
break;
|
||||
case 2:
|
||||
|
@ -1201,6 +1218,7 @@ function RecordResult(testRunTime, errorMsg, scriptResults)
|
|||
UpdateCanvasCache(gURLs[0].url1, gCanvas1);
|
||||
UpdateCanvasCache(gURLs[0].url2, gCanvas2);
|
||||
|
||||
CleanUpCrashDumpFiles();
|
||||
FinishTestItem();
|
||||
break;
|
||||
default:
|
||||
|
@ -1217,6 +1235,55 @@ function LoadFailed(why)
|
|||
FinishTestItem();
|
||||
}
|
||||
|
||||
function RemoveExpectedCrashDumpFiles()
|
||||
{
|
||||
if (gExpectingProcessCrash) {
|
||||
for each (let crashFilename in gExpectedCrashDumpFiles) {
|
||||
let file = gCrashDumpDir.clone();
|
||||
file.append(crashFilename);
|
||||
if (file.exists()) {
|
||||
file.remove(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
gExpectedCrashDumpFiles.length = 0;
|
||||
}
|
||||
|
||||
function FindUnexpectedCrashDumpFiles()
|
||||
{
|
||||
if (!gCrashDumpDir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let entries = gCrashDumpDir.directoryEntries;
|
||||
if (!entries) {
|
||||
return;
|
||||
}
|
||||
|
||||
let foundCrashDumpFile = false;
|
||||
while (entries.hasMoreElements()) {
|
||||
let file = entries.getNext().QueryInterface(CI.nsIFile);
|
||||
let path = String(file.path);
|
||||
if (path.match(/\.(dmp|extra)$/) && !gUnexpectedCrashDumpFiles[path]) {
|
||||
if (!foundCrashDumpFile) {
|
||||
foundCrashDumpFile = true;
|
||||
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL +
|
||||
" | This test left crash dumps behind, but we weren't expecting it to!\n");
|
||||
}
|
||||
gDumpLog("REFTEST INFO | Found unexpected crash dump file" + path +
|
||||
".\n");
|
||||
gUnexpectedCrashDumpFiles[path] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function CleanUpCrashDumpFiles()
|
||||
{
|
||||
RemoveExpectedCrashDumpFiles();
|
||||
FindUnexpectedCrashDumpFiles();
|
||||
gExpectingProcessCrash = false;
|
||||
}
|
||||
|
||||
function FinishTestItem()
|
||||
{
|
||||
// Replace document with BLANK_URL_FOR_CLEARING in case there are
|
||||
|
@ -1316,6 +1383,10 @@ function RegisterMessageListenersAndLoadContentScript()
|
|||
"reftest:UpdateCanvasForInvalidation",
|
||||
function (m) { RecvUpdateCanvasForInvalidation(m.json.rects); }
|
||||
);
|
||||
gBrowserMessageManager.addMessageListener(
|
||||
"reftest:ExpectProcessCrash",
|
||||
function (m) { RecvExpectProcessCrash(); }
|
||||
);
|
||||
|
||||
gBrowserMessageManager.loadFrameScript("chrome://reftest/content/reftest-content.js", true);
|
||||
}
|
||||
|
@ -1376,6 +1447,34 @@ function RecvUpdateCanvasForInvalidation(rects)
|
|||
UpdateCurrentCanvasForInvalidation(rects);
|
||||
}
|
||||
|
||||
function OnProcessCrashed(subject, topic, data)
|
||||
{
|
||||
var id;
|
||||
subject = subject.QueryInterface(CI.nsIPropertyBag2);
|
||||
if (topic == "plugin-crashed") {
|
||||
id = subject.getPropertyAsAString("pluginDumpID");
|
||||
} else if (topic == "ipc:content-shutdown") {
|
||||
id = subject.getPropertyAsAString("dumpID");
|
||||
}
|
||||
if (id) {
|
||||
gExpectedCrashDumpFiles.push(id + ".dmp");
|
||||
gExpectedCrashDumpFiles.push(id + ".extra");
|
||||
}
|
||||
}
|
||||
|
||||
function RegisterProcessCrashObservers()
|
||||
{
|
||||
var os = CC[NS_OBSERVER_SERVICE_CONTRACTID]
|
||||
.getService(CI.nsIObserverService);
|
||||
os.addObserver(OnProcessCrashed, "plugin-crashed", false);
|
||||
os.addObserver(OnProcessCrashed, "ipc:content-shutdown", false);
|
||||
}
|
||||
|
||||
function RecvExpectProcessCrash()
|
||||
{
|
||||
gExpectingProcessCrash = true;
|
||||
}
|
||||
|
||||
function SendClear()
|
||||
{
|
||||
gBrowserMessageManager.sendAsyncMessage("reftest:Clear");
|
||||
|
|
Загрузка…
Ссылка в новой задаче