Bug 1444680: Part 2: Convert test_ext_webRequest_suspend to xpcshell. r=mixedpuppy
authorKris Maglione <maglione.k@gmail.com>
Sat, 10 Mar 2018 18:02:50 -0800
changeset 407812 590b8679be3da45c7923b7b49c2cbddf67222af2
parent 407811 b3689730f6bd8f2af457021e1bd0820c720b9d85
child 407813 36eb1b1ba44f62f05cb225e6ef5902c41f98073b
push id33621
push userapavel@mozilla.com
push dateTue, 13 Mar 2018 17:12:05 +0000
treeherdermozilla-central@deb7714a7bcd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy
bugs1444680
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1444680: Part 2: Convert test_ext_webRequest_suspend to xpcshell. r=mixedpuppy MozReview-Commit-ID: 8SoEdllfzSG
toolkit/components/extensions/test/mochitest/mochitest-common.ini
toolkit/components/extensions/test/mochitest/test_ext_webrequest_suspend.html
toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
--- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini
@@ -162,16 +162,15 @@ skip-if = os == 'android'
 skip-if = os == 'android' && debug # bug 1397615
 [test_ext_webrequest_errors.html]
 [test_ext_webrequest_filter.html]
 [test_ext_webrequest_frameId.html]
 [test_ext_webrequest_hsts.html]
 [test_ext_webrequest_permission.html]
 [test_ext_webrequest_responseBody.html]
 skip-if = os == 'android' || os == 'linux' # linux, bug 1398120
-[test_ext_webrequest_suspend.html]
 [test_ext_webrequest_upgrade.html]
 [test_ext_webrequest_upload.html]
 skip-if = os == 'android' # Currently fails in emulator tests
 [test_ext_webrequest_websocket.html]
 [test_ext_webrequest_redirect_data_uri.html]
 [test_ext_window_postMessage.html]
 [test_ext_xhr_capabilities.html]
rename from toolkit/components/extensions/test/mochitest/test_ext_webrequest_suspend.html
rename to toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_suspend.html
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
@@ -1,33 +1,44 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for simple WebExtension</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
-  <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";
 
