Bug 958712 part 3/3 - CONTINUATION tests r=mcmanus
authorNicholas Hurley <hurley@todesschaf.org>
Fri, 30 Jan 2015 11:13:31 -0800
changeset 227036 26ad04ac4ba3fd67eb00a0be506a58c6e1c30050
parent 227035 6a529065cc9e5ddbacf78258a8adc356ae398c48
child 227037 658ba2f4d8796242b5c80f2d6e793918828a327d
push id55003
push userhurley@todesschaf.org
push dateMon, 02 Feb 2015 20:13:14 +0000
treeherdermozilla-inbound@26ad04ac4ba3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs958712
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 958712 part 3/3 - CONTINUATION tests r=mcmanus
netwerk/test/unit/test_http2.js
testing/xpcshell/moz-http2/moz-http2.js
--- a/netwerk/test/unit/test_http2.js
+++ b/netwerk/test/unit/test_http2.js
@@ -142,16 +142,73 @@ Http2PushListener.prototype.onDataAvaila
   this.isHttp2Connection = checkIsHttp2(request);
   if (ctx.originalURI.spec == "https://localhost:" + serverPort + "/push.js" ||
       ctx.originalURI.spec == "https://localhost:" + serverPort + "/push2.js") {
     do_check_eq(request.getResponseHeader("pushed"), "yes");
   }
   read_stream(stream, cnt);
 };
 
+const pushHdrTxt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+const pullHdrTxt = pushHdrTxt.split('').reverse().join('');
+
+function checkContinuedHeaders(getHeader, headerPrefix, headerText) {
+  for (var i = 0; i < 265; i++) {
+    do_check_eq(getHeader(headerPrefix + 1), headerText);
+  }
+}
+
+var Http2ContinuedHeaderListener = function() {};
+
+Http2ContinuedHeaderListener.prototype = new Http2CheckListener();
+
+Http2ContinuedHeaderListener.prototype.onStopsLeft = 2;
+
+Http2ContinuedHeaderListener.prototype.QueryInterface = function (aIID) {
+  if (aIID.equals(Ci.nsIHttpPushListener) ||
+      aIID.equals(Ci.nsIStreamListener))
+    return this;
+  throw Components.results.NS_ERROR_NO_INTERFACE;
+};
+
+Http2ContinuedHeaderListener.prototype.getInterface = function(aIID) {
+  return this.QueryInterface(aIID);
+};
+
+Http2ContinuedHeaderListener.prototype.onDataAvailable = function (request, ctx, stream, off, cnt) {
+  this.onDataAvailableFired = true;
+  this.isHttp2Connection = checkIsHttp2(request);
+  if (request.originalURI.spec == "https://localhost:" + serverPort + "/continuedheaders") {
+    // This is the original request, so the only one where we'll have continued response headers
+    checkContinuedHeaders(request.getResponseHeader, "X-Pull-Test-Header-", pullHdrTxt);
+  }
+  read_stream(stream, cnt);
+};
+
+Http2ContinuedHeaderListener.prototype.onStopRequest = function (request, ctx, status) {
+  do_check_true(this.onStartRequestFired);
+  do_check_true(Components.isSuccessCode(status));
+  do_check_true(this.onDataAvailableFired);
+  do_check_true(this.isHttp2Connection);
+
+  --this.onStopsLeft;
+  if (this.onStopsLeft === 0) {
+    run_next_test();
+    do_test_finished();
+  }
+};
+
+Http2ContinuedHeaderListener.prototype.onPush = function(associatedChannel, pushChannel) {
+  do_check_eq(associatedChannel.originalURI.spec, "https://localhost:" + serverPort + "/continuedheaders");
+  do_check_eq(pushChannel.getRequestHeader("x-pushed-request"), "true");
+  checkContinuedHeaders(pushChannel.getRequestHeader, "X-Push-Test-Header-", pushHdrTxt);
+
+  pushChannel.asyncOpen(this, pushChannel);
+};
+
 // Does the appropriate checks for a large GET response
 var Http2BigListener = function() {};
 
 Http2BigListener.prototype = new Http2CheckListener();
 Http2BigListener.prototype.buffer = "";
 
 Http2BigListener.prototype.onDataAvailable = function(request, ctx, stream, off, cnt) {
   this.onDataAvailableFired = true;
@@ -639,16 +696,24 @@ function test_http2_h11required_session(
 }
 
 function test_http2_retry_rst() {
   var chan = makeChan("https://localhost:" + serverPort + "/rstonce");
   var listener = new Http2CheckListener();
   chan.asyncOpen(listener, null);
 }
 
+function test_http2_continuations() {
+  var chan = makeChan("https://localhost:" + serverPort + "/continuedheaders");
+  chan.loadGroup = loadGroup;
+  var listener = new Http2ContinuedHeaderListener();
+  chan.notificationCallbacks = listener;
+  chan.asyncOpen(listener, chan);
+}
+
 function test_complete() {
   resetPrefs();
   do_test_finished();
   do_timeout(0,run_next_test);
 }
 
 // hack - the header test resets the multiplex object on the server,
 // so make sure header is always run before the multiplex test.
@@ -675,16 +740,17 @@ var tests = [ test_http2_post_big
             , test_http2_huge_suspended
             , test_http2_post
             , test_http2_pushapi_1
             // These next two must always come in this order
             , test_http2_h11required_stream
             , test_http2_h11required_session
             , test_http2_retry_rst
             , test_http2_wrongsuite
+            , test_http2_continuations
 
             // cleanup
             , test_complete
             ];
 var current_test = 0;
 
 function run_next_test() {
   if (current_test < tests.length) {
--- a/testing/xpcshell/moz-http2/moz-http2.js
+++ b/testing/xpcshell/moz-http2/moz-http2.js
@@ -345,16 +345,38 @@ function handleRequest(req, res) {
     if (req.httpVersionMajor != 2) {
       res.setHeader('Connection', 'close');
     }
     res.writeHead(200);
     res.end("It's all good.");
     return;
   }
 
+  else if (u.pathname === "/continuedheaders") {
+    var pushRequestHeaders = {'x-pushed-request': 'true'};
+    var pushResponseHeaders = {'content-type': 'text/plain',
+                               'content-length': '2',
+                               'X-Connection-Http2': 'yes'};
+    var pushHdrTxt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+    var pullHdrTxt = pushHdrTxt.split('').reverse().join('');
+    for (var i = 0; i < 265; i++) {
+      pushRequestHeaders['X-Push-Test-Header-' + i] = pushHdrTxt;
+      res.setHeader('X-Pull-Test-Header-' + i, pullHdrTxt);
+    }
+    push = res.push({
+      hostname: 'localhost:' + serverPort,
+      port: serverPort,
+      path: '/continuedheaders/push',
+      method: 'GET',
+      headers: pushRequestHeaders
+    });
+    push.writeHead(200, pushResponseHeaders);
+    push.end("ok");
+  }
+
   res.setHeader('Content-Type', 'text/html');
   if (req.httpVersionMajor != 2) {
     res.setHeader('Connection', 'close');
   }
   res.writeHead(200);
   res.end(content);
 }