--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
@@ -31,61 +31,86 @@ function checkEventFormat(events) {
Assert.ok(Object.keys(extra).every(k => typeof(k) == "string"),
"All extra keys should be strings.");
Assert.ok(Object.values(extra).every(v => typeof(v) == "string"),
"All extra values should be strings.");
}
}
}
+/**
+ * @param summaries is of the form
+ * [{process, [event category, event object, event method], count}]
+ * @param clearScalars - true if you want to clear the scalars
+ */
+function checkEventSummary(summaries, clearScalars) {
+ let scalars = Telemetry.snapshotKeyedScalars(OPTOUT, clearScalars);
+ dump(JSON.stringify(summaries));
+ for (let [process, [category, eObject, method], count] of summaries) {
+ let uniqueEventName = `${category}#${eObject}#${method}`;
+ let summaryCount;
+ if (process === "dynamic") {
+ summaryCount = scalars.dynamic["telemetry.dynamic_event_counts"][uniqueEventName];
+ } else {
+ summaryCount = scalars[process]["telemetry.event_counts"][uniqueEventName];
+ }
+ Assert.equal(summaryCount, count, `${uniqueEventName} had wrong summary count`);
+ }
+}
+
add_task(async function test_recording_state() {
const events = [
["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.");
+ 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");
+ 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");
+ 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");
+ 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);
});
add_task(async function test_recording() {
+ Telemetry.clearScalars();
Telemetry.clearEvents();
// Record some events.
let expected = [
{optout: false, event: ["telemetry.test", "test1", "object1"]},
{optout: false, event: ["telemetry.test", "test2", "object2"]},
{optout: false, event: ["telemetry.test", "test1", "object1", "value"]},
@@ -111,16 +136,29 @@ add_task(async function test_recording()
// Strip off trailing null values to match the serialized events.
for (let entry of expected) {
let e = entry.event;
while ((e.length >= 3) && (e[e.length - 1] === null)) {
e.pop();
}
}
+ // Check that the events were summarized properly.
+ let summaries = {};
+ expected.forEach(({optout, event}) => {
+ let [category, eObject, method] = event;
+ let uniqueEventName = `${category}#${eObject}#${method}`;
+ if (!(uniqueEventName in summaries)) {
+ summaries[uniqueEventName] = ["parent", event, 1];
+ } else {
+ summaries[uniqueEventName][2]++;
+ }
+ });
+ checkEventSummary(Object.values(summaries), true);
+
// The following should not result in any recorded events.
Assert.throws(() => Telemetry.recordEvent("unknown.category", "test1", "object1"),
/Error: Unknown event: \["unknown.category", "test1", "object1"\]/,
"Should throw on unknown category.");
Assert.throws(() => Telemetry.recordEvent("telemetry.test", "unknown", "object1"),
/Error: Unknown event: \["telemetry.test", "unknown", "object1"\]/,
"Should throw on unknown method.");
Assert.throws(() => Telemetry.recordEvent("telemetry.test", "test1", "unknown"),
@@ -294,16 +332,17 @@ add_task(async function test_unicodeValu
let events = snapshot.parent;
Assert.equal(events.length, 2, "Should have recorded 2 events.");
Assert.equal(events[0][4], value, "Should have recorded the right value.");
Assert.equal(events[1][5].key1, value, "Should have recorded the right extra value.");
});
add_task(async function test_dynamicEvents() {
Telemetry.clearEvents();
+ Telemetry.clearScalars();
Telemetry.canRecordExtended = true;
// Register some test events.
Telemetry.registerEvents("telemetry.test.dynamic", {
// Event with only required fields.
"test1": {
methods: ["test1"],
objects: ["object1"],
@@ -355,16 +394,19 @@ add_task(async function test_dynamicEven
];
let events = snapshot.dynamic;
Assert.equal(events.length, expected.length, "Should have recorded the right amount of events.");
for (let i = 0; i < expected.length; ++i) {
Assert.deepEqual(events[i].slice(1), expected[i],
"Should have recorded the expected event data.");
}
+ // Check that we've summarized the recorded events
+ checkEventSummary(expected.map(ev => ["dynamic", ev, 1]), true);
+
// Check that the opt-out snapshot contains only the one expected event.
snapshot = Telemetry.snapshotEvents(OPTOUT, false);
Assert.ok(("dynamic" in snapshot), "Should have dynamic events in the snapshot.");
Assert.equal(snapshot.dynamic.length, 1, "Should have one opt-out event in the snapshot.");
expected = ["telemetry.test.dynamic", "test4", "object1"];
Assert.deepEqual(snapshot.dynamic[0].slice(1), expected);
// Recording with unknown extra keys should be ignored and print an error.