-// This file defines content scripts.
-/* eslint-env mozilla/frame-script */
+const HOSTS = new Set([
+  "example.com",
+]);
+
+const server = createHttpServer({hosts: HOSTS});
+
+const BASE_URL = "http://example.com";
+const FETCH_ORIGIN = "http://example.com/dummy";
+
+server.registerPathHandler("/return_headers.sjs", (request, response) => {
+  response.setHeader("Content-Type", "text/plain", false);
+
+  let headers = {};
+  // Why on earth is this a nsISimpleEnumerator...
+  for (let {data: header} of XPCOMUtils.IterSimpleEnumerator(request.headers,
+                                                             Ci.nsISupportsString)) {
+    headers[header.toLowerCase()] = request.getHeader(header);
+  }
+
+  response.write(JSON.stringify(headers));
+});
+
+server.registerPathHandler("/dummy", (request, response) => {
+  response.setStatusLine(request.httpVersion, 200, "OK");
+  response.write("ok");
+});
 
 add_task(async function test_suspend() {
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://mochi.test/",
+        `${BASE_URL}/`,
       ],
     },
 
     background() {
       browser.webRequest.onBeforeSendHeaders.addListener(
         details => {
           // Make sure that returning undefined or a promise that resolves to
           // undefined does not break later handlers.
@@ -42,106 +53,104 @@ add_task(async function test_suspend() {
         {urls: ["<all_urls>"]},
         ["blocking", "requestHeaders"]);
 
       browser.webRequest.onBeforeSendHeaders.addListener(
         details => {
           let requestHeaders = details.requestHeaders.concat({name: "Foo", value: "Bar"});
 
           return new Promise(resolve => {
+            // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
             setTimeout(resolve, 500);
           }).then(() => {
             return {requestHeaders};
           });
         },
         {urls: ["<all_urls>"]},
         ["blocking", "requestHeaders"]);
     },
   });
 
   await extension.startup();
 
-  let result = await fetch(SimpleTest.getTestFileURL("return_headers.sjs"));
+  let headers = JSON.parse(await ExtensionTestUtils.fetch(FETCH_ORIGIN, `${BASE_URL}/return_headers.sjs`));
 
-  let headers = JSON.parse(await result.text());
-
-  is(headers.foo, "Bar", "Request header was correctly set on suspended request");
+  equal(headers.foo, "Bar", "Request header was correctly set on suspended request");
 
   await extension.unload();
 });
 
 
 // Test that requests that were canceled while suspended for a blocking
 // listener are correctly resumed.
 add_task(async function test_error_resume() {
-  let chromeScript = SpecialPowers.loadChromeScript(() => {
-    ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-    let observer = channel => {
-      if (channel instanceof Ci.nsIHttpChannel && channel.URI.spec === "http://example.com/") {
-        Services.obs.removeObserver(observer, "http-on-before-connect");
+  let observer = channel => {
+    if (channel instanceof Ci.nsIHttpChannel && channel.URI.spec === "http://example.com/dummy") {
+      Services.obs.removeObserver(observer, "http-on-before-connect");
 
-        // Wait until the next tick to make sure this runs after WebRequest observers.
-        Promise.resolve().then(() => {
-          channel.cancel(Cr.NS_BINDING_ABORTED);
-        });
-      }
-    };
+      // Wait until the next tick to make sure this runs after WebRequest observers.
+      Promise.resolve().then(() => {
+        channel.cancel(Cr.NS_BINDING_ABORTED);
+      });
+    }
+  };
 
-    Services.obs.addObserver(observer, "http-on-before-connect");
-  });
+  Services.obs.addObserver(observer, "http-on-before-connect");
+
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://example.com/",
-        "http://mochi.test/",
+        `${BASE_URL}/`,
       ],
     },
 
     background() {
       browser.webRequest.onBeforeSendHeaders.addListener(
         details => {
           browser.test.log(`onBeforeSendHeaders({url: ${details.url}})`);
 
-          if (details.url === "http://example.com/") {
+          if (details.url === "http://example.com/dummy") {
             browser.test.sendMessage("got-before-send-headers");
           }
         },
         {urls: ["<all_urls>"]},
         ["blocking"]);
 
       browser.webRequest.onErrorOccurred.addListener(
         details => {
           browser.test.log(`onErrorOccurred({url: ${details.url}})`);
 
-          if (details.url === "http://example.com/") {
+          if (details.url === "http://example.com/dummy") {
             browser.test.sendMessage("got-error-occurred");
           }
         },
         {urls: ["<all_urls>"]});
     },
   });
 
   await extension.startup();
 
   try {
-    await fetch("http://example.com/");
+    await ExtensionTestUtils.fetch(FETCH_ORIGIN, `${BASE_URL}/dummy`);
     ok(false, "Fetch should have failed.");
   } catch (e) {
     ok(true, "Got expected error.");
   }
 
   await extension.awaitMessage("got-before-send-headers");
   await extension.awaitMessage("got-error-occurred");
 
+  // Wait for the next tick so the onErrorRecurred response can be
+  // processed before shutting down the extension.
+  await new Promise(resolve => executeSoon(resolve));
+
   await extension.unload();
-  chromeScript.destroy();
 });
 
 
 // Test that response header modifications take effect before onStartRequest fires.
 add_task(async function test_set_responseHeaders() {
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       permissions: [
@@ -164,18 +173,19 @@ add_task(async function test_set_respons
         ["blocking", "responseHeaders"]);
     },
   });
 
   await extension.startup();
 
   await new Promise(resolve => setTimeout(resolve, 0));
 
