summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/head_telemetry.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/head_telemetry.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/head_telemetry.js172
1 files changed, 172 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/head_telemetry.js b/toolkit/components/extensions/test/xpcshell/head_telemetry.js
new file mode 100644
index 0000000000..ccbdd4d787
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/head_telemetry.js
@@ -0,0 +1,172 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+/* exported IS_OOP, valueSum, clearHistograms, getSnapshots, promiseTelemetryRecorded */
+
+ChromeUtils.defineESModuleGetters(this, {
+ ContentTaskUtils: "resource://testing-common/ContentTaskUtils.sys.mjs",
+});
+
+// Allows to run xpcshell telemetry test also on products (e.g. Thunderbird) where
+// that telemetry wouldn't be actually collected in practice (but to be sure
+// that it will work on those products as well by just adding the product in
+// the telemetry metric definitions if it turns out we want to).
+Services.prefs.setBoolPref(
+ "toolkit.telemetry.testing.overrideProductsCheck",
+ true
+);
+
+const IS_OOP = Services.prefs.getBoolPref("extensions.webextensions.remote");
+
+const WEBEXT_EVENTPAGE_RUNNING_TIME_MS = "WEBEXT_EVENTPAGE_RUNNING_TIME_MS";
+const WEBEXT_EVENTPAGE_RUNNING_TIME_MS_BY_ADDONID =
+ "WEBEXT_EVENTPAGE_RUNNING_TIME_MS_BY_ADDONID";
+const WEBEXT_EVENTPAGE_IDLE_RESULT_COUNT = "WEBEXT_EVENTPAGE_IDLE_RESULT_COUNT";
+const WEBEXT_EVENTPAGE_IDLE_RESULT_COUNT_BY_ADDONID =
+ "WEBEXT_EVENTPAGE_IDLE_RESULT_COUNT_BY_ADDONID";
+
+// Keep this in sync with the order in Histograms.json for "WEBEXT_EVENTPAGE_IDLE_RESULT_COUNT":
+// the position of the category string determines the index of the values collected in the categorial
+// histogram and so the existing labels should be kept in the exact same order and any new category
+// to be added in the future should be appended to the existing ones.
+const HISTOGRAM_EVENTPAGE_IDLE_RESULT_CATEGORIES = [
+ "suspend",
+ "reset_other",
+ "reset_event",
+ "reset_listeners",
+ "reset_nativeapp",
+ "reset_streamfilter",
+];
+
+function valueSum(arr) {
+ return Object.values(arr).reduce((a, b) => a + b, 0);
+}
+
+function clearHistograms() {
+ Services.telemetry.getSnapshotForHistograms("main", true /* clear */);
+ Services.telemetry.getSnapshotForKeyedHistograms("main", true /* clear */);
+}
+
+function getSnapshots(process) {
+ return Services.telemetry.getSnapshotForHistograms("main", false /* clear */)[
+ process
+ ];
+}
+
+function getKeyedSnapshots(process) {
+ return Services.telemetry.getSnapshotForKeyedHistograms(
+ "main",
+ false /* clear */
+ )[process];
+}
+
+// TODO Bug 1357509: There is no good way to make sure that the parent received
+// the histogram entries from the extension and content processes. Let's stick
+// to the ugly, spinning the event loop until we have a good approach.
+function promiseTelemetryRecorded(id, process, expectedCount) {
+ let condition = () => {
+ let snapshot = Services.telemetry.getSnapshotForHistograms(
+ "main",
+ false /* clear */
+ )[process][id];
+ return snapshot && valueSum(snapshot.values) >= expectedCount;
+ };
+ return ContentTaskUtils.waitForCondition(condition);
+}
+
+function promiseKeyedTelemetryRecorded(
+ id,
+ process,
+ expectedKey,
+ expectedCount
+) {
+ let condition = () => {
+ let snapshot = Services.telemetry.getSnapshotForKeyedHistograms(
+ "main",
+ false /* clear */
+ )[process][id];
+ return (
+ snapshot &&
+ snapshot[expectedKey] &&
+ valueSum(snapshot[expectedKey].values) >= expectedCount
+ );
+ };
+ return ContentTaskUtils.waitForCondition(condition);
+}
+
+function assertHistogramSnapshot(
+ histogramId,
+ { keyed, processSnapshot, expectedValue },
+ msg
+) {
+ let histogram;
+
+ if (keyed) {
+ histogram = Services.telemetry.getKeyedHistogramById(histogramId);
+ } else {
+ histogram = Services.telemetry.getHistogramById(histogramId);
+ }
+
+ let res = processSnapshot(histogram.snapshot());
+ Assert.deepEqual(res, expectedValue, msg);
+ return res;
+}
+
+function assertHistogramEmpty(histogramId) {
+ assertHistogramSnapshot(
+ histogramId,
+ {
+ processSnapshot: snapshot => snapshot.sum,
+ expectedValue: 0,
+ },
+ `No data recorded for histogram: ${histogramId}.`
+ );
+}
+
+function assertKeyedHistogramEmpty(histogramId) {
+ assertHistogramSnapshot(
+ histogramId,
+ {
+ keyed: true,
+ processSnapshot: snapshot => Object.keys(snapshot).length,
+ expectedValue: 0,
+ },
+ `No data recorded for histogram: ${histogramId}.`
+ );
+}
+
+function assertHistogramCategoryNotEmpty(
+ histogramId,
+ { category, categories, keyed, key },
+ msg
+) {
+ let message = msg;
+
+ if (!msg) {
+ message = `Data recorded for histogram: ${histogramId}, category "${category}"`;
+ if (keyed) {
+ message += `, key "${key}"`;
+ }
+ }
+
+ assertHistogramSnapshot(
+ histogramId,
+ {
+ keyed,
+ processSnapshot: snapshot => {
+ const categoryIndex = categories.indexOf(category);
+ if (keyed) {
+ return {
+ [key]: snapshot[key]
+ ? snapshot[key].values[categoryIndex] > 0
+ : null,
+ };
+ }
+ return snapshot.values[categoryIndex] > 0;
+ },
+ expectedValue: keyed ? { [key]: true } : true,
+ },
+ message
+ );
+}