tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_http3_perf.js (6690B)


      1 "use strict";
      2 
      3 // This test is run as part of the perf tests which require the metadata.
      4 /* exported perfMetadata */
      5 var perfMetadata = {
      6  owner: "Network Team",
      7  name: "http3 raw",
      8  description:
      9    "XPCShell tests that verifies the lib integration against a local server",
     10  options: {
     11    default: {
     12      perfherder: true,
     13      perfherder_metrics: [
     14        {
     15          name: "speed",
     16          unit: "bps",
     17        },
     18      ],
     19      xpcshell_cycles: 13,
     20      verbose: true,
     21      try_platform: ["linux", "mac"],
     22    },
     23  },
     24  tags: ["network", "http3", "quic"],
     25 };
     26 
     27 var performance = performance || {};
     28 performance.now = (function () {
     29  return (
     30    performance.now ||
     31    performance.mozNow ||
     32    performance.msNow ||
     33    performance.oNow ||
     34    performance.webkitNow ||
     35    Date.now
     36  );
     37 })();
     38 
     39 let h3Route;
     40 let httpsOrigin;
     41 let h3AltSvc;
     42 
     43 let prefs;
     44 
     45 let tests = [
     46  // This test must be the first because it setsup alt-svc connection, that
     47  // other tests use.
     48  test_https_alt_svc,
     49  test_download,
     50  testsDone,
     51 ];
     52 
     53 let current_test = 0;
     54 
     55 function run_next_test() {
     56  if (current_test < tests.length) {
     57    dump("starting test number " + current_test + "\n");
     58    tests[current_test]();
     59    current_test++;
     60  }
     61 }
     62 
     63 // eslint-disable-next-line no-unused-vars
     64 function run_test() {
     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;
     72 
     73  h3Route = "foo.example.com:" + h3Port;
     74  do_get_profile();
     75  prefs = Services.prefs;
     76 
     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
     80  // following pref:
     81  prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true);
     82 
     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
     85  // signing cert.
     86  let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
     87    Ci.nsIX509CertDB
     88  );
     89  addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
     90  httpsOrigin = "https://foo.example.com:" + h2Port + "/";
     91 
     92  run_next_test();
     93 }
     94 
     95 function makeChan(uri) {
     96  let chan = NetUtil.newChannel({
     97    uri,
     98    loadUsingSystemPrincipal: true,
     99  }).QueryInterface(Ci.nsIHttpChannel);
    100  chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
    101  return chan;
    102 }
    103 
    104 let Http3CheckListener = function () {};
    105 
    106 Http3CheckListener.prototype = {
    107  onDataAvailableFired: false,
    108  expectedRoute: "",
    109 
    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);
    114  },
    115 
    116  onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
    117    this.onDataAvailableFired = true;
    118    read_stream(stream, cnt);
    119  },
    120 
    121  onStopRequest: function testOnStopRequest(request, status) {
    122    dump("status is " + status + "\n");
    123    // Assert.equal(status, Cr.NS_OK);
    124    let routed = "NA";
    125    try {
    126      routed = request.getRequestHeader("Alt-Used");
    127    } catch (e) {}
    128    dump("routed is " + routed + "\n");
    129 
    130    Assert.equal(routed, this.expectedRoute);
    131 
    132    let httpVersion = "";
    133    try {
    134      httpVersion = request.protocolVersion;
    135    } catch (e) {}
    136    Assert.equal(httpVersion, "h3");
    137    Assert.equal(this.onDataAvailableFired, true);
    138  },
    139 };
    140 
    141 let WaitForHttp3Listener = function () {};
    142 
    143 WaitForHttp3Listener.prototype = new Http3CheckListener();
    144 
    145 WaitForHttp3Listener.prototype.uri = "";
    146 WaitForHttp3Listener.prototype.h3AltSvc = "";
    147 
    148 WaitForHttp3Listener.prototype.onStopRequest = function testOnStopRequest(
    149  request,
    150  status
    151 ) {
    152  Assert.equal(status, Cr.NS_OK);
    153  let routed = "NA";
    154  try {
    155    routed = request.getRequestHeader("Alt-Used");
    156  } catch (e) {}
    157  dump("routed is " + routed + "\n");
    158 
    159  if (routed == this.expectedRoute) {
    160    Assert.equal(routed, this.expectedRoute); // always true, but a useful log
    161 
    162    let httpVersion = "";
    163    try {
    164      httpVersion = request.protocolVersion;
    165    } catch (e) {}
    166    Assert.equal(httpVersion, "h3");
    167    run_next_test();
    168  } else {
    169    dump("poll later for alt svc mapping\n");
    170    do_test_pending();
    171    do_timeout(500, () => {
    172      doTest(this.uri, this.expectedRoute, this.h3AltSvc);
    173    });
    174  }
    175 
    176  do_test_finished();
    177 };
    178 
    179 function doTest(uri, expectedRoute, altSvc) {
    180  let chan = makeChan(uri);
    181  let listener = new WaitForHttp3Listener();
    182  listener.uri = uri;
    183  listener.expectedRoute = expectedRoute;
    184  listener.h3AltSvc = altSvc;
    185  chan.setRequestHeader("x-altsvc", altSvc, false);
    186  chan.asyncOpen(listener);
    187 }
    188 
    189 // Test Alt-Svc for http3.
    190 // H2 server returns alt-svc=h3=:h3port
    191 function test_https_alt_svc() {
    192  dump("test_https_alt_svc()\n");
    193 
    194  do_test_pending();
    195  doTest(httpsOrigin + "http3-test", h3Route, h3AltSvc);
    196 }
    197 
    198 let PerfHttp3Listener = function () {};
    199 
    200 PerfHttp3Listener.prototype = new Http3CheckListener();
    201 PerfHttp3Listener.prototype.amount = 0;
    202 PerfHttp3Listener.prototype.bytesRead = 0;
    203 PerfHttp3Listener.prototype.startTime = 0;
    204 
    205 PerfHttp3Listener.prototype.onStartRequest = function testOnStartRequest(
    206  request
    207 ) {
    208  this.startTime = performance.now();
    209  Http3CheckListener.prototype.onStartRequest.call(this, request);
    210 };
    211 
    212 PerfHttp3Listener.prototype.onDataAvailable = function testOnStopRequest(
    213  request,
    214  stream,
    215  off,
    216  cnt
    217 ) {
    218  this.bytesRead += cnt;
    219  Http3CheckListener.prototype.onDataAvailable.call(
    220    this,
    221    request,
    222    stream,
    223    off,
    224    cnt
    225  );
    226 };
    227 
    228 PerfHttp3Listener.prototype.onStopRequest = function testOnStopRequest(
    229  request,
    230  status
    231 ) {
    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...");
    236  } else {
    237    let speed = (this.bytesRead * 1000) / (stopTime - this.startTime);
    238    info("perfMetrics", { speed });
    239  }
    240  run_next_test();
    241  do_test_finished();
    242 };
    243 
    244 function test_download() {
    245  dump("test_download()\n");
    246 
    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);
    252  do_test_pending();
    253 }
    254 
    255 function testsDone() {
    256  prefs.clearUserPref("network.http.http3.enable");
    257  prefs.clearUserPref("network.dns.localDomains");
    258  prefs.clearUserPref("network.proxy.allow_hijacking_localhost");
    259  dump("testDone\n");
    260  do_test_pending();
    261  do_test_finished();
    262 }