-  let chromeScript = SpecialPowers.loadChromeScript(() => {
-    ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+  let resolveHeaderPromise;
+  let headerPromise = new Promise(resolve => { resolveHeaderPromise = resolve; });
+  {
     ChromeUtils.import("resource://gre/modules/Services.jsm");
     ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
     let ssm = Services.scriptSecurityManager;
 
     let channel = NetUtil.newChannel({
       uri: "http://example.com/?modify_headers",
       loadingPrincipal: ssm.createCodebasePrincipalFromOrigin("http://example.com"),
@@ -185,48 +195,47 @@ add_task(async function test_set_respons
 
     channel.asyncOpen2({
       QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]),
 
       onStartRequest(request, context) {
         request.QueryInterface(Ci.nsIHttpChannel);
 
         try {
-          sendAsyncMessage("response-header-foo", request.getResponseHeader("foo"));
+          resolveHeaderPromise(request.getResponseHeader("foo"));
         } catch (e) {
-          sendAsyncMessage("response-header-foo", null);
+          resolveHeaderPromise(null);
         }
         request.cancel(Cr.NS_BINDING_ABORTED);
       },
 
       onStopRequest() {
       },
 
       onDataAvailable() {
         throw new Components.Exception("", Cr.NS_ERROR_FAILURE);
       },
     });
-  });
+  }
 
-  let headerValue = await chromeScript.promiseOneMessage("response-header-foo");
-  is(headerValue, "bar", "Expected Foo header value");
+  let headerValue = await headerPromise;
+  equal(headerValue, "bar", "Expected Foo header value");
 
   await extension.unload();
-  chromeScript.destroy();
 });
 
 // Test that exceptions raised from a blocking webRequest listener that returns
 // a promise are logged as expected.
 add_task(async function test_logged_error_on_promise_result() {
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://mochi.test/*",
+        `${BASE_URL}/`,
       ],
     },
 
     background() {
       async function onBeforeRequest() {
         throw new Error("Expected webRequest exception from a promise result");
       }
 
@@ -236,45 +245,34 @@ add_task(async function test_logged_erro
         if (exceptionRaised) {
           return;
         }
 
         // We only need to raise the exception once.
         exceptionRaised = true;
         return onBeforeRequest();
       }, {
-        urls: ["http://mochi.test/*"],
+        urls: ["http://example.com/*"],
         types: ["main_frame"],
       }, ["blocking"]);
 
       browser.webRequest.onBeforeRequest.addListener(() => {
         browser.test.sendMessage("web-request-event-received");
       }, {
-        urls: ["http://mochi.test/*"],
+        urls: ["http://example.com/*"],
         types: ["main_frame"],
       }, ["blocking"]);
-
-      browser.test.sendMessage("background-ready");
     },
   });
 
-  // Start to monitor the console service for the expected console message.
-  consoleMonitor.start([{message: /Expected webRequest exception from a promise result/}]);
-
-  await extension.startup();
-
-  await extension.awaitMessage("background-ready");
+  let {messages} = await promiseConsoleOutput(async () => {
+    await extension.startup();
 
-  const testWin = window.open("http://mochi.test:8888/", "_blank", "width=100,height=100");
-  await waitForLoad(testWin);
-  await extension.awaitMessage("web-request-event-received");
-  testWin.close();
+    let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/dummy`, {remote: true});
+    await extension.awaitMessage("web-request-event-received");
+    await contentPage.close();
+  });
 
-  // Check that the collected messages contains the expected console message, and fails
-  // otherwise.
-  await consoleMonitor.finished();
+  ok(messages.some(msg => /Expected webRequest exception from a promise result/.test(msg.message)),
+     "Got expected console message");
 
   await extension.unload();
 });
-
-</script>
-</body>
-</html>
--- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
@@ -77,16 +77,17 @@ skip-if = os == "android"
 [test_ext_storage_sync_crypto.js]
 skip-if = os == "android"
 [test_ext_storage_telemetry.js]
 skip-if = os == "android" # checking for telemetry needs to be updated: 1384923
 [test_ext_trustworthy_origin.js]
 [test_ext_topSites.js]
 skip-if = os == "android"
 [test_ext_webRequest_filterResponseData.js]
+[test_ext_webRequest_suspend.js]
 [test_native_manifests.js]
 subprocess = true
 skip-if = os == "android"
 [test_ext_permissions.js]
 skip-if = os == "android" # Bug 1350559
 [test_proxy_listener.js]
 [test_proxy_scripts.js]
 [test_proxy_scripts_results.js]