diff options
Diffstat (limited to 'netwerk/test/unit/head_telemetry.js')
-rw-r--r-- | netwerk/test/unit/head_telemetry.js | 171 |
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() + )}` + ); + } + }, +}; |