Bug 1585312 - Modify the IsolationTestTools in order to adapt Fission. r=baku
authorTim Huang <tihuang@mozilla.com>
Tue, 15 Oct 2019 14:26:45 +0000
changeset 498336 ed616e1d059e21d0671d079e6ca3a515929d3f18
parent 498335 53362f65d1b68bbf1c4dfad648e0437a35d2109d
child 498337 1160e60081d1a1d02289e2af57ad816aaad12b56
push id98402
push usertihuang@mozilla.com
push dateMon, 21 Oct 2019 11:37:38 +0000
treeherderautoland@4431f798179b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1585312
milestone71.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 1585312 - Modify the IsolationTestTools in order to adapt Fission. r=baku This patch changes the ways how we construct the test page for the isolation tests. We move to use the SpecialPowers.spawn() instread of the ContentTask.spawn() for the test framework. Differential Revision: https://phabricator.services.mozilla.com/D49242
browser/components/originattributes/test/browser/head.js
--- a/browser/components/originattributes/test/browser/head.js
+++ b/browser/components/originattributes/test/browser/head.js
@@ -11,18 +11,18 @@ const TEST_URL_PATH =
 const TEST_MODE_FIRSTPARTY = 0;
 const TEST_MODE_NO_ISOLATION = 1;
 const TEST_MODE_CONTAINERS = 2;
 
 // The name of each mode.
 const TEST_MODE_NAMES = ["first party isolation", "no isolation", "containers"];
 
 // The frame types.
