1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 const { TelemetryTestUtils } = ChromeUtils.import(
9 "resource://testing-common/TelemetryTestUtils.jsm"
12 var HandshakeTelemetryHelpers = {
13 HISTOGRAMS: ["SSL_HANDSHAKE_RESULT", "SSL_TIME_UNTIL_READY"],
14 FLAVORS: ["", "_FIRST_TRY", "_CONSERVATIVE", "_ECH", "_ECH_GREASE"],
17 * Prints the Histogram to console.
19 * @param {*} name The identifier of the Histogram.
22 let values = Services.telemetry.getHistogramById(name).snapshot().values;
23 dump(`${name}: ${JSON.stringify(values)}\n`);
27 * Counts the number of entries in the histogram, ignoring the bucket value.
28 * e.g. {0: 1, 1: 2, 3: 3} has 6 entries.
30 * @param {Object} histObject The histogram to count the entries of.
31 * @returns The count of the number of entries in the histogram.
33 countHistogramEntries(histObject) {
35 !mozinfo.socketprocess_networking,
36 "Histograms don't populate on network process"
39 let m = histObject.snapshot().values;
47 * Assert that the histogram index is the right value. It expects that
48 * other indexes are all zero.
50 * @param {Object} histogram The histogram to check.
51 * @param {Number} index The index to check against the expected value.
52 * @param {Number} expected The expected value of the index.
54 assertHistogramMap(histogram, expectedEntries) {
56 !mozinfo.socketprocess_networking,
57 "Histograms don't populate on network process"
59 let snapshot = JSON.parse(JSON.stringify(histogram.snapshot()));
60 for (let [Tk, Tv] of expectedEntries.entries()) {
62 for (let [i, val] of Object.entries(snapshot.values)) {
68 `expected counts should match for ${histogram.name()} at index ${i}`
70 snapshot.values[i] = 0; // Reset the value
75 `Should have found an entry for ${histogram.name()} at index ${Tk}`
78 for (let k in snapshot.values) {
82 `Should NOT have found an entry for ${histogram.name()} at index ${k} of value ${
90 * Generates the pairwise concatonation of histograms and flavors.
92 * @param {Array} histogramList A subset of HISTOGRAMS.
93 * @param {Array} flavorList A subset of FLAVORS.
94 * @returns {Array} Valid TLS Histogram identifiers
96 getHistogramNames(histogramList, flavorList) {
98 for (let h of histogramList) {
99 Assert.ok(this.HISTOGRAMS.includes(h), "Histogram name valid");
100 for (let f of flavorList) {
101 Assert.ok(this.FLAVORS.includes(f), "Histogram flavor valid");
102 output.push(h.concat(f));
109 * getHistogramNames but mapped to Histogram objects.
111 getHistograms(histogramList, flavorList) {
112 return this.getHistogramNames(histogramList, flavorList).map(x =>
113 Services.telemetry.getHistogramById(x)
118 * Clears TLS Handshake Histograms.
121 let allHistograms = this.getHistograms(this.HISTOGRAMS, this.FLAVORS);
122 for (let h of allHistograms) {
128 * Checks that all TLS Handshake Histograms of a particular flavor have
129 * exactly resultCount entries for the resultCode and no other entries.
131 * @param {Array} flavors An array of strings corresponding to which types
132 * of histograms should have entries. See
133 * HandshakeTelemetryHelpers.FLAVORS.
134 * @param {number} resultCode The expected result code, see sslerr.h. 0 is success, all others are errors.
135 * @param {number} resultCount The number of handshake results expected.
137 checkEntry(flavors, resultCode, resultCount) {
139 !mozinfo.socketprocess_networking,
140 "Histograms don't populate on network process"
142 // SSL_HANDSHAKE_RESULT_{FLAVOR}
143 for (let h of this.getHistograms(["SSL_HANDSHAKE_RESULT"], flavors)) {
144 TelemetryTestUtils.assertHistogram(h, resultCode, resultCount);
147 // SSL_TIME_UNTIL_READY_{FLAVOR} should only contain values if we expected success.
148 if (resultCode === 0) {
149 for (let h of this.getHistograms(["SSL_TIME_UNTIL_READY"], flavors)) {
151 this.countHistogramEntries(h) === resultCount,
152 "Timing entry count correct"
156 for (let h of this.getHistograms(["SSL_TIME_UNTIL_READY"], flavors)) {
158 this.countHistogramEntries(h) === 0,
159 "No timing entries expected"
165 checkSuccess(flavors, resultCount = 1) {
166 this.checkEntry(flavors, 0, resultCount);
169 checkEmpty(flavors) {
170 for (let h of this.getHistogramNames(this.HISTOGRAMS, flavors)) {
171 let hObj = Services.telemetry.getHistogramById(h);
173 this.countHistogramEntries(hObj) === 0,
174 `No entries expected in ${h.name}. Contents: ${JSON.stringify(