Bug 1796551 [wpt PR 36570] - WebKit export of https://bugs.webkit.org/show_bug.cgi...
[gecko.git] / netwerk / test / unit / head_telemetry.js
blob1814d615f7a67cb9d4770e414fdc590522258608
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/.
4  */
6 "use strict";
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"],
16   /**
17    * Prints the Histogram to console.
18    *
19    * @param {*} name The identifier of the Histogram.
20    */
21   dumpHistogram(name) {
22     let values = Services.telemetry.getHistogramById(name).snapshot().values;
23     dump(`${name}: ${JSON.stringify(values)}\n`);
24   },
26   /**
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.
29    *
30    * @param {Object} histObject The histogram to count the entries of.
31    * @returns The count of the number of entries in the histogram.
32    */
33   countHistogramEntries(histObject) {
34     Assert.ok(
35       !mozinfo.socketprocess_networking,
36       "Histograms don't populate on network process"
37     );
38     let count = 0;
39     let m = histObject.snapshot().values;
40     for (let k in m) {
41       count += m[k];
42     }
43     return count;
44   },
46   /**
47    * Assert that the histogram index is the right value. It expects that
48    * other indexes are all zero.
49    *
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.
53    */
54   assertHistogramMap(histogram, expectedEntries) {
55     Assert.ok(
56       !mozinfo.socketprocess_networking,
57       "Histograms don't populate on network process"
58     );
59     let snapshot = JSON.parse(JSON.stringify(histogram.snapshot()));
60     for (let [Tk, Tv] of expectedEntries.entries()) {
61       let found = false;
62       for (let [i, val] of Object.entries(snapshot.values)) {
63         if (i == Tk) {
64           found = true;
65           Assert.equal(
66             val,
67             Tv,
68             `expected counts should match for ${histogram.name()} at index ${i}`
69           );
70           snapshot.values[i] = 0; // Reset the value
71         }
72       }
73       Assert.ok(
74         found,
75         `Should have found an entry for ${histogram.name()} at index ${Tk}`
76       );
77     }
78     for (let k in snapshot.values) {
79       Assert.equal(
80         snapshot.values[k],
81         0,
82         `Should NOT have found an entry for ${histogram.name()} at index ${k} of value ${
83           snapshot.values[k]
84         }`
85       );
86     }
87   },
89   /**
90    * Generates the pairwise concatonation of histograms and flavors.
91    *
92    * @param {Array} histogramList A subset of HISTOGRAMS.
93    * @param {Array} flavorList  A subset of FLAVORS.
94    * @returns {Array} Valid TLS Histogram identifiers
95    */
96   getHistogramNames(histogramList, flavorList) {
97     let output = [];
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));
103       }
104     }
105     return output;
106   },
108   /**
109    * getHistogramNames but mapped to Histogram objects.
110    */
111   getHistograms(histogramList, flavorList) {
112     return this.getHistogramNames(histogramList, flavorList).map(x =>
113       Services.telemetry.getHistogramById(x)
114     );
115   },
117   /**
118    * Clears TLS Handshake Histograms.
119    */
120   resetHistograms() {
121     let allHistograms = this.getHistograms(this.HISTOGRAMS, this.FLAVORS);
122     for (let h of allHistograms) {
123       h.clear();
124     }
125   },
127   /**
128    * Checks that all TLS Handshake Histograms of a particular flavor have
129    * exactly resultCount entries for the resultCode and no other entries.
130    *
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.
136    */
137   checkEntry(flavors, resultCode, resultCount) {
138     Assert.ok(
139       !mozinfo.socketprocess_networking,
140       "Histograms don't populate on network process"
141     );
142     // SSL_HANDSHAKE_RESULT_{FLAVOR}
143     for (let h of this.getHistograms(["SSL_HANDSHAKE_RESULT"], flavors)) {
144       TelemetryTestUtils.assertHistogram(h, resultCode, resultCount);
145     }
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)) {
150         Assert.ok(
151           this.countHistogramEntries(h) === resultCount,
152           "Timing entry count correct"
153         );
154       }
155     } else {
156       for (let h of this.getHistograms(["SSL_TIME_UNTIL_READY"], flavors)) {
157         Assert.ok(
158           this.countHistogramEntries(h) === 0,
159           "No timing entries expected"
160         );
161       }
162     }
163   },
165   checkSuccess(flavors, resultCount = 1) {
166     this.checkEntry(flavors, 0, resultCount);
167   },
169   checkEmpty(flavors) {
170     for (let h of this.getHistogramNames(this.HISTOGRAMS, flavors)) {
171       let hObj = Services.telemetry.getHistogramById(h);
172       Assert.ok(
173         this.countHistogramEntries(hObj) === 0,
174         `No entries expected in ${h.name}. Contents: ${JSON.stringify(
175           hObj.snapshot()
176         )}`
177       );
178     }
179   },