Bug 1244227 - add an API to enable throttling; r?Honza draft
authorTom Tromey <tom@tromey.com>
Tue, 01 Mar 2016 11:13:41 -0700
changeset 358401 e583352fc50ab73a48c38974cd60453d379a2a4a
parent 358400 84380104cd7815437be22ac3839898586f89caa7
child 519844 3a427a4a226450979de634a351a57c9e6637106d
push id16997
push userbmo:ttromey@mozilla.com
push dateMon, 02 May 2016 19:31:32 +0000
reviewersHonza
bugs1244227
milestone49.0a1
Bug 1244227 - add an API to enable throttling; r?Honza MozReview-Commit-ID: BirjFHVSZN7
devtools/client/netmonitor/test/browser.ini
devtools/client/netmonitor/test/browser_net_throttle.js
devtools/client/webconsole/webconsole.js
devtools/server/actors/webconsole.js
devtools/shared/webconsole/network-monitor.js
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -120,11 +120,12 @@ skip-if = true # Bug 1258809
 skip-if = (e10s && debug && os == 'mac') # Bug 1253037
 [browser_net_sort-02.js]
 [browser_net_sort-03.js]
 [browser_net_statistics-01.js]
 [browser_net_statistics-02.js]
 [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]
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_throttle.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Network throttling integration test.
+
+"use strict";
+
+add_task(function*() {
+  let [, , monitor] = yield initNetMonitor(SIMPLE_URL);
+  const {ACTIVITY_TYPE, NetMonitorController, NetMonitorView} =
+        monitor.panelWin;
+
+  info("Starting test... ");
+
+  const request = {
+    "NetworkMonitor.throttleData": {
+      roundTripTimeMean: 0,
+      roundTripTimeMax: 0,
+      // Must be smaller than the length of SIMPLE_URL in bytes.
+      downloadBPSMean: 200,
+      downloadBPSMax: 200,
+      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;
+
+  // content.location.reload(true);
+  const startTime = Date.now();
+  yield NetMonitorController
+    .triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_DISABLED);
+  const endTime = Date.now();
+  ok(endTime - startTime > 1000, "download took more than one second");
+
+  yield monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_EVENT_TIMINGS);
+  let requestItem = NetMonitorView.RequestsMenu.getItemAtIndex(0);
+  ok(requestItem.attachment.eventTimings.timings.receive > 1000,
+     "download reported as taking more than one second");
+
+  yield teardown(monitor);
+  finish();
+});
--- a/devtools/client/webconsole/webconsole.js
+++ b/devtools/client/webconsole/webconsole.js
@@ -390,16 +390,17 @@ WebConsoleFrame.prototype = {
    */
   get webConsoleClient() {
     return this.proxy ? this.proxy.webConsoleClient : null;
   },
 
   _destroyer: null,
 
   _saveRequestAndResponseBodies: true,
+  _throttleData: null,
 
   // Chevron width at the starting of Web Console's input box.
   _chevronWidth: 0,
   // Width of the monospace characters in Web Console's input box.
   _inputCharWidth: 0,
 
   /**
    * Setter for saving of network request and response bodies.
@@ -428,16 +429,46 @@ WebConsoleFrame.prototype = {
         deferred.reject(response.error);
       }
     });
 
     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
    */
   get persistLog() {
     // For the browser console, we receive tab navigation
     // when the original top level window we attached to is closed,
     // but we don't want to reset console history and just switch to
     // the next available window.
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -1035,21 +1035,28 @@ WebConsoleActor.prototype =
    * @param object aRequest
    *        The request message - which preferences need to be updated.
    */
   onSetPreferences: function WCA_onSetPreferences(aRequest)
   {
     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];
+          }
         }
       }
     }
     return { updated: Object.keys(aRequest.preferences) };
   },
 
   //////////////////
   // End of request handlers.
--- a/devtools/shared/webconsole/network-monitor.js
+++ b/devtools/shared/webconsole/network-monitor.js
@@ -1273,16 +1273,17 @@ function NetworkMonitorChild(appId, mess
 }
 exports.NetworkMonitorChild = NetworkMonitorChild;
 
 NetworkMonitorChild.prototype = {
   appId: null,
   owner: null,
   _netEvents: null,
   _saveRequestAndResponseBodies: true,
+  _throttleData: null,
 
   get saveRequestAndResponseBodies() {
     return this._saveRequestAndResponseBodies;
   },
 
   set saveRequestAndResponseBodies(val) {
     this._saveRequestAndResponseBodies = val;
 
@@ -1290,16 +1291,32 @@ NetworkMonitorChild.prototype = {
       appId: this.appId,
       action: "setPreferences",
       preferences: {
         saveRequestAndResponseBodies: this._saveRequestAndResponseBodies,
       },
     });
   },
 
+  get throttleData() {
+    return this._throttleData;
+  },
+
+  set throttleData(val) {
+    this._throttleData = val;
+
+    this._messageManager.sendAsyncMessage("debug:netmonitor:" + this.connID, {
+      appId: this.appId,
+      action: "setPreferences",
+      preferences: {
+        throttleData: this._throttleData,
+      },
+    });
+  },
+
   init: function () {
     let mm = this._messageManager;
     mm.addMessageListener("debug:netmonitor:" + this.connID + ":newEvent",
                           this._onNewEvent);
     mm.addMessageListener("debug:netmonitor:" + this.connID + ":updateEvent",
                           this._onUpdateEvent);
     mm.sendAsyncMessage("debug:netmonitor:" + this.connID, {
       appId: this.appId,
@@ -1466,18 +1483,19 @@ NetworkMonitorManager.prototype = {
           }, this);
           this.netMonitor.init();
         }
         break;
 
       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;
       }
 
       case "stop":
         if (this.netMonitor) {
           this.netMonitor.destroy();