summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/head_telemetry.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/head_telemetry.js')
-rw-r--r--netwerk/test/unit/head_telemetry.js171
1 files changed, 171 insertions, 0 deletions
diff --git a/netwerk/test/unit/head_telemetry.js b/netwerk/test/unit/head_telemetry.js
new file mode 100644
index 0000000000..c3b1ec66aa
--- /dev/null
+++ b/netwerk/test/unit/head_telemetry.js
@@ -0,0 +1,171 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+"use strict";
+
+const { TelemetryTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TelemetryTestUtils.sys.mjs"
+);
+
+var HandshakeTelemetryHelpers = {
+ HISTOGRAMS: ["SSL_HANDSHAKE_RESULT", "SSL_TIME_UNTIL_READY"],
+ FLAVORS: ["", "_FIRST_TRY", "_CONSERVATIVE", "_ECH", "_ECH_GREASE"],
+
+ /**
+ * Prints the Histogram to console.
+ *
+ * @param {*} name The identifier of the Histogram.
+ */
+ dumpHistogram(name) {
+ let values = Services.telemetry.getHistogramById(name).snapshot().values;
+ dump(`${name}: ${JSON.stringify(values)}\n`);
+ },
+
+ /**
+ * Counts the number of entries in the histogram, ignoring the bucket value.
+ * e.g. {0: 1, 1: 2, 3: 3} has 6 entries.
+ *
+ * @param {Object} histObject The histogram to count the entries of.
+ * @returns The count of the number of entries in the histogram.
+ */
+ countHistogramEntries(histObject) {
+ Assert.ok(
+ !mozinfo.socketprocess_networking,
+ "Histograms don't populate on network process"
+ );
+ let count = 0;
+ let m = histObject.snapshot().values;
+ for (let k in m) {
+ count += m[k];
+ }
+ return count;
+ },
+
+ /**
+ * Assert that the histogram index is the right value. It expects that
+ * other indexes are all zero.
+ *
+ * @param {Object} histogram The histogram to check.
+ * @param {Number} index The index to check against the expected value.
+ * @param {Number} expected The expected value of the index.
+ */
+ assertHistogramMap(histogram, expectedEntries) {
+ Assert.ok(
+ !mozinfo.socketprocess_networking,
+ "Histograms don't populate on network process"
+ );
+ let snapshot = JSON.parse(JSON.stringify(histogram));
+ for (let [Tk, Tv] of expectedEntries.entries()) {
+ let found = false;
+ for (let [i, val] of Object.entries(snapshot.values)) {
+ if (i == Tk) {
+ found = true;
+ Assert.equal(val, Tv, `expected counts should match at index ${i}`);
+ snapshot.values[i] = 0; // Reset the value
+ }
+ }
+ Assert.ok(found, `Should have found an entry at index ${Tk}`);
+ }
+ for (let k in snapshot.values) {
+ Assert.equal(
+ snapshot.values[k],
+ 0,
+ `Should NOT have found an entry at index ${k} of value ${snapshot.values[k]}`
+ );
+ }
+ },
+
+ /**
+ * Generates the pairwise concatonation of histograms and flavors.
+ *
+ * @param {Array} histogramList A subset of HISTOGRAMS.
+ * @param {Array} flavorList A subset of FLAVORS.
+ * @returns {Array} Valid TLS Histogram identifiers
+ */
+ getHistogramNames(histogramList, flavorList) {
+ let output = [];
+ for (let h of histogramList) {
+ Assert.ok(this.HISTOGRAMS.includes(h), "Histogram name valid");
+ for (let f of flavorList) {
+ Assert.ok(this.FLAVORS.includes(f), "Histogram flavor valid");
+ output.push(h.concat(f));
+ }
+ }
+ return output;
+ },
+
+ /**
+ * getHistogramNames but mapped to Histogram objects.
+ */
+ getHistograms(histogramList, flavorList) {
+ return this.getHistogramNames(histogramList, flavorList).map(x =>
+ Services.telemetry.getHistogramById(x)
+ );
+ },
+
+ /**
+ * Clears TLS Handshake Histograms.
+ */
+ resetHistograms() {
+ let allHistograms = this.getHistograms(this.HISTOGRAMS, this.FLAVORS);
+ for (let h of allHistograms) {
+ h.clear();
+ }
+ },
+
+ /**
+ * Checks that all TLS Handshake Histograms of a particular flavor have
+ * exactly resultCount entries for the resultCode and no other entries.
+ *
+ * @param {Array} flavors An array of strings corresponding to which types
+ * of histograms should have entries. See
+ * HandshakeTelemetryHelpers.FLAVORS.
+ * @param {number} resultCode The expected result code, see sslerr.h. 0 is success, all others are errors.
+ * @param {number} resultCount The number of handshake results expected.
+ */
+ checkEntry(flavors, resultCode, resultCount) {
+ Assert.ok(
+ !mozinfo.socketprocess_networking,
+ "Histograms don't populate on network process"
+ );
+ // SSL_HANDSHAKE_RESULT_{FLAVOR}
+ for (let h of this.getHistograms(["SSL_HANDSHAKE_RESULT"], flavors)) {
+ TelemetryTestUtils.assertHistogram(h, resultCode, resultCount);
+ }
+
+ // SSL_TIME_UNTIL_READY_{FLAVOR} should only contain values if we expected success.
+ if (resultCode === 0) {
+ for (let h of this.getHistograms(["SSL_TIME_UNTIL_READY"], flavors)) {
+ Assert.ok(
+ this.countHistogramEntries(h) === resultCount,
+ "Timing entry count correct"
+ );
+ }
+ } else {
+ for (let h of this.getHistograms(["SSL_TIME_UNTIL_READY"], flavors)) {
+ Assert.ok(
+ this.countHistogramEntries(h) === 0,
+ "No timing entries expected"
+ );
+ }
+ }
+ },
+
+ checkSuccess(flavors, resultCount = 1) {
+ this.checkEntry(flavors, 0, resultCount);
+ },
+
+ checkEmpty(flavors) {
+ for (let h of this.getHistogramNames(this.HISTOGRAMS, flavors)) {
+ let hObj = Services.telemetry.getHistogramById(h);
+ Assert.ok(
+ this.countHistogramEntries(hObj) === 0,
+ `No entries expected in ${h.name}. Contents: ${JSON.stringify(
+ hObj.snapshot()
+ )}`
+ );
+ }
+ },
+};