Bug 1425512 - Make the sequence of requests more determinate, r=mayhemer
authorKershaw Chang <kechang@mozilla.com>
Wed, 20 Dec 2017 00:08:00 +0200
changeset 448764 03e5401d560c1a9864bcdff7c4e835fa28575afc
parent 448763 e9cfe039a796e2963a6d3e7d2a161b02cdbadcac
child 448765 6cff7451155d9d1bcdcfad795bb79ec8b42a6d06
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1425512
milestone59.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 1425512 - Make the sequence of requests more determinate, r=mayhemer This test is aimed to check whether the order that http server gets requests is the same as the order in the client's pending queue. However, even if the transactions are dispatched according to the order in pending queue, it doesn't mean the server can get the request in the same order. This is because the transaction is really dispatched to a connection when nsHalfOpenSocket::OnOutputStreamReady() is called. The order may not be always the same as the pending queue. Hence, this patch processes the dummy http request once at the time when the previous request's OnStopRequest() is called. This can force the client dispatch only one transaction at the time and make the behavior of this test more predictable.
netwerk/test/unit/test_bug1355539_http1.js
--- a/netwerk/test/unit/test_bug1355539_http1.js
+++ b/netwerk/test/unit/test_bug1355539_http1.js
@@ -22,16 +22,18 @@ Cu.import("resource://gre/modules/NetUti
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var server = new HttpServer();
 server.start(-1);
 var baseURL = "http://localhost:" + server.identity.primaryPort + "/";
 var maxConnections = 0;
 var debug = false;
+var dummyResponseQueue = new Array();
+var responseQueue = new Array();
 
 function log(msg) {
   if (!debug) {
     return;
   }
 
   if (msg) {
     dump("TEST INFO | " + msg + "\n");
@@ -43,35 +45,35 @@ function make_channel(url) {
   request.QueryInterface(Ci.nsIHttpChannel);
   return request;
 }
 
 function serverStopListener() {
   server.stop();
 }
 
-function createHttpRequest(requestId, priority, isBlocking) {
+function createHttpRequest(requestId, priority, isBlocking, callback) {
   let uri = baseURL;
   var chan = make_channel(uri);
-  var listner = new HttpResponseListener(requestId);
+  var listner = new HttpResponseListener(requestId, callback);
   chan.setRequestHeader("X-ID", requestId, false);
   chan.setRequestHeader("Cache-control", "no-store", false);
   chan.QueryInterface(Ci.nsISupportsPriority).priority = priority;
   if (isBlocking) {
     var cos = chan.QueryInterface(Ci.nsIClassOfService);
     cos.addClassFlags(Ci.nsIClassOfService.Leader);
   }
   chan.asyncOpen2(listner);
   log("Create http request id=" + requestId);
 }
 
-function setup_dummyHttpRequests() {
+function setup_dummyHttpRequests(callback) {
   log("setup_dummyHttpRequests");
   for (var i = 0; i < maxConnections ; i++) {
-    createHttpRequest(i, i, false);
+    createHttpRequest(i, i, false, callback);
     do_test_pending();
   }
 }
 
 var transactionQueue = [
   {requestId: 101, priority: Ci.nsISupportsPriority.PRIORITY_HIGH, isBlocking: true},
   {requestId: 102, priority: Ci.nsISupportsPriority.PRIORITY_NORMAL, isBlocking: true},
   {requestId: 103, priority: Ci.nsISupportsPriority.PRIORITY_LOW, isBlocking: true},
@@ -94,75 +96,91 @@ function setup_HttpRequests() {
 function check_response_id(responses)
 {
   for (var i = 0; i < responses.length; i++) {
     var id = responses[i].getHeader("X-ID");
     do_check_eq(id, transactionQueue[i].requestId);
   }
 }
 
-function HttpResponseListener(id)
+function HttpResponseListener(id, onStopCallback)
 {
   this.id = id
+  this.stopCallback = onStopCallback;
 };
 
 HttpResponseListener.prototype =
 {
   onStartRequest: function (request, ctx) {
   },
 
   onDataAvailable: function (request, ctx, stream, off, cnt) {
   },
 
   onStopRequest: function (request, ctx, status) {
     log("STOP id=" + this.id);
     do_test_finished();
+    if (this.stopCallback) {
+      this.stopCallback();
+    }
   }
 };
 
-var responseQueue = new Array();
 function setup_http_server()
 {
   log("setup_http_server");
   var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
   maxConnections = prefs.getIntPref("network.http.max-persistent-connections-per-server");
 
   var allDummyHttpRequestReceived = false;
   // Start server; will be stopped at test cleanup time.
   server.registerPathHandler('/', function(metadata, response)
   {
     var id = metadata.getHeader("X-ID");
     log("Server recived the response id=" + id);
 
     response.processAsync();
     response.setHeader("X-ID", id);
-    responseQueue.push(response);
 
-    if (responseQueue.length == maxConnections && !allDummyHttpRequestReceived) {
+    if (!allDummyHttpRequestReceived) {
+      dummyResponseQueue.push(response);
+    } else {
+      responseQueue.push(response);
+    }
+
+    if (dummyResponseQueue.length == maxConnections) {
       log("received all dummy http requets");
       allDummyHttpRequestReceived = true;
       setup_HttpRequests();
-      processResponses();
+      processDummyResponse();
     } else if (responseQueue.length == maxConnections) {
       log("received all http requets");
       check_response_id(responseQueue);
       processResponses();
     }
 
   });
 
   do_register_cleanup(function() {
     server.stop(serverStopListener);
   });
 
 }
 
+function processDummyResponse() {
+  if (!dummyResponseQueue.length) {
+    return;
+  }
+  var resposne = dummyResponseQueue.pop();
+  resposne.finish();
+}
+
 function processResponses() {
   while (responseQueue.length) {
     var resposne = responseQueue.pop();
     resposne.finish();
   }
 }
 
 function run_test() {
   setup_http_server();
-  setup_dummyHttpRequests();
+  setup_dummyHttpRequests(processDummyResponse);
 }