Bug 1344089: Speed up webNavigation filters tests. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 02 Mar 2017 17:58:02 -0800
changeset 493020 3c3d6794c1de706badccd77cb461dac262583738
parent 492645 555710da7b9a13e20c927c8bb6adad118c79b932
child 493021 acc1441305a19ba9db6ca073ba7d5272fd31a8af
push id47627
push usermaglione.k@gmail.com
push dateFri, 03 Mar 2017 05:28:21 +0000
reviewersmixedpuppy
bugs1344089
milestone54.0a1
Bug 1344089: Speed up webNavigation filters tests. r?mixedpuppy MozReview-Commit-ID: 2Ily6rDIP7e
toolkit/components/extensions/test/mochitest/mochitest-common.ini
toolkit/components/extensions/test/mochitest/test_ext_webnavigation_filters.html
--- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini
@@ -97,19 +97,17 @@ skip-if = os == 'android' # Bug 1258975 
 [test_ext_i18n.html]
 [test_ext_listener_proxies.html]
 [test_ext_web_accessible_resources.html]
 [test_ext_webrequest_auth.html]
 skip-if = os == 'android'
 [test_ext_webrequest_background_events.html]
 [test_ext_webrequest_basic.html]
 [test_ext_webrequest_filter.html]
-skip-if = os == 'android' # Too slow.
 [test_ext_webrequest_suspend.html]
 [test_ext_webrequest_upload.html]
 skip-if = os == 'android' # Currently fails in emulator tests
 [test_ext_webrequest_permission.html]
 [test_ext_webnavigation.html]
 [test_ext_webnavigation_filters.html]
-skip-if = os == 'android' # Too slow.
 [test_ext_window_postMessage.html]
 [test_ext_subframes_privileges.html]
 [test_ext_xhr_capabilities.html]
--- a/toolkit/components/extensions/test/mochitest/test_ext_webnavigation_filters.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webnavigation_filters.html
@@ -8,86 +8,86 @@
   <script type="text/javascript" src="head.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 
 <script type="text/javascript">
 "use strict";
 
