Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'android'
- Manifest: toolkit/components/telemetry/tests/unit/xpcshell.toml
/* Any copyright is dedicated to the Public Domain.
*/
/**
* This file only contains the |test_abortedSessionQueued| test. This needs
* to be in a separate, stand-alone file since we're initializing Telemetry
* twice, in a non-standard way to simulate incorrect shutdowns. Doing this
* in other files might interfere with the other tests.
*/
const { TelemetryStorage } = ChromeUtils.importESModule(
"resource://gre/modules/TelemetryStorage.sys.mjs"
);
const DATAREPORTING_DIR = "datareporting";
const ABORTED_PING_FILE_NAME = "aborted-session-ping";
const ABORTED_SESSION_UPDATE_INTERVAL_MS = 5 * 60 * 1000;
const PING_TYPE_MAIN = "main";
const REASON_ABORTED_SESSION = "aborted-session";
const TEST_PING_TYPE = "test-ping-type";
ChromeUtils.defineLazyGetter(this, "DATAREPORTING_PATH", function () {
return PathUtils.join(PathUtils.profileDir, DATAREPORTING_DIR);
});
function sendPing() {
if (PingServer.started) {
} else {
}
let options = {
addClientId: true,
addEnvironment: true,
};
return TelemetryController.submitExternalPing(TEST_PING_TYPE, {}, options);
}
add_task(async function test_setup() {
do_get_profile();
PingServer.start();
Services.prefs.setCharPref(
TelemetryUtils.Preferences.Server,
);
});
add_task(async function test_abortedSessionQueued() {
const ABORTED_FILE = PathUtils.join(
DATAREPORTING_PATH,
ABORTED_PING_FILE_NAME
);
// Make sure the aborted sessions directory does not exist to test its creation.
await IOUtils.remove(DATAREPORTING_PATH, {
ignoreAbsent: true,
recursive: true,
});
let schedulerTickCallback = null;
let now = new Date(2040, 1, 1, 0, 0, 0);
fakeNow(now);
// Fake scheduler functions to control aborted-session flow in tests.
fakeSchedulerTimer(
callback => (schedulerTickCallback = callback),
() => {}
);
await TelemetryController.testReset();
Assert.ok(
await IOUtils.exists(DATAREPORTING_PATH),
"Telemetry must create the aborted session directory when starting."
);
// Fake now again so that the scheduled aborted-session save takes place.
now = futureDate(now, ABORTED_SESSION_UPDATE_INTERVAL_MS);
fakeNow(now);
// The first aborted session checkpoint must take place right after the initialisation.
Assert.ok(!!schedulerTickCallback);
// Execute one scheduler tick.
await schedulerTickCallback();
// Check that the aborted session is due at the correct time.
Assert.ok(
await IOUtils.exists(ABORTED_FILE),
"There must be an aborted session ping."
);
await TelemetryStorage.testClearPendingPings();
PingServer.clearRequests();
await TelemetryController.testReset();
Assert.ok(
!(await IOUtils.exists(ABORTED_FILE)),
"The aborted session ping must be removed from the aborted session ping directory."
);
// Restarting Telemetry again to trigger sending pings in TelemetrySend.
await TelemetryController.testReset();
// We should have received an aborted-session ping.
const receivedPing = await PingServer.promiseNextPing();
Assert.equal(
receivedPing.type,
PING_TYPE_MAIN,
"Should have the correct type"
);
Assert.equal(
receivedPing.payload.info.reason,
REASON_ABORTED_SESSION,
"Ping should have the correct reason"
);
await TelemetryController.testShutdown();
});
/*
* An aborted-session ping might have been written when Telemetry upload was disabled and
* the profile had a canary client ID.
* These pings should not be sent out at a later point when Telemetry is enabled again.
*/
add_task(async function test_abortedSession_canary_clientid() {
const ABORTED_FILE = PathUtils.join(
DATAREPORTING_PATH,
ABORTED_PING_FILE_NAME
);
// Make sure the aborted sessions directory does not exist to test its creation.
await IOUtils.remove(DATAREPORTING_PATH, {
ignoreAbsent: true,
recursive: true,
});
let schedulerTickCallback = null;
let now = new Date(2040, 1, 1, 0, 0, 0);
fakeNow(now);
// Fake scheduler functions to control aborted-session flow in tests.
fakeSchedulerTimer(
callback => (schedulerTickCallback = callback),
() => {}
);
await TelemetryController.testReset();
Assert.ok(
await IOUtils.exists(DATAREPORTING_PATH),
"Telemetry must create the aborted session directory when starting."
);
// Fake now again so that the scheduled aborted-session save takes place.
now = futureDate(now, ABORTED_SESSION_UPDATE_INTERVAL_MS);
fakeNow(now);
// The first aborted session checkpoint must take place right after the initialisation.
Assert.ok(!!schedulerTickCallback);
// Execute one scheduler tick.
await schedulerTickCallback();
// Check that the aborted session is due at the correct time.
Assert.ok(
await IOUtils.exists(ABORTED_FILE),
"There must be an aborted session ping."
);
// Set clientID in aborted-session ping to canary value
let abortedPing = await IOUtils.readJSON(ABORTED_FILE);
abortedPing.clientId = TelemetryUtils.knownClientID;
await IOUtils.writeJSON(ABORTED_FILE, abortedPing);
await TelemetryStorage.testClearPendingPings();
PingServer.clearRequests();
await TelemetryController.testReset();
Assert.ok(
!(await IOUtils.exists(ABORTED_FILE)),
"The aborted session ping must be removed from the aborted session ping directory."
);
// Restarting Telemetry again to trigger sending pings in TelemetrySend.
await TelemetryController.testReset();
// Trigger a test ping, so we can verify the server received something.
sendPing();
// We should have received an aborted-session ping.
const receivedPing = await PingServer.promiseNextPing();
Assert.equal(
receivedPing.type,
TEST_PING_TYPE,
"Should have received test ping"
);
await TelemetryController.testShutdown();
});
add_task(async function stopServer() {
await PingServer.stop();
});