--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
@@ -1,12 +1,14 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
*/
+ChromeUtils.defineModuleGetter(this, "TestUtils", "resource://testing-common/TestUtils.jsm");
+
const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN;
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
function checkEventFormat(events) {
Assert.ok(Array.isArray(events), "Events should be serialized to an array.");
for (let e of events) {
Assert.ok(Array.isArray(e), "Event should be an array.");
Assert.greaterOrEqual(e.length, 4, "Event should have at least 4 elements.");
@@ -99,44 +101,59 @@ add_task(async function test_recording_s
["telemetry.test", "test1", "object1"],
["telemetry.test.second", "test", "object1"],
];
// Both test categories should be off by default.
events.forEach(e => Telemetry.recordEvent(...e));
let snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.equal(Object.keys(snapshot).length, 0, "Should not have recorded any events.");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.equal(Object.keys(snapshot).length, 0, "Should not have recorded any events in storage two.");
checkEventSummary(events.map(e => (["parent", e, 1])), true);
// Enable one test category and see that we record correctly.
Telemetry.setEventRecordingEnabled("telemetry.test", true);
events.forEach(e => Telemetry.recordEvent(...e));
snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
Assert.equal(snapshot.parent.length, 1, "Should have recorded one event.");
Assert.equal(snapshot.parent[0][1], "telemetry.test", "Should have recorded one event in telemetry.test");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ Assert.equal(snapshot.parent.length, 1, "Should have recorded one event in storage two.");
+ Assert.equal(snapshot.parent[0][1], "telemetry.test", "Should have recorded one event in telemetry.test (storage two)");
checkEventSummary(events.map(e => (["parent", e, 1])), true);
// Also enable the other test category and see that we record correctly.
Telemetry.setEventRecordingEnabled("telemetry.test.second", true);
events.forEach(e => Telemetry.recordEvent(...e));
snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
Assert.equal(snapshot.parent.length, 2, "Should have recorded two events.");
Assert.equal(snapshot.parent[0][1], "telemetry.test", "Should have recorded one event in telemetry.test");
Assert.equal(snapshot.parent[1][1], "telemetry.test.second", "Should have recorded one event in telemetry.test.second");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ Assert.equal(snapshot.parent.length, 2, "Should have recorded two events in storage two.");
+ Assert.equal(snapshot.parent[0][1], "telemetry.test", "Should have recorded one event in telemetry.test (storage two)");
+ Assert.equal(snapshot.parent[1][1], "telemetry.test.second", "Should have recorded one event in telemetry.test.second (storage two)");
checkEventSummary(events.map(e => (["parent", e, 1])), true);
// Now turn of one category again and check that this works as expected.
Telemetry.setEventRecordingEnabled("telemetry.test", false);
events.forEach(e => Telemetry.recordEvent(...e));
snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
Assert.equal(snapshot.parent.length, 1, "Should have recorded one event.");
Assert.equal(snapshot.parent[0][1], "telemetry.test.second", "Should have recorded one event in telemetry.test.second");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ Assert.equal(snapshot.parent.length, 1, "Should have recorded one event in storage two.");
+ Assert.equal(snapshot.parent[0][1], "telemetry.test.second", "Should have recorded one event in telemetry.test.second (storage two)");
checkEventSummary(events.map(e => (["parent", e, 1])), true);
});
add_task(async function recording_setup() {
// Make sure both test categories are enabled for the remaining tests.
// Otherwise their event recording won't work.
Telemetry.setEventRecordingEnabled("telemetry.test", true);
Telemetry.setEventRecordingEnabled("telemetry.test.second", true);
@@ -219,57 +236,85 @@ add_task(async function test_recording()
Assert.deepEqual(recordedData, expectedData, "The recorded event data should match.");
}
};
// Check that the expected events were recorded.
let snapshot = Telemetry.snapshotEvents(OPTIN, false);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
checkEvents(snapshot.parent, expected);
+ snapshot = Telemetry.snapshotEvents(OPTIN, false, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ checkEvents(snapshot.parent, expected);
// Check serializing only opt-out events.
snapshot = Telemetry.snapshotEvents(OPTOUT, false);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
let filtered = expected.filter(e => !!e.optout);
checkEvents(snapshot.parent, filtered);
+ snapshot = Telemetry.snapshotEvents(OPTOUT, false, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ checkEvents(snapshot.parent, filtered);
});
add_task(async function test_clear() {
Telemetry.clearEvents();
const COUNT = 10;
for (let i = 0; i < COUNT; ++i) {
Telemetry.recordEvent("telemetry.test", "test1", "object1");
Telemetry.recordEvent("telemetry.test.second", "test", "object1");
}
// Check that events were recorded.
// The events are cleared by passing the respective flag.
let snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
Assert.equal(snapshot.parent.length, 2 * COUNT, `Should have recorded ${2 * COUNT} events.`);
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ Assert.equal(snapshot.parent.length, 2 * COUNT, `Should have recorded ${2 * COUNT} events in storage two.`);
// Now the events should be cleared.
snapshot = Telemetry.snapshotEvents(OPTIN, false);
Assert.equal(Object.keys(snapshot).length, 0, `Should have cleared the events.`);
+ snapshot = Telemetry.snapshotEvents(OPTIN, false, false);
+ Assert.equal(Object.keys(snapshot).length, 0, `Should have cleared the events from storage two.`);
+
+ for (let i = 0; i < COUNT; ++i) {
+ Telemetry.recordEvent("telemetry.test", "test1", "object1");
+ Telemetry.recordEvent("telemetry.test.second", "test", "object1");
+ }
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true, 5);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process.");
+ Assert.equal(snapshot.parent.length, 5, "Should have returned 5 events");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process.");
+ Assert.equal(snapshot.parent.length, (2 * COUNT) - 5, `Should have returned ${(2 * COUNT) - 5} events`);
+
});
add_task(async function test_expiry() {
Telemetry.clearEvents();
// Recording call with event that is expired by version.
Telemetry.recordEvent("telemetry.test", "expired_version", "object1");
let snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.equal(Object.keys(snapshot).length, 0, "Should not record event with expired version.");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.equal(Object.keys(snapshot).length, 0, "Should not record event with expired version in storage two.");
// Recording call with event that has expiry_version set into the future.
Telemetry.recordEvent("telemetry.test", "not_expired_optout", "object1");
snapshot = Telemetry.snapshotEvents(OPTOUT, true);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
Assert.equal(snapshot.parent.length, 1, "Should record event when version is not expired.");
+ snapshot = Telemetry.snapshotEvents(OPTOUT, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ Assert.equal(snapshot.parent.length, 1, "Should record event when version is not expired in storage two.");
});
add_task(async function test_invalidParams() {
Telemetry.clearEvents();
// Recording call with wrong type for value argument.
Telemetry.recordEvent("telemetry.test", "test1", "object1", 1);
let snapshot = Telemetry.snapshotEvents(OPTIN, true);
@@ -289,30 +334,40 @@ add_task(async function test_invalidPara
Telemetry.recordEvent("telemetry.test", "test1", "object1", null, {"key3": 1});
snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.equal(Object.keys(snapshot).length, 0, "Should not record event when extra argument with invalid value type is passed.");
});
add_task(async function test_storageLimit() {
Telemetry.clearEvents();
+ let limitReached = TestUtils.topicObserved("event-telemetry-storage-limit-reached");
// Record more events than the storage limit allows.
let LIMIT = 1000;
let COUNT = LIMIT + 10;
for (let i = 0; i < COUNT; ++i) {
Telemetry.recordEvent("telemetry.test", "test1", "object1", String(i));
}
+ await limitReached;
+ Assert.ok(true, "Topic was notified when event limit was reached");
+
// Check that the right events were recorded.
let snapshot = Telemetry.snapshotEvents(OPTIN, true);
Assert.ok(("parent" in snapshot), "Should have entry for main process.");
let events = snapshot.parent;
Assert.equal(events.length, LIMIT, `Should have only recorded ${LIMIT} events`);
Assert.ok(events.every((e, idx) => e[4] === String(idx)),
"Should have recorded all events from before hitting the limit.");
+ snapshot = Telemetry.snapshotEvents(OPTIN, true, true);
+ Assert.ok(("parent" in snapshot), "Should have entry for main process from storage two.");
+ events = snapshot.parent;
+ Assert.equal(events.length, COUNT, `Should have recorded all ${COUNT} events in storage two`);
+ Assert.ok(events.every((e, idx) => e[4] === String(idx)),
+ "Should have recorded all events in storage two.");
});
add_task(async function test_valueLimits() {
Telemetry.clearEvents();
// Record values that are at or over the limits for string lengths.
let LIMIT = 80;
let expected = [