summaryrefslogtreecommitdiffstats
path: root/devtools/shared/network-observer/test/xpcshell/test_throttle.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/shared/network-observer/test/xpcshell/test_throttle.js162
1 files changed, 162 insertions, 0 deletions
diff --git a/devtools/shared/network-observer/test/xpcshell/test_throttle.js b/devtools/shared/network-observer/test/xpcshell/test_throttle.js
new file mode 100644
index 0000000000..5f8ef589fb
--- /dev/null
+++ b/devtools/shared/network-observer/test/xpcshell/test_throttle.js
@@ -0,0 +1,162 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/* eslint-disable mozilla/use-chromeutils-generateqi */
+
+const { NetworkThrottleManager } = ChromeUtils.importESModule(
+ "resource://devtools/shared/network-observer/NetworkThrottleManager.sys.mjs"
+);
+const nsIScriptableInputStream = Ci.nsIScriptableInputStream;
+
+function TestStreamListener() {
+ this.state = "initial";
+}
+TestStreamListener.prototype = {
+ onStartRequest() {
+ this.setState("start");
+ },
+
+ onStopRequest() {
+ this.setState("stop");
+ },
+
+ onDataAvailable(request, inputStream, offset, count) {
+ const sin = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
+ nsIScriptableInputStream
+ );
+ sin.init(inputStream);
+ this.data = sin.read(count);
+ this.setState("data");
+ },
+
+ setState(state) {
+ this.state = state;
+ if (this._deferred) {
+ this._deferred.resolve(state);
+ this._deferred = null;
+ }
+ },
+
+ onStateChanged() {
+ if (!this._deferred) {
+ let resolve, reject;
+ const promise = new Promise(function (res, rej) {
+ resolve = res;
+ reject = rej;
+ });
+ this._deferred = { resolve, reject, promise };
+ }
+ return this._deferred.promise;
+ },
+};
+
+function TestChannel() {
+ this.state = "initial";
+ this.testListener = new TestStreamListener();
+ this._throttleQueue = null;
+}
+TestChannel.prototype = {
+ QueryInterface() {
+ return this;
+ },
+
+ get throttleQueue() {
+ return this._throttleQueue;
+ },
+
+ set throttleQueue(q) {
+ this._throttleQueue = q;
+ this.state = "throttled";
+ },
+
+ setNewListener(listener) {
+ this.listener = listener;
+ this.state = "listener";
+ return this.testListener;
+ },
+};
+
+add_task(async function () {
+ const throttler = new NetworkThrottleManager({
+ latencyMean: 1,
+ latencyMax: 1,
+ downloadBPSMean: 500,
+ downloadBPSMax: 500,
+ uploadBPSMean: 500,
+ uploadBPSMax: 500,
+ });
+
+ const uploadChannel = new TestChannel();
+ throttler.manageUpload(uploadChannel);
+ equal(
+ uploadChannel.state,
+ "throttled",
+ "NetworkThrottleManager set throttleQueue"
+ );
+
+ const downloadChannel = new TestChannel();
+ const testListener = downloadChannel.testListener;
+
+ const listener = throttler.manage(downloadChannel);
+ equal(
+ downloadChannel.state,
+ "listener",
+ "NetworkThrottleManager called setNewListener"
+ );
+
+ equal(testListener.state, "initial", "test listener in initial state");
+
+ // This method must be passed through immediately.
+ listener.onStartRequest(null);
+ equal(testListener.state, "start", "test listener started");
+
+ const TEST_INPUT = "hi bob";
+
+ const testStream = Cc["@mozilla.org/storagestream;1"].createInstance(
+ Ci.nsIStorageStream
+ );
+ testStream.init(512, 512);
+ const out = testStream.getOutputStream(0);
+ out.write(TEST_INPUT, TEST_INPUT.length);
+ out.close();
+ const testInputStream = testStream.newInputStream(0);
+
+ const activityDistributor = Cc[
+ "@mozilla.org/network/http-activity-distributor;1"
+ ].getService(Ci.nsIHttpActivityDistributor);
+ let activitySeen = false;
+ listener.addActivityCallback(
+ () => {
+ activitySeen = true;
+ },
+ null,
+ null,
+ null,
+ activityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
+ null,
+ TEST_INPUT.length,
+ null
+ );
+
+ // onDataAvailable is required to immediately read the data.
+ listener.onDataAvailable(null, testInputStream, 0, 6);
+ equal(testInputStream.available(), 0, "no more data should be available");
+ equal(
+ testListener.state,
+ "start",
+ "test listener should not have received data"
+ );
+ equal(activitySeen, false, "activity not distributed yet");
+
+ let newState = await testListener.onStateChanged();
+ equal(newState, "data", "test listener received data");
+ equal(testListener.data, TEST_INPUT, "test listener received all the data");
+ equal(activitySeen, true, "activity has been distributed");
+
+ const onChange = testListener.onStateChanged();
+ listener.onStopRequest(null, null);
+ newState = await onChange;
+ equal(newState, "stop", "onStateChanged reported");
+});