-const TEST_TYPE_FRAME = 0;
-const TEST_TYPE_IFRAME = 1;
+const TEST_TYPE_FRAME = 1;
+const TEST_TYPE_IFRAME = 2;
 
 // The default frame setting.
 const DEFAULT_FRAME_SETTING = [TEST_TYPE_IFRAME];
 
 let gFirstPartyBasicPage = TEST_URL_PATH + "file_firstPartyBasic.html";
 
 /**
  * Add a tab for the given url with the specific user context id.
@@ -31,35 +31,40 @@ let gFirstPartyBasicPage = TEST_URL_PATH
  *    The url of the page.
  * @param aUserContextId
  *    The user context id for this tab.
  *
  * @return tab     - The tab object of this tab.
  *         browser - The browser object of this tab.
  */
 async function openTabInUserContext(aURL, aUserContextId) {
+  info(`Start to open tab in specific userContextID: ${aUserContextId}.`);
   let originAttributes = {
     userContextId: aUserContextId,
   };
+  info("Create triggeringPrincipal.");
   let triggeringPrincipal = Services.scriptSecurityManager.createContentPrincipal(
     makeURI(aURL),
     originAttributes
   );
   // Open the tab in the correct userContextId.
+  info("Open the tab and wait for it to be loaded.");
   let tab = BrowserTestUtils.addTab(gBrowser, aURL, {
     userContextId: aUserContextId,
     triggeringPrincipal,
   });
 
   // Select tab and make sure its browser is focused.
   gBrowser.selectedTab = tab;
   tab.ownerGlobal.focus();
 
   let browser = gBrowser.getBrowserForTab(tab);
   await BrowserTestUtils.browserLoaded(browser);
+  info("Finished tab opening.");
+
   return { tab, browser };
 }
 
 /**
  * Add a tab for a page with the given first party domain. This page will have
  * an iframe which is loaded with the given url by default or you could specify
  * a frame setting to create nested frames. And this function will also modify
  * the 'content' in the ContentTask to the target frame's window object.
@@ -78,111 +83,118 @@ async function openTabInUserContext(aURL
  * @return tab     - The tab object of this tab.
  *         browser - The browser object of this tab.
  */
 async function openTabInFirstParty(
   aURL,
   aFirstPartyDomain,
   aFrameSetting = DEFAULT_FRAME_SETTING
 ) {
+  info(`Start to open tab under first party domain "${aFirstPartyDomain}".`);
   // If the first party domain ends with '/', we remove it.
   if (aFirstPartyDomain.endsWith("/")) {
     aFirstPartyDomain = aFirstPartyDomain.slice(0, -1);
   }
 
   let basicPageURL = aFirstPartyDomain + gFirstPartyBasicPage;
 
   // Open the tab for the basic first party page.
+  info("Open the tab and then wait for it to be loaded.");
   let tab = BrowserTestUtils.addTab(gBrowser, basicPageURL);
 
   // Select tab and make sure its browser is focused.
   gBrowser.selectedTab = tab;
   tab.ownerGlobal.focus();
 
   let browser = gBrowser.getBrowserForTab(tab);
   await BrowserTestUtils.browserLoaded(browser);
 
-  let pageArgs = {
-    url: aURL,
-    frames: aFrameSetting,
-    typeFrame: TEST_TYPE_FRAME,
-    typeIFrame: TEST_TYPE_IFRAME,
-    basicFrameSrc: basicPageURL,
-  };
+  // Clone the frame setting here since we will modify it later.
+  let frameSetting = aFrameSetting.slice(0);
+  let frameType;
+  let targetBrowsingContext;
 
   // Create the frame structure.
-  await ContentTask.spawn(browser, pageArgs, async function(arg) {
-    let typeFrame = arg.typeFrame;
-    let typeIFrame = arg.typeIFrame;
+  info("Create the frame structure.");
+  while ((frameType = frameSetting.shift())) {
+    if (!targetBrowsingContext) {
+      targetBrowsingContext = browser;
+    }
+
+    let frameURL = !frameSetting.length ? aURL : basicPageURL;
 
-    // Redefine the 'content' for allowing us to change its target, and making
-    // ContentTask.spawn can directly work on the frame element.
-    this.frameWindow = content;
-
-    Object.defineProperty(this, "content", {
-      get: () => this.frameWindow,
-    });
-
-    let frameElement;
-    let numOfLayers = 0;
+    if (frameType == TEST_TYPE_FRAME) {
+      info("Add the frameset.");
+      targetBrowsingContext = await SpecialPowers.spawn(
+        targetBrowsingContext,
+        [frameURL],
+        async function(aFrameURL) {
+          // Add a frameset which carries the frame element.
+          let frameSet = content.document.createElement("frameset");
+          frameSet.cols = "50%,50%";
 
-    for (let type of arg.frames) {
-      let document = content.document;
-      numOfLayers++;
+          let frame = content.document.createElement("frame");
+          let dummyFrame = content.document.createElement("frame");
+
+          frameSet.appendChild(frame);
+          frameSet.appendChild(dummyFrame);
+
+          content.document.body.appendChild(frameSet);
 
-      if (type === typeFrame) {
-        // Add a frameset which carries the frame element.
-        let frameSet = document.createElement("frameset");
-        frameSet.cols = "50%,50%";
+          // Wait for the frame to be loaded.
+          await new Promise(done => {
+            frame.addEventListener(
+              "load",
+              function() {
+                done();
+              },
+              { capture: true, once: true }
+            );
 
-        let frame = document.createElement("frame");
-        let dummyFrame = document.createElement("frame");
-
-        frameSet.appendChild(frame);
-        frameSet.appendChild(dummyFrame);
-
-        document.body.appendChild(frameSet);
+            frame.setAttribute("src", aFrameURL);
+          });
 
-        frameElement = frame;
-      } else if (type === typeIFrame) {
-        // Add an iframe.
-        let iframe = document.createElement("iframe");
-        document.body.appendChild(iframe);
-
-        frameElement = iframe;
-      } else {
-        ok(false, "Invalid frame type.");
-        break;
-      }
+          return frame.browsingContext;
+        }
+      );
+    } else if (frameType == TEST_TYPE_IFRAME) {
+      info("Add the iframe.");
+      targetBrowsingContext = await SpecialPowers.spawn(
+        targetBrowsingContext,
+        [frameURL],
+        async function(aFrameURL) {
+          // Add an iframe.
+          let frame = content.document.createElement("iframe");
+          content.document.body.appendChild(frame);
 
-      // Wait for the frame to be loaded.
-      await new Promise(done => {
-        frameElement.addEventListener(
-          "load",
-          function() {
-            done();
-          },
-          { capture: true, once: true }
-        );
+          // Wait for the frame to be loaded.
+          await new Promise(done => {
+            frame.addEventListener(
+              "load",
+              function() {
+                done();
+              },
+              { capture: true, once: true }
+            );
+
+            frame.setAttribute("src", aFrameURL);
+          });
 
-        // If it is the deepest layer, we load the target URL. Otherwise, we
-        // load a basic page.
-        if (numOfLayers === arg.frames.length) {
-          frameElement.setAttribute("src", arg.url);
-        } else {
-          frameElement.setAttribute("src", arg.basicFrameSrc);
+          return frame.browsingContext;
         }
-      });
+      );
+    } else {
+      ok(false, "Invalid frame type.");
+      break;
+    }
+    info("Successfully added a frame");
+  }
+  info("Finished the frame structure");
 
-      // Redirect the 'content' to the frame's window.
-      this.frameWindow = frameElement.contentWindow;
-    }
-  });
-
-  return { tab, browser };
+  return { tab, browser: targetBrowsingContext };
 }
 
 this.IsolationTestTools = {
   /**
    * Adds isolation tests for first party isolation, no isolation
    * and containers respectively.
    *
    * @param aTask
@@ -219,17 +231,17 @@ this.IsolationTestTools = {
   },
 
   _addTaskForMode(aMode, aPref, aSkip, aTask) {
     if (aSkip) {
       return;
     }
 
     add_task(async function() {
-      info("Starting the test for " + TEST_MODE_NAMES[aMode]);
+      info(`Starting the test for ${TEST_MODE_NAMES[aMode]}.`);
 
       // Before run this task, reset the preferences first.
       await SpecialPowers.flushPrefEnv();
 
       // Make sure preferences are set properly.
       await SpecialPowers.pushPrefEnv({ set: aPref });
 
       await SpecialPowers.pushPrefEnv({ set: [["dom.ipc.processCount", 1]] });
@@ -347,58 +359,85 @@ this.IsolationTestTools = {
         ];
 
     this._add_task(async function(aMode) {
       let tabSettingA = 0;
 
       for (let tabSettingB of [0, 1]) {
         // Give the test a chance to set up before each case is run.
         if (aBeforeFunc) {
-          await aBeforeFunc(aMode);
+          try {
+            await aBeforeFunc(aMode);
+          } catch (e) {
+            ok(false, `Caught error while doing testing setup: ${e}.`);
+          }
         }
-
         // Create Tabs.
+        info(`Create tab A for ${TEST_MODE_NAMES[aMode]} test.`);
         let tabInfoA = await IsolationTestTools._addTab(
           aMode,
           pageURL,
           tabSettings[tabSettingA],
           firstFrameSetting
         );
+        info(`Finished Create tab A for ${TEST_MODE_NAMES[aMode]} test.`);
         let resultsA = [];
         if (aGetResultImmediately) {
-          for (let getResultFunc of aGetResultFuncs) {
-            resultsA.push(await getResultFunc(tabInfoA.browser));
+          try {
+            info(
+              `Immediately get result from tab A for ${
+                TEST_MODE_NAMES[aMode]
+              } test`
+            );
+            for (let getResultFunc of aGetResultFuncs) {
+              resultsA.push(await getResultFunc(tabInfoA.browser));
+            }
+          } catch (e) {
+            ok(false, `Caught error while getting result from Tab A: ${e}.`);
           }
         }
+        info(`Create tab B for ${TEST_MODE_NAMES[aMode]}.`);
         let tabInfoB = await IsolationTestTools._addTab(
           aMode,
           pageURL,
           tabSettings[tabSettingB],
           secondFrameSetting
         );
+        info(`Finished Create tab B for ${TEST_MODE_NAMES[aMode]} test.`);
         let i = 0;
         for (let getResultFunc of aGetResultFuncs) {
           // Fetch results from tabs.
-          let resultA = aGetResultImmediately
-            ? resultsA[i++]
-            : await getResultFunc(tabInfoA.browser);
-          let resultB = await getResultFunc(tabInfoB.browser);
-
+          info(`Fetching result from tab A for ${TEST_MODE_NAMES[aMode]}.`);
+          let resultA;
+          try {
+            resultA = aGetResultImmediately
+              ? resultsA[i++]
+              : await getResultFunc(tabInfoA.browser);
+          } catch (e) {
+            ok(false, `Caught error while getting result from Tab A: ${e}.`);
+          }
+          info(`Fetching result from tab B for ${TEST_MODE_NAMES[aMode]}.`);
+          let resultB;
+          try {
+            resultB = await getResultFunc(tabInfoB.browser);
+          } catch (e) {
+            ok(false, `Caught error while getting result from Tab B: ${e}.`);
+          }
           // Compare results.
           let result = false;
           let shouldIsolate =
             aMode !== TEST_MODE_NO_ISOLATION && tabSettingA !== tabSettingB;
           if (aCompareResultFunc) {
             result = await aCompareResultFunc(shouldIsolate, resultA, resultB);
           } else {
             result = shouldIsolate ? resultA !== resultB : resultA === resultB;
           }
 
           let msg =
-            `Testing ${TEST_MODE_NAMES[aMode]} for ` +
+            `Result of Testing ${TEST_MODE_NAMES[aMode]} for ` +
             `isolation ${shouldIsolate ? "on" : "off"} with TabSettingA ` +
             `${tabSettingA} and tabSettingB ${tabSettingB}` +
             `, resultA = ${resultA}, resultB = ${resultB}`;
 
           ok(result, msg);
         }
 
         // Close Tabs.