mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
106 lines
3.3 KiB
JavaScript
106 lines
3.3 KiB
JavaScript
const Ci = Components.interfaces;
|
|
const Cc = Components.classes;
|
|
const Cu = Components.utils;
|
|
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
|
|
function getMainThreadHangStats() {
|
|
let threads = Services.telemetry.threadHangStats;
|
|
return threads.find((thread) => (thread.name === "Gecko"));
|
|
}
|
|
|
|
function run_test() {
|
|
let startHangs = getMainThreadHangStats();
|
|
|
|
// We disable hang reporting in several situations (e.g. debug builds,
|
|
// official releases). In those cases, we don't have hang stats available
|
|
// and should exit the test early.
|
|
if (!startHangs) {
|
|
ok("Hang reporting not enabled.");
|
|
return;
|
|
}
|
|
|
|
if (Services.appinfo.OS === 'Linux' || Services.appinfo.OS === 'Android') {
|
|
// We use the rt_tgsigqueueinfo syscall on Linux which requires a
|
|
// certain kernel version. It's not an error if the system running
|
|
// the test is older than that.
|
|
let kernel = Services.sysinfo.get('kernel_version') ||
|
|
Services.sysinfo.get('version');
|
|
if (Services.vc.compare(kernel, '2.6.31') < 0) {
|
|
ok("Hang reporting not supported for old kernel.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Run three events in the event loop:
|
|
// the first event causes a transient hang;
|
|
// the second event causes a permanent hang;
|
|
// the third event checks results from previous events.
|
|
|
|
do_execute_soon(() => {
|
|
// Cause a hang lasting 1 second (transient hang).
|
|
let startTime = Date.now();
|
|
while ((Date.now() - startTime) < 1000) {
|
|
}
|
|
});
|
|
|
|
do_execute_soon(() => {
|
|
// Cause a hang lasting 10 seconds (permanent hang).
|
|
let startTime = Date.now();
|
|
while ((Date.now() - startTime) < 10000) {
|
|
}
|
|
});
|
|
|
|
do_execute_soon(() => {
|
|
do_test_pending();
|
|
|
|
let check_results = () => {
|
|
let endHangs = getMainThreadHangStats();
|
|
|
|
// Because hangs are recorded asynchronously, if we don't see new hangs,
|
|
// we should wait for pending hangs to be recorded. On the other hand,
|
|
// if hang monitoring is broken, this test will time out.
|
|
if (endHangs.hangs.length === startHangs.hangs.length) {
|
|
do_timeout(100, check_results);
|
|
return;
|
|
}
|
|
|
|
let check_histogram = (histogram) => {
|
|
equal(typeof histogram, "object");
|
|
equal(histogram.histogram_type, 0);
|
|
equal(typeof histogram.min, "number");
|
|
equal(typeof histogram.max, "number");
|
|
equal(typeof histogram.sum, "number");
|
|
ok(Array.isArray(histogram.ranges));
|
|
ok(Array.isArray(histogram.counts));
|
|
equal(histogram.counts.length, histogram.ranges.length);
|
|
};
|
|
|
|
// Make sure the hang stats structure is what we expect.
|
|
equal(typeof endHangs, "object");
|
|
check_histogram(endHangs.activity);
|
|
|
|
ok(Array.isArray(endHangs.hangs));
|
|
notEqual(endHangs.hangs.length, 0);
|
|
|
|
ok(Array.isArray(endHangs.hangs[0].stack));
|
|
notEqual(endHangs.hangs[0].stack.length, 0);
|
|
equal(typeof endHangs.hangs[0].stack[0], "string");
|
|
|
|
// Make sure one of the hangs is a permanent
|
|
// hang containing a native stack.
|
|
ok(endHangs.hangs.some((hang) => (
|
|
Array.isArray(hang.nativeStack) &&
|
|
hang.nativeStack.length !== 0 &&
|
|
typeof hang.nativeStack[0] === "string"
|
|
)));
|
|
|
|
check_histogram(endHangs.hangs[0].histogram);
|
|
|
|
do_test_finished();
|
|
};
|
|
|
|
check_results();
|
|
});
|
|
}
|