diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/test/unit/test_bug1355539_http1.js | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_bug1355539_http1.js b/netwerk/test/unit/test_bug1355539_http1.js new file mode 100644 index 0000000000..7203179cd1 --- /dev/null +++ b/netwerk/test/unit/test_bug1355539_http1.js @@ -0,0 +1,204 @@ +// test bug 1355539. +// +// Summary: +// Transactions in one pending queue are splited into two groups: +// [(Blocking Group)|(Non Blocking Group)] +// In each group, the transactions are ordered by its priority. +// This test will check if the transaction's order in pending queue is correct. +// +// Test step: +// 1. Create 6 dummy http requests. Server would not process responses until get +// all 6 requests. +// 2. Once server receive 6 dummy requests, create another 6 http requests with the +// defined priority and class flag in |transactionQueue|. +// 3. Server starts to process the 6 dummy http requests, so the client can start to +// process the pending queue. Server will queue those http requests and put them in +// |responseQueue|. +// 4. When the server receive all 6 requests, check if the order in |responseQueue| is +// equal to |transactionQueue| by comparing the value of X-ID. + +"use strict"; + +const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js"); + +var server = new HttpServer(); +server.start(-1); +var baseURL = "http://localhost:" + server.identity.primaryPort + "/"; +var maxConnections = 0; +var debug = false; +var dummyResponseQueue = []; +var responseQueue = []; + +function log(msg) { + if (!debug) { + return; + } + + if (msg) { + dump("TEST INFO | " + msg + "\n"); + } +} + +function make_channel(url) { + var request = NetUtil.newChannel({ + uri: url, + loadUsingSystemPrincipal: true, + }); + request.QueryInterface(Ci.nsIHttpChannel); + return request; +} + +function serverStopListener() { + server.stop(); +} + +function createHttpRequest(requestId, priority, isBlocking, callback) { + let uri = baseURL; + var chan = make_channel(uri); + 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.asyncOpen(listner); + log("Create http request id=" + requestId); +} + +function setup_dummyHttpRequests(callback) { + log("setup_dummyHttpRequests"); + for (var i = 0; i < maxConnections; i++) { + 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, + }, + { + requestId: 104, + priority: Ci.nsISupportsPriority.PRIORITY_HIGH, + isBlocking: false, + }, + { + requestId: 105, + priority: Ci.nsISupportsPriority.PRIORITY_NORMAL, + isBlocking: false, + }, + { + requestId: 106, + priority: Ci.nsISupportsPriority.PRIORITY_LOW, + isBlocking: false, + }, +]; + +function setup_HttpRequests() { + log("setup_HttpRequests"); + // Create channels in reverse order + for (var i = transactionQueue.length - 1; i > -1; ) { + var e = transactionQueue[i]; + createHttpRequest(e.requestId, e.priority, e.isBlocking); + do_test_pending(); + --i; + } +} + +function check_response_id(responses) { + for (var i = 0; i < responses.length; i++) { + var id = responses[i].getHeader("X-ID"); + Assert.equal(id, transactionQueue[i].requestId); + } +} + +function HttpResponseListener(id, onStopCallback) { + this.id = id; + this.stopCallback = onStopCallback; +} + +HttpResponseListener.prototype = { + onStartRequest(request) {}, + + onDataAvailable(request, stream, off, cnt) {}, + + onStopRequest(request, status) { + log("STOP id=" + this.id); + do_test_finished(); + if (this.stopCallback) { + this.stopCallback(); + } + }, +}; + +function setup_http_server() { + log("setup_http_server"); + maxConnections = Services.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); + + if (!allDummyHttpRequestReceived) { + dummyResponseQueue.push(response); + } else { + responseQueue.push(response); + } + + if (dummyResponseQueue.length == maxConnections) { + log("received all dummy http requets"); + allDummyHttpRequestReceived = true; + setup_HttpRequests(); + processDummyResponse(); + } else if (responseQueue.length == maxConnections) { + log("received all http requets"); + check_response_id(responseQueue); + processResponses(); + } + }); + + registerCleanupFunction(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(processDummyResponse); +} |