// test bug 1312782. // // Summary: // Assume we have 6 http requests in queue, 4 are from the focused window and // the other 2 are from the non-focused window. We want to test that the server // should receive 4 requests from the focused window first and then receive the // rest 2 requests. // // 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 4 http requests with the focused // window id and 2 requests with non-focused window id. Note that the requets's // id is a serial number starting from the focused window id. // 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 again and wait // until get all 6 requests. // 4. When the server receive all 6 requests, starts to check that the request ids of // the first 4 requests in the queue should be all less than focused window id // plus 4. Also, the request ids of the rest requests should be less than non-focused // window id + 2. "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; const FOCUSED_WINDOW_ID = 123; var NON_FOCUSED_WINDOW_ID; var FOCUSED_WINDOW_REQUEST_COUNT; var NON_FOCUSED_WINDOW_REQUEST_COUNT; 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(browsingContextId, requestId) { let uri = baseURL; var chan = make_channel(uri); chan.topBrowsingContextId = browsingContextId; var listner = new HttpResponseListener(requestId); chan.setRequestHeader("X-ID", requestId, false); chan.setRequestHeader("Cache-control", "no-store", false); chan.asyncOpen(listner); log("Create http request id=" + requestId); } function setup_dummyHttpRequests() { log("setup_dummyHttpRequests"); for (var i = 0; i < maxConnections; i++) { createHttpRequest(0, i); do_test_pending(); } } function setup_focusedWindowHttpRequests() { log("setup_focusedWindowHttpRequests"); for (var i = 0; i < FOCUSED_WINDOW_REQUEST_COUNT; i++) { createHttpRequest(FOCUSED_WINDOW_ID, FOCUSED_WINDOW_ID + i); do_test_pending(); } } function setup_nonFocusedWindowHttpRequests() { log("setup_nonFocusedWindowHttpRequests"); for (var i = 0; i < NON_FOCUSED_WINDOW_REQUEST_COUNT; i++) { createHttpRequest(NON_FOCUSED_WINDOW_ID, NON_FOCUSED_WINDOW_ID + i); do_test_pending(); } } function HttpResponseListener(id) { this.id = id; } HttpResponseListener.prototype = { onStartRequest(request) {}, onDataAvailable(request, stream, off, cnt) {}, onStopRequest(request, status) { log("STOP id=" + this.id); do_test_finished(); }, }; function check_response_id(responses, maxWindowId) { for (var i = 0; i < responses.length; i++) { var id = responses[i].getHeader("X-ID"); log("response id=" + id + " maxWindowId=" + maxWindowId); Assert.ok(id < maxWindowId); } } var responseQueue = []; function setup_http_server() { log("setup_http_server"); maxConnections = Services.prefs.getIntPref( "network.http.max-persistent-connections-per-server" ); FOCUSED_WINDOW_REQUEST_COUNT = Math.floor(maxConnections * 0.8); NON_FOCUSED_WINDOW_REQUEST_COUNT = maxConnections - FOCUSED_WINDOW_REQUEST_COUNT; NON_FOCUSED_WINDOW_ID = FOCUSED_WINDOW_ID + FOCUSED_WINDOW_REQUEST_COUNT; 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 ) { log("received all dummy http requets"); allDummyHttpRequestReceived = true; setup_nonFocusedWindowHttpRequests(); setup_focusedWindowHttpRequests(); processResponses(); } else if (responseQueue.length == maxConnections) { var focusedWindowResponses = responseQueue.slice( 0, FOCUSED_WINDOW_REQUEST_COUNT ); var nonFocusedWindowResponses = responseQueue.slice( FOCUSED_WINDOW_REQUEST_COUNT, responseQueue.length ); check_response_id( focusedWindowResponses, FOCUSED_WINDOW_ID + FOCUSED_WINDOW_REQUEST_COUNT ); check_response_id( nonFocusedWindowResponses, NON_FOCUSED_WINDOW_ID + NON_FOCUSED_WINDOW_REQUEST_COUNT ); processResponses(); } }); registerCleanupFunction(function() { server.stop(serverStopListener); }); } function processResponses() { while (responseQueue.length) { var resposne = responseQueue.pop(); resposne.finish(); } } function run_test() { // Make sure "network.http.active_tab_priority" is true, so we can expect to // receive http requests with focused window id before others. Services.prefs.setBoolPref("network.http.active_tab_priority", true); setup_http_server(); setup_dummyHttpRequests(); var windowIdWrapper = Cc["@mozilla.org/supports-PRUint64;1"].createInstance( Ci.nsISupportsPRUint64 ); windowIdWrapper.data = FOCUSED_WINDOW_ID; var obsvc = Services.obs; obsvc.notifyObservers(windowIdWrapper, "net:current-top-browsing-context-id"); }