test_throttle.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* Any copyright is dedicated to the Public Domain.
  2. http://creativecommons.org/publicdomain/zero/1.0/ */
  3. "use strict";
  4. const Cu = Components.utils;
  5. const Cc = Components.classes;
  6. const Ci = Components.interfaces;
  7. const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
  8. const promise = require("promise");
  9. const { NetworkThrottleManager } =
  10. require("devtools/shared/webconsole/throttle");
  11. const nsIScriptableInputStream = Ci.nsIScriptableInputStream;
  12. function TestStreamListener() {
  13. this.state = "initial";
  14. }
  15. TestStreamListener.prototype = {
  16. onStartRequest: function() {
  17. this.setState("start");
  18. },
  19. onStopRequest: function() {
  20. this.setState("stop");
  21. },
  22. onDataAvailable: function(request, context, inputStream, offset, count) {
  23. const sin = Components.classes["@mozilla.org/scriptableinputstream;1"]
  24. .createInstance(nsIScriptableInputStream);
  25. sin.init(inputStream);
  26. this.data = sin.read(count);
  27. this.setState("data");
  28. },
  29. setState: function(state) {
  30. this.state = state;
  31. if (this._deferred) {
  32. this._deferred.resolve(state);
  33. this._deferred = null;
  34. }
  35. },
  36. onStateChanged: function() {
  37. if (!this._deferred) {
  38. this._deferred = promise.defer();
  39. }
  40. return this._deferred.promise;
  41. }
  42. };
  43. function TestChannel() {
  44. this.state = "initial";
  45. this.testListener = new TestStreamListener();
  46. this._throttleQueue = null;
  47. }
  48. TestChannel.prototype = {
  49. QueryInterface: function() {
  50. return this;
  51. },
  52. get throttleQueue() {
  53. return this._throttleQueue;
  54. },
  55. set throttleQueue(q) {
  56. this._throttleQueue = q;
  57. this.state = "throttled";
  58. },
  59. setNewListener: function(listener) {
  60. this.listener = listener;
  61. this.state = "listener";
  62. return this.testListener;
  63. },
  64. };
  65. add_task(function*() {
  66. let throttler = new NetworkThrottleManager({
  67. roundTripTimeMean: 1,
  68. roundTripTimeMax: 1,
  69. downloadBPSMean: 500,
  70. downloadBPSMax: 500,
  71. uploadBPSMean: 500,
  72. uploadBPSMax: 500,
  73. });
  74. let uploadChannel = new TestChannel();
  75. throttler.manageUpload(uploadChannel);
  76. equal(uploadChannel.state, "throttled",
  77. "NetworkThrottleManager set throttleQueue");
  78. let downloadChannel = new TestChannel();
  79. let testListener = downloadChannel.testListener;
  80. let listener = throttler.manage(downloadChannel);
  81. equal(downloadChannel.state, "listener",
  82. "NetworkThrottleManager called setNewListener");
  83. equal(testListener.state, "initial", "test listener in initial state");
  84. // This method must be passed through immediately.
  85. listener.onStartRequest(null, null);
  86. equal(testListener.state, "start", "test listener started");
  87. const TEST_INPUT = "hi bob";
  88. let testStream = Cc["@mozilla.org/storagestream;1"]
  89. .createInstance(Ci.nsIStorageStream);
  90. testStream.init(512, 512);
  91. let out = testStream.getOutputStream(0);
  92. out.write(TEST_INPUT, TEST_INPUT.length);
  93. out.close();
  94. let testInputStream = testStream.newInputStream(0);
  95. let activityDistributor =
  96. Cc["@mozilla.org/network/http-activity-distributor;1"]
  97. .getService(Ci.nsIHttpActivityDistributor);
  98. let activitySeen = false;
  99. listener.addActivityCallback(() => activitySeen = true, null, null, null,
  100. activityDistributor
  101. .ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
  102. null, TEST_INPUT.length, null);
  103. // onDataAvailable is required to immediately read the data.
  104. listener.onDataAvailable(null, null, testInputStream, 0, 6);
  105. equal(testInputStream.available(), 0, "no more data should be available");
  106. equal(testListener.state, "start",
  107. "test listener should not have received data");
  108. equal(activitySeen, false, "activity not distributed yet");
  109. let newState = yield testListener.onStateChanged();
  110. equal(newState, "data", "test listener received data");
  111. equal(testListener.data, TEST_INPUT, "test listener received all the data");
  112. equal(activitySeen, true, "activity has been distributed");
  113. let onChange = testListener.onStateChanged();
  114. listener.onStopRequest(null, null, null);
  115. newState = yield onChange;
  116. equal(newState, "stop", "onStateChanged reported");
  117. });