test_throttle.js (4128B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /* eslint-disable mozilla/use-chromeutils-generateqi */ 7 8 const { NetworkThrottleManager } = ChromeUtils.importESModule( 9 "resource://devtools/shared/network-observer/NetworkThrottleManager.sys.mjs" 10 ); 11 const nsIScriptableInputStream = Ci.nsIScriptableInputStream; 12 13 class TestStreamListener { 14 constructor() { 15 this.state = "initial"; 16 } 17 onStartRequest() { 18 this.setState("start"); 19 } 20 21 onStopRequest() { 22 this.setState("stop"); 23 } 24 25 onDataAvailable(request, inputStream, offset, count) { 26 const sin = Cc["@mozilla.org/scriptableinputstream;1"].createInstance( 27 nsIScriptableInputStream 28 ); 29 sin.init(inputStream); 30 this.data = sin.read(count); 31 this.setState("data"); 32 } 33 34 setState(state) { 35 this.state = state; 36 if (this._deferred) { 37 this._deferred.resolve(state); 38 this._deferred = null; 39 } 40 } 41 42 onStateChanged() { 43 if (!this._deferred) { 44 let resolve, reject; 45 const promise = new Promise(function (res, rej) { 46 resolve = res; 47 reject = rej; 48 }); 49 this._deferred = { resolve, reject, promise }; 50 } 51 return this._deferred.promise; 52 } 53 } 54 55 class TestChannel { 56 constructor() { 57 this.state = "initial"; 58 this.testListener = new TestStreamListener(); 59 this._throttleQueue = null; 60 } 61 QueryInterface() { 62 return this; 63 } 64 65 get throttleQueue() { 66 return this._throttleQueue; 67 } 68 69 set throttleQueue(q) { 70 this._throttleQueue = q; 71 this.state = "throttled"; 72 } 73 74 setNewListener(listener) { 75 this.listener = listener; 76 this.state = "listener"; 77 return this.testListener; 78 } 79 } 80 81 add_task(async function () { 82 const throttler = new NetworkThrottleManager({ 83 latencyMean: 1, 84 latencyMax: 1, 85 downloadBPSMean: 500, 86 downloadBPSMax: 500, 87 uploadBPSMean: 500, 88 uploadBPSMax: 500, 89 }); 90 91 const uploadChannel = new TestChannel(); 92 throttler.manageUpload(uploadChannel); 93 equal( 94 uploadChannel.state, 95 "throttled", 96 "NetworkThrottleManager set throttleQueue" 97 ); 98 99 const downloadChannel = new TestChannel(); 100 const testListener = downloadChannel.testListener; 101 102 const listener = throttler.manage(downloadChannel); 103 equal( 104 downloadChannel.state, 105 "listener", 106 "NetworkThrottleManager called setNewListener" 107 ); 108 109 equal(testListener.state, "initial", "test listener in initial state"); 110 111 // This method must be passed through immediately. 112 listener.onStartRequest(null); 113 equal(testListener.state, "start", "test listener started"); 114 115 const TEST_INPUT = "hi bob"; 116 117 const testStream = Cc["@mozilla.org/storagestream;1"].createInstance( 118 Ci.nsIStorageStream 119 ); 120 testStream.init(512, 512); 121 const out = testStream.getOutputStream(0); 122 out.write(TEST_INPUT, TEST_INPUT.length); 123 out.close(); 124 const testInputStream = testStream.newInputStream(0); 125 126 const activityDistributor = Cc[ 127 "@mozilla.org/network/http-activity-distributor;1" 128 ].getService(Ci.nsIHttpActivityDistributor); 129 let activitySeen = false; 130 listener.addActivityCallback( 131 () => { 132 activitySeen = true; 133 }, 134 null, 135 null, 136 null, 137 activityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, 138 null, 139 TEST_INPUT.length, 140 null 141 ); 142 143 // onDataAvailable is required to immediately read the data. 144 listener.onDataAvailable(null, testInputStream, 0, 6); 145 equal(testInputStream.available(), 0, "no more data should be available"); 146 equal( 147 testListener.state, 148 "start", 149 "test listener should not have received data" 150 ); 151 equal(activitySeen, false, "activity not distributed yet"); 152 153 let newState = await testListener.onStateChanged(); 154 equal(newState, "data", "test listener received data"); 155 equal(testListener.data, TEST_INPUT, "test listener received all the data"); 156 equal(activitySeen, true, "activity has been distributed"); 157 158 const onChange = testListener.onStateChanged(); 159 listener.onStopRequest(null, null); 160 newState = await onChange; 161 equal(newState, "stop", "onStateChanged reported"); 162 });