163 lines
5.1 KiB
JavaScript
163 lines
5.1 KiB
JavaScript
function create_subdir(dir, subdirname) {
|
|
let subdir = dir.clone();
|
|
subdir.append(subdirname);
|
|
if (subdir.exists()) {
|
|
subdir.remove(true);
|
|
}
|
|
subdir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
|
|
return subdir;
|
|
}
|
|
|
|
function generate_uuid() {
|
|
let uuidGenerator = Services.uuid;
|
|
let uuid = uuidGenerator.generateUUID().toString();
|
|
// ditch the {}
|
|
return uuid.substring(1, uuid.length - 1);
|
|
}
|
|
|
|
// need to hold on to this to unregister for cleanup
|
|
var _provider = null;
|
|
|
|
function make_fake_appdir() {
|
|
// Create a directory inside the profile and register it as UAppData, so
|
|
// we can stick fake crash reports inside there. We put it inside the profile
|
|
// just because we know that will get cleaned up after the mochitest run.
|
|
let profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
|
// create a subdir just to keep our files out of the way
|
|
let appD = create_subdir(profD, "UAppData");
|
|
|
|
let crashesDir = create_subdir(appD, "Crash Reports");
|
|
create_subdir(crashesDir, "pending");
|
|
create_subdir(crashesDir, "submitted");
|
|
|
|
_provider = {
|
|
getFile(prop, persistent) {
|
|
persistent.value = true;
|
|
if (prop == "UAppData") {
|
|
return appD.clone();
|
|
}
|
|
// Depending on timing we can get requests for other files.
|
|
// When we threw an exception here, in the world before bug 997440, this got lost
|
|
// because of the arbitrary JSContext being used in nsXPCWrappedJS::CallMethod.
|
|
// After bug 997440 this gets reported to our window and causes the tests to fail.
|
|
// So, we'll just dump out a message to the logs.
|
|
dump(
|
|
"WARNING: make_fake_appdir - fake nsIDirectoryServiceProvider - Unexpected getFile for: '" +
|
|
prop +
|
|
"'\n"
|
|
);
|
|
return null;
|
|
},
|
|
QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]),
|
|
};
|
|
// register our new provider
|
|
Services.dirsvc
|
|
.QueryInterface(Ci.nsIDirectoryService)
|
|
.registerProvider(_provider);
|
|
// and undefine the old value
|
|
try {
|
|
Services.dirsvc.undefine("UAppData");
|
|
} catch (ex) {} // it's ok if this fails, the value might not be cached yet
|
|
return appD.clone();
|
|
}
|
|
|
|
function cleanup_fake_appdir() {
|
|
Services.dirsvc
|
|
.QueryInterface(Ci.nsIDirectoryService)
|
|
.unregisterProvider(_provider);
|
|
// undefine our value so future calls get the real value
|
|
try {
|
|
Services.dirsvc.undefine("UAppData");
|
|
} catch (ex) {
|
|
dump("cleanup_fake_appdir: dirSvc.undefine failed: " + ex.message + "\n");
|
|
}
|
|
}
|
|
|
|
function add_fake_crashes(crD, count) {
|
|
let results = [];
|
|
let submitdir = crD.clone();
|
|
submitdir.append("submitted");
|
|
// create them from oldest to newest, to ensure that about:crashes
|
|
// displays them in the correct order
|
|
let date = Date.now() - count * 60000;
|
|
for (let i = 0; i < count; i++) {
|
|
let uuid = "bp-" + generate_uuid();
|
|
let fn = uuid + ".txt";
|
|
let file = submitdir.clone();
|
|
file.append(fn);
|
|
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
|
file.lastModifiedTime = date;
|
|
results.push({ id: uuid, date, pending: false });
|
|
|
|
date += 60000;
|
|
}
|
|
// we want them sorted newest to oldest, since that's the order
|
|
// that about:crashes lists them in
|
|
results.sort((a, b) => b.date - a.date);
|
|
return results;
|
|
}
|
|
|
|
function clear_fake_crashes(crD, crashes) {
|
|
let submitdir = crD.clone();
|
|
submitdir.append("submitted");
|
|
for (let i of crashes) {
|
|
let fn = i.id + ".txt";
|
|
let file = submitdir.clone();
|
|
file.append(fn);
|
|
file.remove(false);
|
|
}
|
|
}
|
|
|
|
function writeDataToFile(file, data) {
|
|
var fstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
|
Ci.nsIFileOutputStream
|
|
);
|
|
// open, write, truncate
|
|
fstream.init(file, -1, -1, 0);
|
|
var os = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(
|
|
Ci.nsIConverterOutputStream
|
|
);
|
|
os.init(fstream, "UTF-8");
|
|
os.writeString(data);
|
|
os.close();
|
|
fstream.close();
|
|
}
|
|
|
|
function writeCrashReportFile(dir, uuid, suffix, date, data) {
|
|
let file = dir.clone();
|
|
file.append(uuid + suffix);
|
|
writeDataToFile(file, data);
|
|
file.lastModifiedTime = date;
|
|
}
|
|
|
|
function writeMinidumpFile(dir, uuid, date, payload = "") {
|
|
// that's the start of a valid minidump, anyway
|
|
writeCrashReportFile(dir, uuid, ".dmp", date, `MDMP${payload}`);
|
|
}
|
|
|
|
function writeExtraFile(dir, uuid, date, data) {
|
|
writeCrashReportFile(dir, uuid, ".extra", date, JSON.stringify(data));
|
|
}
|
|
|
|
function writeMemoryReport(dir, uuid, date) {
|
|
let data = "Let's pretend this is a memory report";
|
|
writeCrashReportFile(dir, uuid, ".memory.json.gz", date, data);
|
|
}
|
|
|
|
function addPendingCrashreport(crD, date, extra, payload = "") {
|
|
let pendingdir = crD.clone();
|
|
pendingdir.append("pending");
|
|
let uuid = generate_uuid();
|
|
writeMinidumpFile(pendingdir, uuid, date, payload);
|
|
writeExtraFile(pendingdir, uuid, date, extra);
|
|
writeMemoryReport(pendingdir, uuid, date);
|
|
return { id: uuid, date, pending: true, extra };
|
|
}
|
|
|
|
function addIncompletePendingCrashreport(crD, date) {
|
|
let pendingdir = crD.clone();
|
|
pendingdir.append("pending");
|
|
let uuid = generate_uuid();
|
|
writeMinidumpFile(pendingdir, uuid, date);
|
|
return { id: uuid, date, pending: true };
|
|
}
|