diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/test/unit/test_http3_perf.js | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_http3_perf.js b/netwerk/test/unit/test_http3_perf.js new file mode 100644 index 0000000000..b330fd7e83 --- /dev/null +++ b/netwerk/test/unit/test_http3_perf.js @@ -0,0 +1,262 @@ +"use strict"; + +// This test is run as part of the perf tests which require the metadata. +/* exported perfMetadata */ +var perfMetadata = { + owner: "Network Team", + name: "http3 raw", + description: + "XPCShell tests that verifies the lib integration against a local server", + options: { + default: { + perfherder: true, + perfherder_metrics: [ + { + name: "speed", + unit: "bps", + }, + ], + xpcshell_cycles: 13, + verbose: true, + try_platform: ["linux", "mac"], + }, + }, + tags: ["network", "http3", "quic"], +}; + +var performance = performance || {}; +performance.now = (function() { + return ( + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + Date.now + ); +})(); + +let h3Route; +let httpsOrigin; +let h3AltSvc; + +let prefs; + +let tests = [ + // This test must be the first because it setsup alt-svc connection, that + // other tests use. + test_https_alt_svc, + test_download, + testsDone, +]; + +let current_test = 0; + +function run_next_test() { + if (current_test < tests.length) { + dump("starting test number " + current_test + "\n"); + tests[current_test](); + current_test++; + } +} + +// eslint-disable-next-line no-unused-vars +function run_test() { + let h2Port = Services.env.get("MOZHTTP2_PORT"); + Assert.notEqual(h2Port, null); + Assert.notEqual(h2Port, ""); + let h3Port = Services.env.get("MOZHTTP3_PORT"); + Assert.notEqual(h3Port, null); + Assert.notEqual(h3Port, ""); + h3AltSvc = ":" + h3Port; + + h3Route = "foo.example.com:" + h3Port; + do_get_profile(); + prefs = Services.prefs; + + prefs.setBoolPref("network.http.http3.enable", true); + prefs.setCharPref("network.dns.localDomains", "foo.example.com"); + // We always resolve elements of localDomains as it's hardcoded without the + // following pref: + prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); + + // The certificate for the http3server server is for foo.example.com and + // is signed by http2-ca.pem so add that cert to the trust list as a + // signing cert. + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u"); + httpsOrigin = "https://foo.example.com:" + h2Port + "/"; + + run_next_test(); +} + +function makeChan(uri) { + let chan = NetUtil.newChannel({ + uri, + loadUsingSystemPrincipal: true, + }).QueryInterface(Ci.nsIHttpChannel); + chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI; + return chan; +} + +let Http3CheckListener = function() {}; + +Http3CheckListener.prototype = { + onDataAvailableFired: false, + expectedRoute: "", + + onStartRequest: function testOnStartRequest(request) { + Assert.ok(request instanceof Ci.nsIHttpChannel); + Assert.equal(request.status, Cr.NS_OK); + Assert.equal(request.responseStatus, 200); + }, + + onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) { + this.onDataAvailableFired = true; + read_stream(stream, cnt); + }, + + onStopRequest: function testOnStopRequest(request, status) { + dump("status is " + status + "\n"); + // Assert.equal(status, Cr.NS_OK); + let routed = "NA"; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + dump("routed is " + routed + "\n"); + + Assert.equal(routed, this.expectedRoute); + + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + Assert.equal(httpVersion, "h3-29"); + Assert.equal(this.onDataAvailableFired, true); + }, +}; + +let WaitForHttp3Listener = function() {}; + +WaitForHttp3Listener.prototype = new Http3CheckListener(); + +WaitForHttp3Listener.prototype.uri = ""; +WaitForHttp3Listener.prototype.h3AltSvc = ""; + +WaitForHttp3Listener.prototype.onStopRequest = function testOnStopRequest( + request, + status +) { + Assert.equal(status, Cr.NS_OK); + let routed = "NA"; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + dump("routed is " + routed + "\n"); + + if (routed == this.expectedRoute) { + Assert.equal(routed, this.expectedRoute); // always true, but a useful log + + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + Assert.equal(httpVersion, "h3-29"); + run_next_test(); + } else { + dump("poll later for alt svc mapping\n"); + do_test_pending(); + do_timeout(500, () => { + doTest(this.uri, this.expectedRoute, this.h3AltSvc); + }); + } + + do_test_finished(); +}; + +function doTest(uri, expectedRoute, altSvc) { + let chan = makeChan(uri); + let listener = new WaitForHttp3Listener(); + listener.uri = uri; + listener.expectedRoute = expectedRoute; + listener.h3AltSvc = altSvc; + chan.setRequestHeader("x-altsvc", altSvc, false); + chan.asyncOpen(listener); +} + +// Test Alt-Svc for http3. +// H2 server returns alt-svc=h3-29=:h3port +function test_https_alt_svc() { + dump("test_https_alt_svc()\n"); + + do_test_pending(); + doTest(httpsOrigin + "http3-test", h3Route, h3AltSvc); +} + +let PerfHttp3Listener = function() {}; + +PerfHttp3Listener.prototype = new Http3CheckListener(); +PerfHttp3Listener.prototype.amount = 0; +PerfHttp3Listener.prototype.bytesRead = 0; +PerfHttp3Listener.prototype.startTime = 0; + +PerfHttp3Listener.prototype.onStartRequest = function testOnStartRequest( + request +) { + this.startTime = performance.now(); + Http3CheckListener.prototype.onStartRequest.call(this, request); +}; + +PerfHttp3Listener.prototype.onDataAvailable = function testOnStopRequest( + request, + stream, + off, + cnt +) { + this.bytesRead += cnt; + Http3CheckListener.prototype.onDataAvailable.call( + this, + request, + stream, + off, + cnt + ); +}; + +PerfHttp3Listener.prototype.onStopRequest = function testOnStopRequest( + request, + status +) { + let stopTime = performance.now(); + Http3CheckListener.prototype.onStopRequest.call(this, request, status); + if (this.bytesRead != this.amount) { + dump("Wrong number of bytes..."); + } else { + let speed = (this.bytesRead * 1000) / (stopTime - this.startTime); + info("perfMetrics", { speed }); + } + run_next_test(); + do_test_finished(); +}; + +function test_download() { + dump("test_download()\n"); + + let listener = new PerfHttp3Listener(); + listener.expectedRoute = h3Route; + listener.amount = 1024 * 1024; + let chan = makeChan(httpsOrigin + listener.amount.toString()); + chan.asyncOpen(listener); + do_test_pending(); +} + +function testsDone() { + prefs.clearUserPref("network.http.http3.enable"); + prefs.clearUserPref("network.dns.localDomains"); + prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); + dump("testDone\n"); + do_test_pending(); + do_test_finished(); +} |