Bug 1444680: Part 6: Convert test_ext_webRequest_responseBody to xpcshell. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 10 Mar 2018 20:15:52 -0800
changeset 765940 449141397a2f4c13969b2c0f13d6f088ee08b542
parent 765939 28198b6b577b98fd2f358c2dcba5538b85094620
push id102183
push usermaglione.k@gmail.com
push dateSun, 11 Mar 2018 06:57:39 +0000
reviewersmixedpuppy
bugs1444680
milestone60.0a1
Bug 1444680: Part 6: Convert test_ext_webRequest_responseBody to xpcshell. r?mixedpuppy MozReview-Commit-ID: DgAENLT9Kzv
toolkit/components/extensions/test/mochitest/lorem.html.gz
toolkit/components/extensions/test/mochitest/lorem.html.gz^headers^
toolkit/components/extensions/test/mochitest/mochitest-common.ini
toolkit/components/extensions/test/mochitest/test_ext_webrequest_responseBody.html
toolkit/components/extensions/test/xpcshell/data/lorem.html.gz
toolkit/components/extensions/test/xpcshell/test_ext_webRequest_responseBody.js
toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
deleted file mode 100644
--- a/toolkit/components/extensions/test/mochitest/lorem.html.gz^headers^
+++ /dev/null
@@ -1,2 +0,0 @@
-Content-Type: text/html; charset=utf-8
-Content-Encoding: gzip
--- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini
@@ -41,18 +41,16 @@ support-files =
   file_webNavigation_manualSubframe_page1.html
   file_webNavigation_manualSubframe_page2.html
   file_with_about_blank.html
   head.js
   head_cookies.js
   head_unlimitedStorage.js
   head_webrequest.js
   hsts.sjs
-  lorem.html.gz
-  lorem.html.gz^headers^
   mochitest_console.js
   oauth.html
   redirect_auto.sjs
   redirection.sjs
   return_headers.sjs
   slow_response.sjs
   webrequest_worker.js
   !/dom/tests/mochitest/geolocation/network_geolocation.sjs
@@ -152,16 +150,15 @@ skip-if = os == 'android' && debug # bug
 skip-if = os == 'android'
 [test_ext_webrequest_background_events.html]
 [test_ext_webrequest_basic.html]
 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_responseBody.html]
 skip-if = os == 'android' || os == 'linux' # linux, bug 1398120
 [test_ext_webrequest_upgrade.html]
 [test_ext_webrequest_upload.html]
 skip-if = os == 'android' # Currently fails in emulator tests
 [test_ext_webrequest_redirect_data_uri.html]
 [test_ext_window_postMessage.html]
 [test_ext_xhr_capabilities.html]