-if (AppConstants.platform === "android") {
-  SimpleTest.requestLongerTimeout(6);
-}
-
 add_task(function* test_webnav_unresolved_uri_on_expected_URI_scheme() {
   function background() {
-    let lastTest;
+    let listeners = [];
 
     function cleanupTestListeners() {
-      if (lastTest) {
-        let {event, okListener, failListener} = lastTest;
-        lastTest = null;
-        browser.test.log(`Cleanup previous test event listeners`);
-        browser.webNavigation[event].removeListener(okListener);
-        browser.webNavigation[event].removeListener(failListener);
+      browser.test.log(`Cleanup previous test event listeners`);
+      for (let {event, listener} of listeners.splice(0)) {
+        browser.webNavigation[event].removeListener(listener);
       }
     }
 
     function createTestListener(event, fail, urlFilter) {
-      function listener(details) {
-        let log = JSON.stringify({url: details.url, urlFilter});
-        if (fail) {
-          browser.test.fail(`Got an unexpected ${event} on the failure listener: ${log}`);
-        } else {
-          browser.test.succeed(`Got the expected ${event} on the success listener: ${log}`);
+      return new Promise(resolve => {
+        function listener(details) {
+          let log = JSON.stringify({url: details.url, urlFilter});
+          if (fail) {
+            browser.test.fail(`Got an unexpected ${event} on the failure listener: ${log}`);
+          } else {
+            browser.test.succeed(`Got the expected ${event} on the success listener: ${log}`);
+          }
+
+          resolve();
         }
 
-        cleanupTestListeners();
-        browser.test.sendMessage("test-filter-next");
-      }
-
-      browser.webNavigation[event].addListener(listener, urlFilter);
-
-      return listener;
+        browser.webNavigation[event].addListener(listener, {url: urlFilter});
+        listeners.push({event, listener});
+      });
     }
 
-    browser.test.onMessage.addListener((msg, event, okFilter, failFilter) => {
-      if (msg !== "test-filter") {
+    browser.test.onMessage.addListener((msg, events, data) => {
+      if (msg !== "test-filters") {
         return;
       }
 
-      lastTest = {
-        event,
-        // Register the failListener first, which should not be called
-        // and if it is called the test scenario is marked as a failure.
-        failListener: createTestListener(event, true, failFilter),
-        okListener: createTestListener(event, false, okFilter),
-      };
+      let promises = [];
+
+      for (let {okFilter, failFilter} of data.filters) {
+        for (let event of events) {
+          promises.push(
+            Promise.race([
+              createTestListener(event, false, okFilter),
+              createTestListener(event, true, failFilter),
+            ]));
+        }
+      }
+
+      Promise.all(promises).catch(e => {
+        browser.test.fail(`Error: ${e} :: ${e.stack}`);
+      }).then(() => {
+        cleanupTestListeners();
+        browser.test.sendMessage("test-filter-next");
+      });
 
       browser.test.sendMessage("test-filter-ready");
     });
-
-    browser.test.sendMessage("ready");
   }
 
   let extensionData = {
     manifest: {
       permissions: [
         "webNavigation",
       ],
     },
     background,
   };
 
   let extension = ExtensionTestUtils.loadExtension(extensionData);
 
   yield extension.startup();
 
-  yield extension.awaitMessage("ready");
-
   let win = window.open();
 
   let testFilterScenarios = [
     {
       url: "http://example.net/browser",
       filters: [
         // schemes
         {
@@ -98,16 +98,28 @@ add_task(function* test_webnav_unresolve
         {
           okFilter: [{ports: [80, 22, 443]}],
           failFilter: [{ports: [81, 82, 83]}],
         },
         {
           okFilter: [{ports: [22, 443, [10, 80]]}],
           failFilter: [{ports: [22, 23, [81, 100]]}],
         },
+        // multiple criteria in a single filter:
+        // if one of the critera is not verified, the event should not be received.
+        {
+          okFilter: [{schemes: ["http"], ports: [80, 22, 443]}],
+          failFilter: [{schemes: ["http"], ports: [81, 82, 83]}],
+        },
+        // multiple urlFilters on the same listener
+        // if at least one of the critera is verified, the event should be received.
+        {
+          okFilter: [{schemes: ["https"]}, {ports: [80, 22, 443]}],
+          failFilter: [{schemes: ["https"]}, {ports: [81, 82, 83]}],
+        },
       ],
     },
     {
       url: "http://example.net/browser?param=1#ref",
       filters: [
         // host: Equals, Contains, Prefix, Suffix
         {
           okFilter: [{hostEquals: "example.net"}],
@@ -165,96 +177,71 @@ add_task(function* test_webnav_unresolve
           failFilter: [{urlMatches: "example.net/.*\?wrongparam=2"}],
         },
         {
           okFilter: [{originAndPathMatches: "example.net\/browser"}],
           failFilter: [{originAndPathMatches: "example.net/.*\?param=1"}],
         },
       ],
     },
-    {
-      url: "http://example.net/browser",
-      filters: [
-        // multiple criteria in a single filter:
-        // if one of the critera is not verified, the event should not be received.
-        {
-          okFilter: [{schemes: ["http"], ports: [80, 22, 443]}],
-          failFilter: [{schemes: ["http"], ports: [81, 82, 83]}],
-        },
-        // multiple urlFilters on the same listener
-        // if at least one of the critera is verified, the event should be received.
-        {
-          okFilter: [{schemes: ["https"]}, {ports: [80, 22, 443]}],
-          failFilter: [{schemes: ["https"]}, {ports: [81, 82, 83]}],
-        },
-      ],
-    },
   ];
 
-  function* runTestScenario(event, {url, filters}) {
-    for (let testFilters of filters) {
-      let {okFilter, failFilter} = testFilters;
-
-      info(`Prepare the new test scenario: ${event} ${url} ${JSON.stringify(testFilters)}`);
-      win.location = "about:blank";
-
-      extension.sendMessage("test-filter", event, {url: okFilter}, {url: failFilter});
-      yield extension.awaitMessage("test-filter-ready");
+  info("WebNavigation event filters test scenarios starting...");
 
-      info(`Loading the test url: ${url}`);
-      win.location = url;
-
-      yield extension.awaitMessage("test-filter-next");
-
-      info("Test scenario completed. Moving to the next test scenario.");
-    }
-  }
-
-  const BASE_WEBNAV_EVENTS = [
+  const EVENTS = [
     "onBeforeNavigate",
     "onCommitted",
     "onDOMContentLoaded",
     "onCompleted",
   ];
 
-  info("WebNavigation event filters test scenarios starting...");
+  for (let data of testFilterScenarios) {
+    info(`Prepare the new test scenario: ${JSON.stringify(data)}`);
+
+    win.location = "about:blank";
 
-  for (let filterScenario of testFilterScenarios) {
-    for (let event of BASE_WEBNAV_EVENTS) {
-      yield runTestScenario(event, filterScenario);
-    }
+    extension.sendMessage("test-filters", EVENTS, data);
+    yield extension.awaitMessage("test-filter-ready");
+
+    info(`Loading the test url: ${data.url}`);
+    win.location = data.url;
+
+    yield extension.awaitMessage("test-filter-next");
+
+    info("Test scenario completed. Moving to the next test scenario.");
   }
 
   info("WebNavigation event filters test onReferenceFragmentUpdated scenario starting...");
 
   const BASE = "http://mochi.test:8888/tests/toolkit/components/extensions/test/mochitest";
   let url = BASE + "/file_WebNavigation_page3.html";
 
   let okFilter = [{urlContains: "_page3.html"}];
   let failFilter = [{ports: [444]}];
+  let data = {filters: [{okFilter, failFilter}]};
   let event = "onCompleted";
 
   info(`Loading the initial test url: ${url}`);
-  extension.sendMessage("test-filter", event, {url: okFilter}, {url: failFilter});
+  extension.sendMessage("test-filters", [event], data);
 
   yield extension.awaitMessage("test-filter-ready");
   win.location = url;
   yield extension.awaitMessage("test-filter-next");
 
   event = "onReferenceFragmentUpdated";
-  extension.sendMessage("test-filter", event, {url: okFilter}, {url: failFilter});
+  extension.sendMessage("test-filters", [event], data);
 
   yield extension.awaitMessage("test-filter-ready");
   win.location = url + "#ref1";
   yield extension.awaitMessage("test-filter-next");
 
   info("WebNavigation event filters test onHistoryStateUpdated scenario starting...");
 
   event = "onHistoryStateUpdated";
-  extension.sendMessage("test-filter", event, {url: okFilter}, {url: failFilter});
+  extension.sendMessage("test-filters", [event], data);
   yield extension.awaitMessage("test-filter-ready");
 
   win.history.pushState({}, "", BASE + "/pushState_page3.html");
   yield extension.awaitMessage("test-filter-next");
 
   // TODO: add additional specific tests for the other webNavigation events:
   // onErrorOccurred (and onCreatedNavigationTarget on supported)