3 // This test is run as part of the perf tests which require the metadata.
4 /* exported perfMetadata */
9 "XPCShell tests that verifies the lib integration against a local server",
21 try_platform: ["linux", "mac"],
24 tags: ["network", "http3", "quic"],
27 var performance = performance || {};
28 performance.now = (function () {
34 performance.webkitNow ||
46 // This test must be the first because it setsup alt-svc connection, that
55 function run_next_test() {
56 if (current_test < tests.length) {
57 dump("starting test number " + current_test + "\n");
58 tests[current_test]();
63 // eslint-disable-next-line no-unused-vars
65 let h2Port = Services.env.get("MOZHTTP2_PORT");
66 Assert.notEqual(h2Port, null);
67 Assert.notEqual(h2Port, "");
68 let h3Port = Services.env.get("MOZHTTP3_PORT");
69 Assert.notEqual(h3Port, null);
70 Assert.notEqual(h3Port, "");
71 h3AltSvc = ":" + h3Port;
73 h3Route = "foo.example.com:" + h3Port;
75 prefs = Services.prefs;
77 prefs.setBoolPref("network.http.http3.enable", true);
78 prefs.setCharPref("network.dns.localDomains", "foo.example.com");
79 // We always resolve elements of localDomains as it's hardcoded without the
81 prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true);
83 // The certificate for the http3server server is for foo.example.com and
84 // is signed by http2-ca.pem so add that cert to the trust list as a
86 let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
89 addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
90 httpsOrigin = "https://foo.example.com:" + h2Port + "/";
95 function makeChan(uri) {
96 let chan = NetUtil.newChannel({
98 loadUsingSystemPrincipal: true,
99 }).QueryInterface(Ci.nsIHttpChannel);
100 chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
104 let Http3CheckListener = function () {};
106 Http3CheckListener.prototype = {
107 onDataAvailableFired: false,
110 onStartRequest: function testOnStartRequest(request) {
111 Assert.ok(request instanceof Ci.nsIHttpChannel);
112 Assert.equal(request.status, Cr.NS_OK);
113 Assert.equal(request.responseStatus, 200);
116 onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
117 this.onDataAvailableFired = true;
118 read_stream(stream, cnt);
121 onStopRequest: function testOnStopRequest(request, status) {
122 dump("status is " + status + "\n");
123 // Assert.equal(status, Cr.NS_OK);
126 routed = request.getRequestHeader("Alt-Used");
128 dump("routed is " + routed + "\n");
130 Assert.equal(routed, this.expectedRoute);
132 let httpVersion = "";
134 httpVersion = request.protocolVersion;
136 Assert.equal(httpVersion, "h3-29");
137 Assert.equal(this.onDataAvailableFired, true);
141 let WaitForHttp3Listener = function () {};
143 WaitForHttp3Listener.prototype = new Http3CheckListener();
145 WaitForHttp3Listener.prototype.uri = "";
146 WaitForHttp3Listener.prototype.h3AltSvc = "";
148 WaitForHttp3Listener.prototype.onStopRequest = function testOnStopRequest(
152 Assert.equal(status, Cr.NS_OK);
155 routed = request.getRequestHeader("Alt-Used");
157 dump("routed is " + routed + "\n");
159 if (routed == this.expectedRoute) {
160 Assert.equal(routed, this.expectedRoute); // always true, but a useful log
162 let httpVersion = "";
164 httpVersion = request.protocolVersion;
166 Assert.equal(httpVersion, "h3-29");
169 dump("poll later for alt svc mapping\n");
171 do_timeout(500, () => {
172 doTest(this.uri, this.expectedRoute, this.h3AltSvc);
179 function doTest(uri, expectedRoute, altSvc) {
180 let chan = makeChan(uri);
181 let listener = new WaitForHttp3Listener();
183 listener.expectedRoute = expectedRoute;
184 listener.h3AltSvc = altSvc;
185 chan.setRequestHeader("x-altsvc", altSvc, false);
186 chan.asyncOpen(listener);
189 // Test Alt-Svc for http3.
190 // H2 server returns alt-svc=h3-29=:h3port
191 function test_https_alt_svc() {
192 dump("test_https_alt_svc()\n");
195 doTest(httpsOrigin + "http3-test", h3Route, h3AltSvc);
198 let PerfHttp3Listener = function () {};
200 PerfHttp3Listener.prototype = new Http3CheckListener();
201 PerfHttp3Listener.prototype.amount = 0;
202 PerfHttp3Listener.prototype.bytesRead = 0;
203 PerfHttp3Listener.prototype.startTime = 0;
205 PerfHttp3Listener.prototype.onStartRequest = function testOnStartRequest(
208 this.startTime = performance.now();
209 Http3CheckListener.prototype.onStartRequest.call(this, request);
212 PerfHttp3Listener.prototype.onDataAvailable = function testOnStopRequest(
218 this.bytesRead += cnt;
219 Http3CheckListener.prototype.onDataAvailable.call(
228 PerfHttp3Listener.prototype.onStopRequest = function testOnStopRequest(
232 let stopTime = performance.now();
233 Http3CheckListener.prototype.onStopRequest.call(this, request, status);
234 if (this.bytesRead != this.amount) {
235 dump("Wrong number of bytes...");
237 let speed = (this.bytesRead * 1000) / (stopTime - this.startTime);
238 info("perfMetrics", { speed });
244 function test_download() {
245 dump("test_download()\n");
247 let listener = new PerfHttp3Listener();
248 listener.expectedRoute = h3Route;
249 listener.amount = 1024 * 1024;
250 let chan = makeChan(httpsOrigin + listener.amount.toString());
251 chan.asyncOpen(listener);
255 function testsDone() {
256 prefs.clearUserPref("network.http.http3.enable");
257 prefs.clearUserPref("network.dns.localDomains");
258 prefs.clearUserPref("network.proxy.allow_hijacking_localhost");