rename from toolkit/components/extensions/test/mochitest/lorem.html.gz
rename to toolkit/components/extensions/test/xpcshell/data/lorem.html.gz
rename from toolkit/components/extensions/test/mochitest/test_ext_webrequest_responseBody.html
rename to toolkit/components/extensions/test/xpcshell/test_ext_webRequest_responseBody.js
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_responseBody.html
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_responseBody.js
@@ -1,23 +1,27 @@
-<!DOCTYPE html>
+"use strict";
+
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+/* eslint-disable no-shadow */
+
+ChromeUtils.import("resource://gre/modules/Timer.jsm");
+ChromeUtils.import("resource://gre/modules/osfile.jsm");
+ChromeUtils.import("resource://testing-common/ExtensionTestCommon.jsm");
 
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>WebRequest response body filter test</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>
-"use strict";
+Cu.importGlobalProperties(["URL"]);
+
+const HOSTS = new Set([
+  "example.com",
+]);
+
+const server = createHttpServer({hosts: HOSTS});
+
+const BASE_URL = "http://example.com";
+const FETCH_ORIGIN = "http://example.com/data/file_sample.html";
 
 const SEQUENTIAL = false;
 
 const PARTS = [
   `<!DOCTYPE html>
     <html lang="en">
     <head>
       <meta charset="UTF-8">
@@ -32,16 +36,57 @@ const PARTS = [
   "Excepteur sint occaecat cupidatat non proident, <br>",
   "sunt in culpa qui officia deserunt mollit anim id est laborum.<br>",
   `
     </body>
     </html>`,
 ].map(part => `${part}\n`);
 
 const TIMEOUT = AppConstants.DEBUG ? 4000 : 800;
+
+function delay(timeout = TIMEOUT) {
+  return new Promise(resolve => setTimeout(resolve, timeout));
+}
+
+server.registerPathHandler("/slow_response.sjs", async (request, response) => {
+  response.processAsync();
+
+  response.setHeader("Content-Type", "text/html", false);
+  response.setHeader("Cache-Control", "no-cache", false);
+
+  await delay();
+
+  for (let part of PARTS) {
+    try {
+      response.write(part);
+    } catch (e) {
+      // This fails if we attempt to write data after the connection has
+      // been closed.
+      break;
+    }
+    await delay();
+  }
+
+  response.finish();
+});
+
+server.registerPathHandler("/lorem.html.gz", async (request, response) => {
+  response.processAsync();
+
+  response.setHeader("Content-Type", "Content-Type: text/html; charset=utf-8", false);
+  response.setHeader("Content-Encoding", "gzip", false);
+
+  let data = await OS.File.read(do_get_file("data/lorem.html.gz").path);
+  response.write(String.fromCharCode(...new Uint8Array(data)));
+
+  response.finish();
+});
+
+server.registerDirectory("/data/", do_get_file("data"));
+
 const TASKS = [
   {
     url: "slow_response.sjs",
     task(filter, resolve, num) {
       let decoder = new TextDecoder("utf-8");
 
       browser.test.assertEq("uninitialized", filter.status,
                             `(${num}): Got expected initial status`);
@@ -69,50 +114,50 @@ const TASKS = [
         filter.write(event.data);
 
         if (n == 3) {
           filter.suspend();
 
           browser.test.assertEq("suspended", filter.status,
                                 `(${num}): Got expected suspended status`);
 
-          let fail = event => {
+          let fail = () => {
             browser.test.fail(`(${num}): Got unexpected data event while suspended`);
           };
           filter.addEventListener("data", fail);
 
-          await new Promise(resolve => setTimeout(resolve, TIMEOUT * 3));
+          await delay(TIMEOUT * 3);
 
           browser.test.assertEq("suspended", filter.status,
                                 `(${num}): Got expected suspended status`);
 
           filter.removeEventListener("data", fail);
           filter.resume();
           browser.test.assertEq("transferringdata", filter.status,
                                 `(${num}): Got expected resumed status`);
         } else if (n > 4) {
           filter.disconnect();
 
-          filter.addEventListener("data", event => {
+          filter.addEventListener("data", () => {
             browser.test.fail(`(${num}): Got unexpected data event while disconnected`);
           });
 
           browser.test.assertEq("disconnected", filter.status,
                                 `(${num}): Got expected disconnected status`);
 
           resolve();
         }
       };
 
       filter.onerror = event => {
         browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
       };
     },
     verify(response) {
-      is(response, PARTS.join(""), "Got expected final HTML");
+      equal(response, PARTS.join(""), "Got expected final HTML");
     },
   },
   {
     url: "slow_response.sjs",
     task(filter, resolve, num) {
       let decoder = new TextDecoder("utf-8");
 
       filter.onstop = event => {
@@ -130,30 +175,30 @@ const TASKS = [
         }
         n++;
 
         filter.write(event.data);
 
         if (n == 3) {
           filter.suspend();
 
-          await new Promise(resolve => setTimeout(resolve, TIMEOUT * 3));
+          await delay(TIMEOUT * 3);
 
           filter.disconnect();
 
           resolve();
         }
       };
 
       filter.onerror = event => {
         browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
       };
     },
     verify(response) {
-      is(response, PARTS.join(""), "Got expected final HTML");
+      equal(response, PARTS.join(""), "Got expected final HTML");
     },
   },
   {
     url: "slow_response.sjs",
     task(filter, resolve, num) {
       let encoder = new TextEncoder("utf-8");
 
       filter.onstop = event => {
@@ -176,17 +221,17 @@ const TASKS = [
           checkState("suspended");
           filter.suspend();
           checkState("suspended");
           filter.resume();
           checkState("transferringdata");
           filter.suspend();
           checkState("suspended");
 
-          await new Promise(resolve => setTimeout(resolve, TIMEOUT * 3));
+          await delay(TIMEOUT * 3);
 
           checkState("suspended");
           filter.disconnect();
           checkState("disconnected");
 
           for (let method of ["suspend", "resume", "close"]) {
             browser.test.assertThrows(
               () => {
@@ -209,17 +254,17 @@ const TASKS = [
         }
       };
 
       filter.onerror = event => {
         browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
       };
     },
     verify(response) {
-      is(response, PARTS.join(""), "Got expected final HTML");
+      equal(response, PARTS.join(""), "Got expected final HTML");
     },
   },
   {
     url: "slow_response.sjs",
     task(filter, resolve, num) {
       let encoder = new TextEncoder("utf-8");
       let decoder = new TextDecoder("utf-8");
 
@@ -272,17 +317,17 @@ const TASKS = [
         }
       };
 
       filter.onerror = event => {
         browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
       };
     },
     verify(response) {
-      is(response, PARTS.slice(0, 3).join(""), "Got expected final HTML");
+      equal(response, PARTS.slice(0, 3).join(""), "Got expected final HTML");
     },
   },
   {
     url: "lorem.html.gz",
     task(filter, resolve, num) {
       let response = "";
       let decoder = new TextDecoder("utf-8");
 
@@ -313,24 +358,22 @@ const TASKS = [
         filter.write(event.data);
       };
 
       filter.onerror = event => {
         browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
       };
     },
     verify(response) {
-      is(response, PARTS.join(""), "Got expected final HTML");
+      equal(response, PARTS.join(""), "Got expected final HTML");
     },
   },
 ];
 
 function serializeTest(test, num) {
-  /* globals ExtensionTestCommon */
-
   let url = `${test.url}?test_num=${num}`;
   let task = ExtensionTestCommon.serializeFunction(test.task);
 
   return `{url: ${JSON.stringify(url)}, task: ${task}}`;
 }
 
 add_task(async function() {
   function background(TASKS) {
@@ -355,45 +398,46 @@ add_task(async function() {
       details => {
         for (let [num, test] of TASKS.entries()) {
           if (details.url.endsWith(test.url)) {
             runTest(test, num, details);
             break;
           }
         }
       }, {
-        urls: ["http://mochi.test/*?test_num=*"],
+        urls: ["http://example.com/*?test_num=*"],
       },
       ["blocking"]);
   }
 
   let extension = ExtensionTestUtils.loadExtension({
     background: `
       const PARTS = ${JSON.stringify(PARTS)};
       const TIMEOUT = ${TIMEOUT};
 
+      ${delay}
+
       (${background})([${TASKS.map(serializeTest)}])
     `,
 
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://mochi.test/",
+        "http://example.com/",
       ],
     },
   });
 
   await extension.startup();
 
   async function runTest(test, num) {
-    let url = `${test.url}?test_num=${num}`;
+    let url = `${BASE_URL}/${test.url}?test_num=${num}`;
 
-    let resp = await fetch(url);
-    let body = await resp.text();
+    let body = await ExtensionTestUtils.fetch(FETCH_ORIGIN, url);
 
     await extension.awaitMessage(`finished-${num}`);
 
     info(`Verifying test #${num}: ${url}`);
     await test.verify(body);
   }
 
   if (SEQUENTIAL) {
@@ -404,16 +448,18 @@ add_task(async function() {
     await Promise.all(TASKS.map(runTest));
   }
 
   await extension.unload();
 });
 
 // Test that registering a listener for a cached response does not cause a crash.
 add_task(async function test_cachedResponse() {
+  Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
+
   let extension = ExtensionTestUtils.loadExtension({
     background() {
       browser.webRequest.onHeadersReceived.addListener(
         data => {
           let filter = browser.webRequest.filterResponseData(data.requestId);
 
           filter.onstop = event => {
             filter.close();
@@ -421,35 +467,35 @@ add_task(async function test_cachedRespo
           filter.ondata = event => {
             filter.write(event.data);
           };
 
           if (data.fromCache) {
             browser.test.sendMessage("from-cache");
           }
         }, {
-          urls: ["http://mochi.test/*/file_sample.html?r=*"],
+          urls: ["http://example.com/*/file_sample.html?r=*"],
         },
         ["blocking"]);
     },
 
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://mochi.test/",
+        "http://example.com/",
       ],
     },
   });
 
   await extension.startup();
 
-  let url = `file_sample.html?r=${Math.random()}`;
-  await fetch(url);
-  await fetch(url);
+  let url = `${BASE_URL}/data/file_sample.html?r=${Math.random()}`;
+  await ExtensionTestUtils.fetch(FETCH_ORIGIN, url);
+  await ExtensionTestUtils.fetch(FETCH_ORIGIN, url);
   await extension.awaitMessage("from-cache");
 
   await extension.unload();
 });
 
 // Test that finishing transferring data doesn't overwrite an existing closing/closed state.
 add_task(async function test_late_close() {
   let extension = ExtensionTestUtils.loadExtension({
@@ -466,40 +512,40 @@ add_task(async function test_late_close(
           };
           filter.ondata = event => {
             filter.write(event.data);
             filter.close();
 
             browser.test.sendMessage(`done-${data.url}`);
           };
         }, {
-          urls: ["http://mochi.test/*/file_sample.html?*"],
+          urls: ["http://example.com/*/file_sample.html?*"],
         },
         ["blocking"]);
     },
 
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://mochi.test/",
+        "http://example.com/",
       ],
     },
   });
 
   await extension.startup();
 
   // This issue involves a race, so several requests in parallel to increase
   // the chances of triggering it.
   let urls = [];
   for (let i = 0; i < 32; i++) {
-    urls.push(new URL(`file_sample.html?r=${Math.random()}`, location).href);
+    urls.push(`${BASE_URL}/data/file_sample.html?r=${Math.random()}`);
   }
 
