зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1244227
- Add an API to enable throttling. r=Honza
MozReview-Commit-ID: BirjFHVSZN7
This commit is contained in:
Родитель
e660321898
Коммит
8cfae2d757
|
@ -9,3 +9,4 @@ support-files =
|
|||
|
||||
[browser_net_har_copy_all_as_har.js]
|
||||
[browser_net_har_post_data.js]
|
||||
[browser_net_har_throttle_upload.js]
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test timing of upload when throttling.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
yield throttleUploadTest(true);
|
||||
yield throttleUploadTest(false);
|
||||
});
|
||||
|
||||
function* throttleUploadTest(actuallyThrottle) {
|
||||
let [ , debuggee, monitor ] = yield initNetMonitor(
|
||||
HAR_EXAMPLE_URL + "html_har_post-data-test-page.html");
|
||||
|
||||
info("Starting test... (actuallyThrottle = " + actuallyThrottle + ")");
|
||||
|
||||
let { NetMonitorView } = monitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
const size = 4096;
|
||||
const uploadSize = actuallyThrottle ? size / 3 : 0;
|
||||
|
||||
const request = {
|
||||
"NetworkMonitor.throttleData": {
|
||||
roundTripTimeMean: 0,
|
||||
roundTripTimeMax: 0,
|
||||
downloadBPSMean: 200000,
|
||||
downloadBPSMax: 200000,
|
||||
uploadBPSMean: uploadSize,
|
||||
uploadBPSMax: uploadSize,
|
||||
},
|
||||
};
|
||||
let client = monitor._controller.webConsoleClient;
|
||||
|
||||
info("sending throttle request");
|
||||
let deferred = promise.defer();
|
||||
client.setPreferences(request, response => {
|
||||
deferred.resolve(response);
|
||||
});
|
||||
yield deferred.promise;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
// Execute one POST request on the page and wait till its done.
|
||||
debuggee.executeTest2(size);
|
||||
yield waitForNetworkEvents(monitor, 0, 1);
|
||||
|
||||
// Copy HAR into the clipboard (asynchronous).
|
||||
let jsonString = yield RequestsMenu.copyAllAsHar();
|
||||
let har = JSON.parse(jsonString);
|
||||
|
||||
// Check out the HAR log.
|
||||
isnot(har.log, null, "The HAR log must exist");
|
||||
is(har.log.pages.length, 1, "There must be one page");
|
||||
is(har.log.entries.length, 1, "There must be one request");
|
||||
|
||||
let entry = har.log.entries[0];
|
||||
is(entry.request.postData.text, "x".repeat(size),
|
||||
"Check post data payload");
|
||||
|
||||
const wasTwoSeconds = entry.timings.send >= 2000;
|
||||
if (actuallyThrottle) {
|
||||
ok(wasTwoSeconds, "upload should have taken more than 2 seconds");
|
||||
} else {
|
||||
ok(!wasTwoSeconds, "upload should not have taken more than 2 seconds");
|
||||
}
|
||||
|
||||
// Clean up
|
||||
yield teardown(monitor);
|
||||
}
|
|
@ -27,6 +27,12 @@
|
|||
var data = "{'first': 'John', 'last': 'Doe'}";
|
||||
post(url, data);
|
||||
}
|
||||
|
||||
function executeTest2(size) {
|
||||
var url = "html_har_post-data-test-page.html";
|
||||
var data = "x".repeat(size);
|
||||
post(url, data);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ skip-if = (e10s && debug && os == 'mac') # Bug 1253037
|
|||
[browser_net_statistics-03.js]
|
||||
[browser_net_status-codes.js]
|
||||
[browser_net_streaming-response.js]
|
||||
[browser_net_throttle.js]
|
||||
[browser_net_timeline_ticks.js]
|
||||
[browser_net_timing-division.js]
|
||||
[browser_net_persistent_logs.js]
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Network throttling integration test.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
yield throttleTest(true);
|
||||
yield throttleTest(false);
|
||||
});
|
||||
|
||||
function* throttleTest(actuallyThrottle) {
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let [, , monitor] = yield initNetMonitor(SIMPLE_URL);
|
||||
const {ACTIVITY_TYPE, NetMonitorController, NetMonitorView} =
|
||||
monitor.panelWin;
|
||||
|
||||
info("Starting test... (actuallyThrottle = " + actuallyThrottle + ")");
|
||||
|
||||
// When throttling, must be smaller than the length of the content
|
||||
// of SIMPLE_URL in bytes.
|
||||
const size = actuallyThrottle ? 200 : 0;
|
||||
|
||||
const request = {
|
||||
"NetworkMonitor.throttleData": {
|
||||
roundTripTimeMean: 0,
|
||||
roundTripTimeMax: 0,
|
||||
downloadBPSMean: size,
|
||||
downloadBPSMax: size,
|
||||
uploadBPSMean: 10000,
|
||||
uploadBPSMax: 10000,
|
||||
},
|
||||
};
|
||||
let client = monitor._controller.webConsoleClient;
|
||||
|
||||
info("sending throttle request");
|
||||
let deferred = promise.defer();
|
||||
client.setPreferences(request, response => {
|
||||
deferred.resolve(response);
|
||||
});
|
||||
yield deferred.promise;
|
||||
|
||||
let eventPromise =
|
||||
monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_EVENT_TIMINGS);
|
||||
yield NetMonitorController
|
||||
.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_DISABLED);
|
||||
|
||||
yield eventPromise;
|
||||
let requestItem = NetMonitorView.RequestsMenu.getItemAtIndex(0);
|
||||
const reportedOneSecond = requestItem.attachment.eventTimings.timings.receive > 1000;
|
||||
if (actuallyThrottle) {
|
||||
ok(reportedOneSecond, "download reported as taking more than one second");
|
||||
} else {
|
||||
ok(!reportedOneSecond, "download reported as taking less than one second");
|
||||
}
|
||||
|
||||
yield teardown(monitor);
|
||||
}
|
|
@ -387,6 +387,7 @@ WebConsoleFrame.prototype = {
|
|||
_destroyer: null,
|
||||
|
||||
_saveRequestAndResponseBodies: true,
|
||||
_throttleData: null,
|
||||
|
||||
// Chevron width at the starting of Web Console's input box.
|
||||
_chevronWidth: 0,
|
||||
|
@ -424,6 +425,36 @@ WebConsoleFrame.prototype = {
|
|||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Setter for throttling data.
|
||||
*
|
||||
* @param boolean value
|
||||
* The new value you want to set; @see NetworkThrottleManager.
|
||||
*/
|
||||
setThrottleData: function(value) {
|
||||
if (!this.webConsoleClient) {
|
||||
// Don't continue if the webconsole disconnected.
|
||||
return promise.resolve(null);
|
||||
}
|
||||
|
||||
let deferred = promise.defer();
|
||||
let toSet = {
|
||||
"NetworkMonitor.throttleData": value,
|
||||
};
|
||||
|
||||
// Make sure the web console client connection is established first.
|
||||
this.webConsoleClient.setPreferences(toSet, response => {
|
||||
if (!response.error) {
|
||||
this._throttleData = value;
|
||||
deferred.resolve(response);
|
||||
} else {
|
||||
deferred.reject(response.error);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter for the persistent logging preference.
|
||||
* @type boolean
|
||||
|
|
|
@ -1055,11 +1055,18 @@ WebConsoleActor.prototype =
|
|||
for (let key in aRequest.preferences) {
|
||||
this._prefs[key] = aRequest.preferences[key];
|
||||
|
||||
if (key == "NetworkMonitor.saveRequestAndResponseBodies" &&
|
||||
this.networkMonitor) {
|
||||
this.networkMonitor.saveRequestAndResponseBodies = this._prefs[key];
|
||||
if (this.networkMonitorChild) {
|
||||
this.networkMonitorChild.saveRequestAndResponseBodies = this._prefs[key];
|
||||
if (this.networkMonitor) {
|
||||
if (key == "NetworkMonitor.saveRequestAndResponseBodies") {
|
||||
this.networkMonitor.saveRequestAndResponseBodies = this._prefs[key];
|
||||
if (this.networkMonitorChild) {
|
||||
this.networkMonitorChild.saveRequestAndResponseBodies =
|
||||
this._prefs[key];
|
||||
}
|
||||
} else if (key == "NetworkMonitor.throttleData") {
|
||||
this.networkMonitor.throttleData = this._prefs[key];
|
||||
if (this.networkMonitorChild) {
|
||||
this.networkMonitorChild.throttleData = this._prefs[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1454,6 +1454,7 @@ NetworkMonitorChild.prototype = {
|
|||
owner: null,
|
||||
_netEvents: null,
|
||||
_saveRequestAndResponseBodies: true,
|
||||
_throttleData: null,
|
||||
|
||||
get saveRequestAndResponseBodies() {
|
||||
return this._saveRequestAndResponseBodies;
|
||||
|
@ -1470,6 +1471,21 @@ NetworkMonitorChild.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
get throttleData() {
|
||||
return this._throttleData;
|
||||
},
|
||||
|
||||
set throttleData(val) {
|
||||
this._throttleData = val;
|
||||
|
||||
this._messageManager.sendAsyncMessage("debug:netmonitor", {
|
||||
action: "setPreferences",
|
||||
preferences: {
|
||||
throttleData: this._throttleData,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.conn.setupInParent({
|
||||
module: "devtools/shared/webconsole/network-monitor",
|
||||
|
@ -1676,8 +1692,9 @@ NetworkMonitorParent.prototype = {
|
|||
case "setPreferences": {
|
||||
let {preferences} = msg.json;
|
||||
for (let key of Object.keys(preferences)) {
|
||||
if (key == "saveRequestAndResponseBodies" && this.netMonitor) {
|
||||
this.netMonitor.saveRequestAndResponseBodies = preferences[key];
|
||||
if ((key == "saveRequestAndResponseBodies" ||
|
||||
key == "throttleData") && this.netMonitor) {
|
||||
this.netMonitor[key] = preferences[key];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -360,16 +360,28 @@ NetworkThrottleQueue.prototype = {
|
|||
* downloadBPSMax {Number} Maximum bytes per second for downloads.
|
||||
* uploadBPSMean {Number} Mean bytes per second for uploads.
|
||||
* uploadBPSMax {Number} Maximum bytes per second for uploads.
|
||||
*
|
||||
* Download throttling will not be done if downloadBPSMean and
|
||||
* downloadBPSMax are <= 0. Upload throttling will not be done if
|
||||
* uploadBPSMean and uploadBPSMax are <= 0.
|
||||
*/
|
||||
function NetworkThrottleManager({roundTripTimeMean, roundTripTimeMax,
|
||||
downloadBPSMean, downloadBPSMax,
|
||||
uploadBPSMean, uploadBPSMax}) {
|
||||
this.downloadQueue =
|
||||
new NetworkThrottleQueue(downloadBPSMean, downloadBPSMax,
|
||||
roundTripTimeMean, roundTripTimeMax);
|
||||
this.uploadQueue = Cc["@mozilla.org/network/throttlequeue;1"]
|
||||
.createInstance(Ci.nsIInputChannelThrottleQueue);
|
||||
this.uploadQueue.init(uploadBPSMean, uploadBPSMax);
|
||||
if (downloadBPSMax <= 0 && downloadBPSMean <= 0) {
|
||||
this.downloadQueue = null;
|
||||
} else {
|
||||
this.downloadQueue =
|
||||
new NetworkThrottleQueue(downloadBPSMean, downloadBPSMax,
|
||||
roundTripTimeMean, roundTripTimeMax);
|
||||
}
|
||||
if (uploadBPSMax <= 0 && uploadBPSMean <= 0) {
|
||||
this.uploadQueue = null;
|
||||
} else {
|
||||
this.uploadQueue = Cc["@mozilla.org/network/throttlequeue;1"]
|
||||
.createInstance(Ci.nsIInputChannelThrottleQueue);
|
||||
this.uploadQueue.init(uploadBPSMean, uploadBPSMax);
|
||||
}
|
||||
}
|
||||
exports.NetworkThrottleManager = NetworkThrottleManager;
|
||||
|
||||
|
@ -379,13 +391,17 @@ NetworkThrottleManager.prototype = {
|
|||
* install it using |setNewListener|.
|
||||
*
|
||||
* @param {nsITraceableChannel} channel the channel to manage
|
||||
* @return {NetworkThrottleListener} the new listener
|
||||
* @return {NetworkThrottleListener} the new listener, or null if
|
||||
* download throttling is not being done.
|
||||
*/
|
||||
manage: function (channel) {
|
||||
let listener = new NetworkThrottleListener(this.downloadQueue);
|
||||
let originalListener = channel.setNewListener(listener);
|
||||
listener.setOriginalListener(originalListener);
|
||||
return listener;
|
||||
if (this.downloadQueue) {
|
||||
let listener = new NetworkThrottleListener(this.downloadQueue);
|
||||
let originalListener = channel.setNewListener(listener);
|
||||
listener.setOriginalListener(originalListener);
|
||||
return listener;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -394,7 +410,9 @@ NetworkThrottleManager.prototype = {
|
|||
* @param {nsITraceableChannel} channel the channel to manage
|
||||
*/
|
||||
manageUpload: function (channel) {
|
||||
channel = channel.QueryInterface(Ci.nsIThrottledInputChannel);
|
||||
channel.throttleQueue = this.uploadQueue;
|
||||
if (this.uploadQueue) {
|
||||
channel = channel.QueryInterface(Ci.nsIThrottledInputChannel);
|
||||
channel.throttleQueue = this.uploadQueue;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче