Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
*/
const { TelemetryController } = ChromeUtils.importESModule(
);
const { ContentTaskUtils } = ChromeUtils.importESModule(
);
const MESSAGE_CHILD_TEST_DONE = "ChildTest:Done";
const RECORDED_CONTENT_EVENTS = [
["telemetry.test", "content_only", "object1"],
["telemetry.test", "main_and_content", "object1"],
["telemetry.test", "content_only", "object1", "some value"],
["telemetry.test", "content_only", "object1", null, { foo: "x", bar: "y" }],
[
"telemetry.test",
"content_only",
"object1",
"some value",
{ foo: "x", bar: "y" },
],
];
const UNRECORDED_CONTENT_EVENTS = [["telemetry.test", "main_only", "object1"]];
const RECORDED_PARENT_EVENTS = [
["telemetry.test", "main_and_content", "object1"],
["telemetry.test", "main_only", "object1"],
];
const UNRECORDED_PARENT_EVENTS = [
["telemetry.test", "content_only", "object1"],
];
const RECORDED_DYNAMIC_EVENTS = [
["telemetry.test.dynamic", "test1", "object1"],
["telemetry.test.dynamic", "test2", "object1"],
];
function run_child_test() {
// Record some events in the "content" process.
RECORDED_CONTENT_EVENTS.forEach(e => Telemetry.recordEvent(...e));
// These events should not be recorded for the content process.
UNRECORDED_CONTENT_EVENTS.forEach(e => Telemetry.recordEvent(...e));
// Record some dynamic events from the content process.
RECORDED_DYNAMIC_EVENTS.forEach(e => Telemetry.recordEvent(...e));
}
/**
* This function waits until content events are reported into the
* events snapshot.
*/
async function waitForContentEvents() {
await ContentTaskUtils.waitForCondition(() => {
const snapshot = Telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
);
return (
Object.keys(snapshot).includes("content") &&
Object.keys(snapshot).includes("dynamic")
);
});
}
add_task(async function () {
if (!runningInParent) {
TelemetryController.testSetupContent();
run_child_test();
do_send_remote_message(MESSAGE_CHILD_TEST_DONE);
return;
}
// Setup.
do_get_profile(true);
await loadAddonManager(APP_ID, APP_NAME, APP_VERSION, PLATFORM_VERSION);
finishAddonManagerStartup();
fakeIntlReady();
await TelemetryController.testSetup();
// Make sure we don't generate unexpected pings due to pref changes.
await setEmptyPrefWatchlist();
// Enable recording for the test event category.
Telemetry.setEventRecordingEnabled("telemetry.test", true);
// Register dynamic test events.
Telemetry.registerEvents("telemetry.test.dynamic", {
// Event with only required fields.
test1: {
methods: ["test1"],
objects: ["object1"],
},
// Event with extra_keys.
test2: {
methods: ["test2", "test2b"],
objects: ["object1"],
extra_keys: ["key1", "key2"],
},
});
// Run test in child, don't wait for it to finish: just wait for the
// MESSAGE_CHILD_TEST_DONE.
const timestampBeforeChildEvents = Telemetry.msSinceProcessStart();
run_test_in_child("test_ChildEvents.js");
await do_await_remote_message(MESSAGE_CHILD_TEST_DONE);
// Once events are set by the content process, they don't immediately get
// sent to the parent process. Wait for the Telemetry IPC Timer to trigger
// and batch send the data back to the parent process.
await waitForContentEvents();
const timestampAfterChildEvents = Telemetry.msSinceProcessStart();
// Also record some events in the parent.
RECORDED_PARENT_EVENTS.forEach(e => Telemetry.recordEvent(...e));
UNRECORDED_PARENT_EVENTS.forEach(e => Telemetry.recordEvent(...e));
let snapshot = Telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
);
Assert.ok("parent" in snapshot, "Should have main process section");
Assert.ok(
!!snapshot.parent.length,
"Main process section should have events."
);
Assert.ok("content" in snapshot, "Should have child process section");
Assert.ok(
!!snapshot.content.length,
"Child process section should have events."
);
Assert.ok("dynamic" in snapshot, "Should have dynamic process section");
Assert.ok(
!!snapshot.dynamic.length,
"Dynamic process section should have events."
);
// Check that the expected events are present from the content process.
let contentEvents = snapshot.content.map(e => e.slice(1));
Assert.equal(
contentEvents.length,
RECORDED_CONTENT_EVENTS.length,
"Should match expected event count."
);
for (let i = 0; i < RECORDED_CONTENT_EVENTS.length; ++i) {
Assert.deepEqual(
contentEvents[i],
RECORDED_CONTENT_EVENTS[i],
"Should have recorded expected event."
);
}
// Check that the expected events are present from the parent process.
let parentEvents = snapshot.parent.map(e => e.slice(1));
Assert.equal(
parentEvents.length,
RECORDED_PARENT_EVENTS.length,
"Should match expected event count."
);
for (let i = 0; i < RECORDED_PARENT_EVENTS.length; ++i) {
Assert.deepEqual(
parentEvents[i],
RECORDED_PARENT_EVENTS[i],
"Should have recorded expected event."
);
}
// Check that the expected dynamic events are present.
let dynamicEvents = snapshot.dynamic.map(e => e.slice(1));
Assert.equal(
dynamicEvents.length,
RECORDED_DYNAMIC_EVENTS.length,
"Should match expected event count."
);
for (let i = 0; i < RECORDED_DYNAMIC_EVENTS.length; ++i) {
Assert.deepEqual(
dynamicEvents[i],
RECORDED_DYNAMIC_EVENTS[i],
"Should have recorded expected event."
);
}
// Check that the event timestamps are in the expected ranges.
let contentTimestamps = snapshot.content.map(e => e[0]);
let parentTimestamps = snapshot.parent.map(e => e[0]);
Assert.ok(
contentTimestamps.every(
ts =>
ts > Math.floor(timestampBeforeChildEvents) &&
ts < timestampAfterChildEvents
),
"All content event timestamps should be in the expected time range."
);
Assert.ok(
parentTimestamps.every(ts => ts >= Math.floor(timestampAfterChildEvents)),
"All parent event timestamps should be in the expected time range."
);
// Make sure all events are cleared from storage properly.
snapshot = Telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
true
);
Assert.greaterOrEqual(
Object.keys(snapshot).length,
2,
"Should have events from at least two processes."
);
snapshot = Telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
true
);
Assert.equal(
Object.keys(snapshot).length,
0,
"Should have cleared all events from storage."
);
});