Bug 1170190 - Part 3: Add tests for the e10s case too; r=mayhemer
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 16 Dec 2016 17:15:16 -0500
changeset 453584 1ac1af4f133b43d2a61551c084ef2daf5e9bf7f3
parent 453583 891791aa2301956cecedd0e9909f1fc27dbf6986
child 453585 ecd1cb767041b22a56db4e2284440bb0e7523f45
push id39711
push userdmitchell@mozilla.com
push dateFri, 23 Dec 2016 21:59:47 +0000
reviewersmayhemer
bugs1170190
milestone53.0a1
Bug 1170190 - Part 3: Add tests for the e10s case too; r=mayhemer
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/test/unit/test_trackingProtection_annotateChannels.js
netwerk/test/unit_ipc/test_trackingProtection_annotateChannels_wrap1.js
netwerk/test/unit_ipc/test_trackingProtection_annotateChannels_wrap2.js
netwerk/test/unit_ipc/xpcshell.ini
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -2898,10 +2898,17 @@ HttpChannelChild::ShouldInterceptURI(nsI
   if (aShouldUpgrade) {
     rv = NS_GetSecureUpgradedURI(aURI, getter_AddRefs(upgradedURI));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   return ShouldIntercept(upgradedURI ? upgradedURI.get() : aURI);
 }
 
+mozilla::ipc::IPCResult
+HttpChannelChild::RecvSetPriority(const uint16_t& aPriority)
+{
+  mPriority = aPriority;
+  return IPC_OK();
+}
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -150,16 +150,18 @@ protected:
   mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
 
   mozilla::ipc::IPCResult RecvReportSecurityMessage(const nsString& messageTag,
                                                     const nsString& messageCategory) override;
 
   mozilla::ipc::IPCResult RecvIssueDeprecationWarning(const uint32_t& warning,
                                                       const bool& asError) override;
 
+  mozilla::ipc::IPCResult RecvSetPriority(const uint16_t& aPriority) override;
+
   bool GetAssociatedContentSecurity(nsIAssociatedContentSecurity** res = nullptr);
   virtual void DoNotifyListenerCleanup() override;
 
   NS_IMETHOD GetResponseSynthesized(bool* aSynthesized) override;
 
 private:
 
   class OverrideRunnable : public Runnable {
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1822,10 +1822,18 @@ HttpChannelParent::ReportSecurityMessage
 
 NS_IMETHODIMP
 HttpChannelParent::IssueWarning(uint32_t aWarning, bool aAsError)
 {
   Unused << SendIssueDeprecationWarning(aWarning, aAsError);
   return NS_OK;
 }
 
+void
+HttpChannelParent::DoSendSetPriority(int16_t aValue)
+{
+  if (!mIPCClosed) {
+    Unused << SendSetPriority(aValue);
+  }
+}
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -94,16 +94,19 @@ public:
     if (mChannel) {
       mChannel->SetApplyConversion(aApplyConversion);
     }
   }
 
   nsresult OpenAlternativeOutputStream(const nsACString & type, nsIOutputStream * *_retval);
 
   void InvokeAsyncOpen(nsresult rv);
+
+  // Calls SendSetPriority if mIPCClosed is false.
+  void DoSendSetPriority(int16_t aValue);
 protected:
   // used to connect redirected-to channel in parent with just created
   // ChildChannel.  Used during redirects.
   bool ConnectChannel(const uint32_t& channelId, const bool& shouldIntercept);
 
   bool DoAsyncOpen(const URIParams&           uri,
                    const OptionalURIParams&   originalUri,
                    const OptionalURIParams&   docUri,
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -26,17 +26,16 @@ namespace net {
 protocol PHttpChannel
 {
   manager PNecko;
 
 parent:
   // Note: channels are opened during construction, so no open method here:
   // see PNecko.ipdl
 
-  async SetPriority(uint16_t priority);
   async SetClassOfService(uint32_t cos);
 
   async SetCacheTokenCachedCharset(nsCString charset);
 
   async UpdateAssociatedContentSecurity(int32_t broken,
                                         int32_t no);
   async Suspend();
   async Resume();
@@ -172,13 +171,15 @@ child:
   async IssueDeprecationWarning(uint32_t warning, bool asError);
 
 both:
   // After receiving this message, the parent also calls
   // SendFinishInterceptedRedirect, and makes sure not to send any more messages
   // after that. When receiving this message, the child will call
   // Send__delete__() and complete the steps required to finish the redirect.
   async FinishInterceptedRedirect();
+
+  async SetPriority(uint16_t priority);
 };
 
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -97,16 +97,17 @@
 #include "nsICompressConvStats.h"
 #include "nsCORSListenerProxy.h"
 #include "nsISocketProvider.h"
 #include "mozilla/net/Predictor.h"
 #include "CacheControlParser.h"
 #include "nsMixedContentBlocker.h"
 #include "HSTSPrimerListener.h"
 #include "CacheStorageService.h"
+#include "HttpChannelParent.h"
 
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
 #endif
 
 namespace mozilla { namespace net {
 
 namespace {
@@ -6165,16 +6166,26 @@ NS_IMETHODIMP
 nsHttpChannel::SetPriority(int32_t value)
 {
     int16_t newValue = clamped<int32_t>(value, INT16_MIN, INT16_MAX);
     if (mPriority == newValue)
         return NS_OK;
     mPriority = newValue;
     if (mTransaction)
         gHttpHandler->RescheduleTransaction(mTransaction, mPriority);
+
+    // If this channel is the real channel for an e10s channel, notify the
+    // child side about the priority change as well.
+    nsCOMPtr<nsIParentChannel> parentChannel;
+    NS_QueryNotificationCallbacks(this, parentChannel);
+    RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
+    if (httpParent) {
+        httpParent->DoSendSetPriority(newValue);
+    }
+
     return NS_OK;
 }
 
 nsresult
 nsHttpChannel::ContinueBeginConnectWithResult()
 {
     LOG(("nsHttpChannel::ContinueBeginConnectWithResult [this=%p]", this));
     NS_PRECONDITION(!mCallOnResume, "How did that happen?");
--- a/netwerk/test/unit/test_trackingProtection_annotateChannels.js
+++ b/netwerk/test/unit/test_trackingProtection_annotateChannels.js
@@ -1,14 +1,33 @@
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://testing-common/httpd.js");
 
-do_get_profile();
+// This test supports both e10s and non-e10s mode. In non-e10s mode, this test
+// drives itself by creating a profile directory, setting up the URL classifier
+// test tables and adjusting the prefs which are necessary to do the testing.
+// In e10s mode however, some of these operations such as creating a profile
+// directory, setting up the URL classifier test tables and setting prefs
+// aren't supported in the content process, so we split the test into two
+// parts, the part testing the normal priority case by setting both prefs to
+// false (test_trackingProtection_annotateChannels_wrap1.js), and the part
+// testing the lowest priority case by setting both prefs to true
+// (test_trackingProtection_annotateChannels_wrap2.js).  These wrapper scripts
+// are also in charge of creating the profile directory and setting up the URL
+// classifier test tables.
+//
+// Below where we need to take different actions based on the process type we're
+// in, we use runtime.processType to take the correct actions.
+
+const runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
+if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) {
+  do_get_profile();
+}
 
 var Ci = Components.interfaces;
 
 function listener(tracking, priority, nextTest) {
   this._tracking = tracking;
   this._priority = priority;
   this._nextTest = nextTest;
 }
@@ -26,25 +45,42 @@ listener.prototype = {
   onStopRequest: function(request, context, status) {
   }
 };
 
 var httpServer;
 var normalOrigin, trackingOrigin;
 var testPriorityMap;
 var currentTest;
+// When this test is running in e10s mode, the parent process is in charge of
+// setting the prefs for us, so here we merely read our prefs, and if they have
+// been set we skip the normal priority test and only test the lowest priority
+// case, and if it they have not been set we skip the lowest priority test and
+// only test the normal priority case.
+// In non-e10s mode, both of these will remain false and we adjust the prefs
+// ourselves and test both of the cases in one go.
+var skipNormalPriority = false, skipLowestPriority = false;
 
 function setup_test() {
   httpServer = new HttpServer();
   httpServer.start(-1);
   httpServer.identity.setPrimary("http", "tracking.example.com", httpServer.identity.primaryPort);
   httpServer.identity.add("http", "example.com", httpServer.identity.primaryPort);
   normalOrigin = "http://localhost:" + httpServer.identity.primaryPort;
   trackingOrigin = "http://tracking.example.com:" + httpServer.identity.primaryPort;
 
+  if (runtime.processType == runtime.PROCESS_TYPE_CONTENT) {
+    if (Services.prefs.getBoolPref("privacy.trackingprotection.annotate_channels") &&
+        Services.prefs.getBoolPref("privacy.trackingprotection.lower_network_priority")) {
+      skipNormalPriority = true;
+    } else {
+      skipLowestPriority = true;
+    }
+  }
+
   runTests();
 }
 
 function doPriorityTest() {
   if (!testPriorityMap.length) {
     runTests();
     return;
   }
@@ -68,25 +104,35 @@ function makeChannel(path) {
 }
 
 var tests =[
   // Create the HTTP server.
   setup_test,
 
   // Add the test table into tracking protection table.
   function addTestTrackers() {
-    UrlClassifierTestUtils.addTestTrackers().then(() => {
+    if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) {
+      UrlClassifierTestUtils.addTestTrackers().then(() => {
+        runTests();
+      });
+    } else {
       runTests();
-    });
+    }
   },
 
   // With the pref off, the priority of channel should be normal.
   function setupNormalPriority() {
-    Services.prefs.setBoolPref("privacy.trackingprotection.annotate_channels", false);
-    Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", false);
+    if (skipNormalPriority) {
+      runTests();
+      return;
+    }
+    if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) {
+      Services.prefs.setBoolPref("privacy.trackingprotection.annotate_channels", false);
+      Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", false);
+    }
     testPriorityMap = [
       {
         path: normalOrigin + "/innocent.css",
         expectedTracking: false,
         expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
       },
       {
         path: normalOrigin + "/innocent.js",
@@ -99,24 +145,32 @@ var tests =[
         expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
       },
       {
         path: trackingOrigin + "/evil.js",
         expectedTracking: false,
         expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
       },
     ];
+    // We add the doPriorityTest test here so that it only gets injected in the
+    // test list if we're not skipping over this test.
+    tests.unshift(doPriorityTest);
     runTests();
   },
-  doPriorityTest,
 
   // With the pref on, the priority of channel should be lowest.
   function setupLowestPriority() {
-    Services.prefs.setBoolPref("privacy.trackingprotection.annotate_channels", true);
-    Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", true);
+    if (skipLowestPriority) {
+      runTests();
+      return;
+    }
+    if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) {
+      Services.prefs.setBoolPref("privacy.trackingprotection.annotate_channels", true);
+      Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", true);
+    }
     testPriorityMap = [
       {
         path: normalOrigin + "/innocent.css",
         expectedTracking: false,
         expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
       },
       {
         path: normalOrigin + "/innocent.js",
@@ -129,23 +183,27 @@ var tests =[
         expectedPriority: Ci.nsISupportsPriority.PRIORITY_LOWEST
       },
       {
         path: trackingOrigin + "/evil.js",
         expectedTracking: true,
         expectedPriority: Ci.nsISupportsPriority.PRIORITY_LOWEST
       },
     ];
+    // We add the doPriorityTest test here so that it only gets injected in the
+    // test list if we're not skipping over this test.
+    tests.unshift(doPriorityTest);
     runTests();
   },
-  doPriorityTest,
 
   function cleanUp() {
     httpServer.stop(do_test_finished);
-    UrlClassifierTestUtils.cleanupTestTrackers();
+    if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) {
+      UrlClassifierTestUtils.cleanupTestTrackers();
+    }
     runTests();
   }
 ];
 
 function runTests()
 {
   if (!tests.length) {
     do_test_finished();
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit_ipc/test_trackingProtection_annotateChannels_wrap1.js
@@ -0,0 +1,16 @@
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm");
+
+function run_test() {
+  do_get_profile();
+  Services.prefs.setBoolPref("privacy.trackingprotection.annotate_channels", false);
+  Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", false);
+  do_test_pending();
+  UrlClassifierTestUtils.addTestTrackers().then(() => {
+    run_test_in_child("../unit/test_trackingProtection_annotateChannels.js", () => {
+      UrlClassifierTestUtils.cleanupTestTrackers();
+      do_test_finished();
+    });
+    do_test_finished();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit_ipc/test_trackingProtection_annotateChannels_wrap2.js
@@ -0,0 +1,16 @@
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm");
+
+function run_test() {
+  do_get_profile();
+  Services.prefs.setBoolPref("privacy.trackingprotection.annotate_channels", true);
+  Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", true);
+  do_test_pending();
+  UrlClassifierTestUtils.addTestTrackers().then(() => {
+    run_test_in_child("../unit/test_trackingProtection_annotateChannels.js", () => {
+      UrlClassifierTestUtils.cleanupTestTrackers();
+      do_test_finished();
+    });
+    do_test_finished();
+  });
+}
--- a/netwerk/test/unit_ipc/xpcshell.ini
+++ b/netwerk/test/unit_ipc/xpcshell.ini
@@ -33,16 +33,17 @@ support-files =
   !/netwerk/test/unit/test_redirect_from_script.js
   !/netwerk/test/unit/test_redirect_history.js
   !/netwerk/test/unit/test_redirect_passing.js
   !/netwerk/test/unit/test_reentrancy.js
   !/netwerk/test/unit/test_reply_without_content_type.js
   !/netwerk/test/unit/test_resumable_channel.js
   !/netwerk/test/unit/test_simple.js
   !/netwerk/test/unit/test_synthesized_response.js
+  !/netwerk/test/unit/test_trackingProtection_annotateChannels.js
   !/netwerk/test/unit/test_xmlhttprequest.js
   !/netwerk/test/unit/head_channels.js
   !/netwerk/test/unit/head_cache2.js
   !/netwerk/test/unit/data/image.png
   !/netwerk/test/unit/data/system_root.lnk
   !/netwerk/test/unit/data/test_psl.txt
   !/netwerk/test/unit/data/test_readline1.txt
   !/netwerk/test/unit/data/test_readline2.txt
@@ -92,8 +93,10 @@ skip-if = true
 [test_XHR_redirects.js]
 [test_redirect_history_wrap.js]
 [test_reply_without_content_type_wrap.js]
 [test_getHost_wrap.js]
 [test_alt-data_simple_wrap.js]
 [test_alt-data_stream_wrap.js]
 [test_original_sent_received_head_wrap.js]
 [test_channel_id.js]
+[test_trackingProtection_annotateChannels_wrap1.js]
+[test_trackingProtection_annotateChannels_wrap2.js]