summaryrefslogtreecommitdiffstats
path: root/toolkit/components/terminator/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/components/terminator/tests/xpcshell/test_terminator_advance_phases.js157
-rw-r--r--toolkit/components/terminator/tests/xpcshell/test_terminator_record.js171
-rw-r--r--toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js88
-rw-r--r--toolkit/components/terminator/tests/xpcshell/xpcshell.toml7
4 files changed, 158 insertions, 265 deletions
diff --git a/toolkit/components/terminator/tests/xpcshell/test_terminator_advance_phases.js b/toolkit/components/terminator/tests/xpcshell/test_terminator_advance_phases.js
new file mode 100644
index 0000000000..42f0e3686f
--- /dev/null
+++ b/toolkit/components/terminator/tests/xpcshell/test_terminator_advance_phases.js
@@ -0,0 +1,157 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+
+"use strict";
+
+// Test that the Shutdown Terminator advances through the shutdown phases
+// correctly.
+
+const { setTimeout } = ChromeUtils.importESModule(
+ "resource://gre/modules/Timer.sys.mjs"
+);
+
+var terminator;
+
+var HEARTBEAT_MS = 100;
+
+let KEYS = [
+ "quit-application",
+ "profile-change-net-teardown",
+ "profile-change-teardown",
+ "profile-before-change",
+ "profile-before-change-qm",
+ "xpcom-will-shutdown",
+ "xpcom-shutdown",
+ "xpcom-shutdown-threads",
+ "XPCOMShutdownFinal",
+ "CCPostLastCycleCollection",
+];
+
+let DATA = [];
+let MeasuredDurations = [];
+
+add_task(async function init() {
+ do_get_profile();
+
+ // Initialize the terminator
+ // (normally, this is done through the manifest file, but xpcshell
+ // doesn't take them into account).
+ info("Initializing the Terminator");
+ terminator = Cc["@mozilla.org/toolkit/shutdown-terminator;1"].createInstance(
+ Ci.nsIObserver
+ );
+
+ Assert.ok(
+ terminator instanceof Ci.nsITerminatorTest,
+ "Terminator should implement nsITerminatorTest"
+ );
+});
+
+var currentPhase = 0;
+
+var advancePhase = async function () {
+ let key = "terminator-test-" + KEYS[currentPhase];
+ let msDuration = 200 + HEARTBEAT_MS * currentPhase;
+
+ info("Advancing shutdown phase to " + KEYS[currentPhase]);
+ terminator.observe(null, key, null);
+ await new Promise(resolve => setTimeout(resolve, msDuration));
+
+ let data = terminator.getTicksForShutdownPhases();
+
+ Assert.ok(
+ KEYS[currentPhase] in data,
+ "The KEYS object contains the expected key"
+ );
+ Assert.equal(
+ Object.keys(data).length,
+ currentPhase + 1,
+ "KEYS object does not contain more durations than expected"
+ );
+
+ DATA[currentPhase] = data;
+ currentPhase++;
+ if (currentPhase < KEYS.length) {
+ return true;
+ }
+ return false;
+};
+
+// This is a timing affected test, as we want to check if the time measurements
+// from the terminator are reasonable. Bug 1768795 assumes that they tend to
+// be lower than wall-clock, in particular on MacOS, confirmed by the logs on
+// intermittent bug 1760094. This is not a big deal for the terminator's
+// general functionality (timeouts might just come a little later than
+// expected nominally), but it makes testing harder and the transferred
+// telemetry data slightly less reliable (shutdowns might appear shorter than
+// they really were). So this test is just happy if there is any data that
+// is not too long wrt what we expect. If we ever want to fix bug 1768795,
+// we can check for a more reasonable lower boundary, too.
+add_task(async function test_record() {
+ info("Collecting duration data for all known phases");
+
+ let morePhases = true;
+ while (morePhases) {
+ let beforeWait = Date.now();
+
+ morePhases = await advancePhase();
+
+ // We measure the effective time that passed as wall-clock and include all
+ // file IO overhead as the terminator will do so in its measurement, too.
+ MeasuredDurations[currentPhase - 1] = Math.floor(
+ (Date.now() - beforeWait) / HEARTBEAT_MS
+ );
+ }
+
+ Assert.equal(DATA.length, KEYS.length, "We have data for each phase");
+
+ for (let i = 0; i < KEYS.length; i++) {
+ let lastDuration = DATA[KEYS.length - 1][KEYS[i]];
+ Assert.equal(
+ typeof lastDuration,
+ "number",
+ "Duration of phase " + i + ":" + KEYS[i] + " is a number"
+ );
+
+ // The durations are only meaningful after we advanced to the next phase.
+ if (i < KEYS.length - 1) {
+ // So we read it from the data written for the following phase.
+ let ticksDuration = DATA[i + 1][KEYS[i]];
+ let measuredDuration = MeasuredDurations[i];
+ info(
+ "measuredDuration:" + measuredDuration + " - " + typeof measuredDuration
+ );
+ Assert.lessOrEqual(
+ ticksDuration,
+ measuredDuration + 2,
+ "Duration of phase " + i + ":" + KEYS[i] + " is not too long"
+ );
+ Assert.greaterOrEqual(
+ ticksDuration,
+ 0, // TODO: Raise the lower boundary after bug 1768795.
+ "Duration of phase " + i + ":" + KEYS[i] + " is not too short"
+ );
+ }
+ // This check is done only for phases <= xpcom-shutdown-threads
+ // where we have two data points.
+ if (i < KEYS.length - 2) {
+ let ticksDuration = DATA[i + 1][KEYS[i]];
+ Assert.equal(
+ ticksDuration,
+ DATA[KEYS.length - 1][KEYS[i]],
+ "Duration of phase " + i + ":" + KEYS[i] + " hasn't changed"
+ );
+ }
+ }
+
+ // Note that after this check the KEYS array remains sorted, so this
+ // must be the last check to not get confused.
+ Assert.equal(
+ Object.keys(DATA[KEYS.length - 1])
+ .sort()
+ .join(", "),
+ KEYS.sort().join(", "),
+ "The KEYS object contains all expected keys"
+ );
+});
diff --git a/toolkit/components/terminator/tests/xpcshell/test_terminator_record.js b/toolkit/components/terminator/tests/xpcshell/test_terminator_record.js
deleted file mode 100644
index 62cee636f3..0000000000
--- a/toolkit/components/terminator/tests/xpcshell/test_terminator_record.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-/* eslint-disable mozilla/no-arbitrary-setTimeout */
-
-"use strict";
-
-// Test that the Shutdown Terminator records durations correctly
-
-const { setTimeout } = ChromeUtils.importESModule(
- "resource://gre/modules/Timer.sys.mjs"
-);
-
-var PATH;
-var PATH_TMP;
-var terminator;
-
-var HEARTBEAT_MS = 100;
-
-let KEYS = [
- "quit-application",
- "profile-change-net-teardown",
- "profile-change-teardown",
- "profile-before-change",
- "profile-before-change-qm",
- "xpcom-will-shutdown",
- "xpcom-shutdown",
- "xpcom-shutdown-threads",
- "XPCOMShutdownFinal",
- "CCPostLastCycleCollection",
-];
-
-let DATA = [];
-let MeasuredDurations = [];
-
-add_task(async function init() {
- do_get_profile();
- PATH = PathUtils.join(PathUtils.localProfileDir, "ShutdownDuration.json");
- PATH_TMP = PATH + ".tmp";
-
- // Initialize the terminator
- // (normally, this is done through the manifest file, but xpcshell
- // doesn't take them into account).
- info("Initializing the Terminator");
- terminator = Cc["@mozilla.org/toolkit/shutdown-terminator;1"].createInstance(
- Ci.nsIObserver
- );
-});
-
-var promiseShutdownDurationData = async function () {
- // Wait until PATH exists.
- // Timeout if it is never created.
- while (true) {
- if (await IOUtils.exists(PATH)) {
- break;
- }
-
- // Wait just a very short period to not increase measured values.
- // Usually the file should appear almost immediately.
- await new Promise(resolve => setTimeout(resolve, 50));
- }
-
- return IOUtils.readJSON(PATH);
-};
-
-var currentPhase = 0;
-
-var advancePhase = async function () {
- let key = "terminator-test-" + KEYS[currentPhase];
- let msDuration = 200 + HEARTBEAT_MS * currentPhase;
-
- info("Advancing shutdown phase to " + KEYS[currentPhase]);
- terminator.observe(null, key, null);
- await new Promise(resolve => setTimeout(resolve, msDuration));
-
- let data = await promiseShutdownDurationData();
-
- Assert.ok(KEYS[currentPhase] in data, "The file contains the expected key");
- Assert.equal(
- Object.keys(data).length,
- currentPhase + 1,
- "File does not contain more durations than expected"
- );
-
- DATA[currentPhase] = data;
- currentPhase++;
- if (currentPhase < KEYS.length) {
- return true;
- }
- return false;
-};
-
-// This is a timing affected test, as we want to check if the time measurements
-// from the terminator are reasonable. Bug 1768795 assumes that they tend to
-// be lower than wall-clock, in particular on MacOS, confirmed by the logs on
-// intermittent bug 1760094. This is not a big deal for the terminator's
-// general functionality (timeouts might just come a little later than
-// expected nominally), but it makes testing harder and the transferred
-// telemetry data slightly less reliable (shutdowns might appear shorter than
-// they really were). So this test is just happy if there is any data that
-// is not too long wrt what we expect. If we ever want to fix bug 1768795,
-// we can check for a more reasonable lower boundary, too.
-add_task(async function test_record() {
- info("Collecting duration data for all known phases");
-
- let morePhases = true;
- while (morePhases) {
- let beforeWait = Date.now();
-
- morePhases = await advancePhase();
-
- await IOUtils.remove(PATH);
- await IOUtils.remove(PATH_TMP);
-
- // We measure the effective time that passed as wall-clock and include all
- // file IO overhead as the terminator will do so in its measurement, too.
- MeasuredDurations[currentPhase - 1] = Math.floor(
- (Date.now() - beforeWait) / HEARTBEAT_MS
- );
- }
-
- Assert.equal(DATA.length, KEYS.length, "We have data for each phase");
-
- for (let i = 0; i < KEYS.length; i++) {
- let lastDuration = DATA[KEYS.length - 1][KEYS[i]];
- Assert.equal(
- typeof lastDuration,
- "number",
- "Duration of phase " + i + ":" + KEYS[i] + " is a number"
- );
-
- // The durations are only meaningful after we advanced to the next phase.
- if (i < KEYS.length - 1) {
- // So we read it from the data written for the following phase.
- let ticksDuration = DATA[i + 1][KEYS[i]];
- let measuredDuration = MeasuredDurations[i];
- info(
- "measuredDuration:" + measuredDuration + " - " + typeof measuredDuration
- );
- Assert.lessOrEqual(
- ticksDuration,
- measuredDuration + 2,
- "Duration of phase " + i + ":" + KEYS[i] + " is not too long"
- );
- Assert.greaterOrEqual(
- ticksDuration,
- 0, // TODO: Raise the lower boundary after bug 1768795.
- "Duration of phase " + i + ":" + KEYS[i] + " is not too short"
- );
- }
- // This check is done only for phases <= xpcom-shutdown-threads
- // where we have two data points.
- if (i < KEYS.length - 2) {
- let ticksDuration = DATA[i + 1][KEYS[i]];
- Assert.equal(
- ticksDuration,
- DATA[KEYS.length - 1][KEYS[i]],
- "Duration of phase " + i + ":" + KEYS[i] + " hasn't changed"
- );
- }
- }
-
- // Note that after this check the KEYS array remains sorted, so this
- // must be the last check to not get confused.
- Assert.equal(
- Object.keys(DATA[KEYS.length - 1])
- .sort()
- .join(", "),
- KEYS.sort().join(", "),
- "The last file contains all expected keys"
- );
-});
diff --git a/toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js b/toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js
deleted file mode 100644
index 79aecd818b..0000000000
--- a/toolkit/components/terminator/tests/xpcshell/test_terminator_reload.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that the Shutdown Terminator reloads durations correctly
-
-const HISTOGRAMS = {
- "quit-application": "SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION",
- "profile-change-net-teardown":
- "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_NET_TEARDOWN",
- "profile-change-teardown":
- "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN",
- "profile-before-change":
- "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE",
- "profile-before-change-qm":
- "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE_QM",
- "xpcom-will-shutdown": "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN",
- "xpcom-shutdown": "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_SHUTDOWN",
-};
-
-let PATH;
-
-add_setup(async function init() {
- do_get_profile();
- PATH = PathUtils.join(PathUtils.localProfileDir, "ShutdownDuration.json");
-});
-
-add_task(async function test_reload() {
- info("Forging data");
- let data = {};
- let telemetrySnapshots = Services.telemetry.getSnapshotForHistograms(
- "main",
- false /* clear */
- ).parent;
- let i = 0;
- for (let k of Object.keys(HISTOGRAMS)) {
- let id = HISTOGRAMS[k];
- data[k] = i++;
- Assert.equal(
- telemetrySnapshots[id] || undefined,
- undefined,
- "Histogram " + id + " is empty"
- );
- }
-
- // Extra fields that nsTerminator reports that we do not have histograms for.
- data["xpcom-shutdown-threads"] = 123;
- data.XPCOMShutdownFinal = 456;
- data.CCPostLastCycleCollection = 789;
-
- await IOUtils.writeJSON(PATH, data);
-
- const TOPIC = "shutdown-terminator-telemetry-updated";
-
- let wait = new Promise(resolve =>
- Services.obs.addObserver(function observer() {
- info("Telemetry has been updated");
- Services.obs.removeObserver(observer, TOPIC);
- resolve();
- }, TOPIC)
- );
-
- info("Starting nsTerminatorTelemetry");
- let tt = Cc[
- "@mozilla.org/toolkit/shutdown-terminator-telemetry;1"
- ].createInstance(Ci.nsIObserver);
- tt.observe(null, "profile-after-change", "");
-
- info("Waiting until telemetry is updated");
- // Now wait until Telemetry is updated
- await wait;
-
- telemetrySnapshots = Services.telemetry.getSnapshotForHistograms(
- "main",
- false /* clear */
- ).parent;
- for (let k of Object.keys(HISTOGRAMS)) {
- let id = HISTOGRAMS[k];
- info("Testing histogram " + id);
- let snapshot = telemetrySnapshots[id];
- let count = 0;
- for (let x of Object.values(snapshot.values)) {
- count += x;
- }
- Assert.equal(count, 1, "We have added one item");
- }
-});
diff --git a/toolkit/components/terminator/tests/xpcshell/xpcshell.toml b/toolkit/components/terminator/tests/xpcshell/xpcshell.toml
index cb328ca2c8..67cc36f265 100644
--- a/toolkit/components/terminator/tests/xpcshell/xpcshell.toml
+++ b/toolkit/components/terminator/tests/xpcshell/xpcshell.toml
@@ -1,15 +1,10 @@
[DEFAULT]
head = ""
-["test_terminator_record.js"]
+["test_terminator_advance_phases.js"]
skip-if = [
"debug",
"asan", # Disabled by bug 1242084, bug 1255484 will enable it again
"ccov", # Bug 1607583 tracks the ccov failure
"tsan", # Bug 1683730 made this timeout for tsan.
]
-run-sequentially = "very high failure rate in parallel"
-
-["test_terminator_reload.js"]
-skip-if = ["os == 'android'"]
-run-sequentially = "very high failure rate in parallel"