-  await Promise.all(urls.map(url => fetch(url)));
+  await Promise.all(urls.map(url => ExtensionTestUtils.fetch(FETCH_ORIGIN, url)));
   await Promise.all(urls.map(url => extension.awaitMessage(`done-${url}`)));
 
   await extension.unload();
 });
 
 add_task(async function test_permissions() {
   let extension = ExtensionTestUtils.loadExtension({
     background() {
@@ -507,17 +553,17 @@ add_task(async function test_permissions
         undefined,
         browser.webRequest.filterResponseData,
         "filterResponseData is undefined without blocking permissions");
     },
 
     manifest: {
       permissions: [
         "webRequest",
-        "http://mochi.test/",
+        "http://example.com/",
       ],
     },
   });
 
   await extension.startup();
   await extension.unload();
 });
 
@@ -534,20 +580,17 @@ add_task(async function test_invalidId()
 
       browser.test.notifyPass("invalid-request-id");
     },
 
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
-        "http://mochi.test/",
+        "http://example.com/",
       ],
     },
   });
 
   await extension.startup();
   await extension.awaitFinish("invalid-request-id");
   await extension.unload();
 });
-</script>
-</body>
-</html>
--- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
@@ -78,16 +78,17 @@ skip-if = os == "android"
 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_permission.js]
+[test_ext_webRequest_responseBody.js]
 [test_ext_webRequest_set_cookie.js]
 [test_ext_webRequest_suspend.js]
 [test_ext_webRequest_webSocket.js]
 [test_native_manifests.js]
 subprocess = true
 skip-if = os == "android"
 [test_ext_permissions.js]
 skip-if = os == "android" # Bug 1350559