diff --git a/dom/ipc/tests/browser.ini b/dom/ipc/tests/browser.ini index 2e93f22883ef..aba377c4d095 100644 --- a/dom/ipc/tests/browser.ini +++ b/dom/ipc/tests/browser.ini @@ -20,3 +20,6 @@ skip-if = !e10s [browser_ElapsedTime.js] support-files = elapsed_time.sjs skip-if = (debug && os == "linux" && os_version == "18.04") || (!debug && os == "win") #Bug 1591344 +[browser_bug1646088.js] +support-files = file_dummy.html +skip-if = !e10s diff --git a/dom/ipc/tests/browser_bug1646088.js b/dom/ipc/tests/browser_bug1646088.js new file mode 100644 index 000000000000..4466c67129b2 --- /dev/null +++ b/dom/ipc/tests/browser_bug1646088.js @@ -0,0 +1,70 @@ +const { PromiseUtils } = ChromeUtils.import( + "resource://gre/modules/PromiseUtils.jsm" +); + +let dir = getChromeDir(getResolvedURI(gTestPath)); +dir.append("file_dummy.html"); +const uriString = Services.io.newFileURI(dir).spec; + +add_task(async function() { + await BrowserTestUtils.withNewTab("https://example.com", async function( + browser + ) { + // Override the browser's `prepareToChangeRemoteness` so that we can delay + // the process switch for an indefinite amount of time. This will allow us + // to control the timing of the resolve call to trigger the bug. + let prepareToChangeCalled = PromiseUtils.defer(); + let finishSwitch = PromiseUtils.defer(); + let oldPrepare = browser.prepareToChangeRemoteness; + browser.prepareToChangeRemoteness = async () => { + prepareToChangeCalled.resolve(); + await oldPrepare.call(browser); + await finishSwitch.promise; + }; + + // Begin a process switch, which should cause `prepareToChangeRemoteness` to + // be called. We do this from the content process to make sure the frontend + // has no chance to trigger an eager process switch. + info("Beginning process switch into file URI process"); + let browserLoaded = BrowserTestUtils.browserLoaded(browser); + await SpecialPowers.spawn(browser, [uriString], uri => { + content.location = uri; + }); + await prepareToChangeCalled.promise; + + // The tab we opened is now midway through process switching. Open another + // browser within the same tab, and immediately close it after the load + // finishes. + info("Creating new tab loaded in file URI process"); + let fileProcess; + let browserParentDestroyed = PromiseUtils.defer(); + await BrowserTestUtils.withNewTab(uriString, async function(otherBrowser) { + let remoteTab = otherBrowser.frameLoader.remoteTab; + fileProcess = remoteTab.contentProcessId; + info("Loaded test URI in pid: " + fileProcess); + + browserParentDestroyed.resolve( + TestUtils.topicObserved( + "ipc:browser-destroyed", + subject => subject === remoteTab + ) + ); + }); + await browserParentDestroyed.promise; + + // This browser has now been closed, which could cause the file content + // process to begin shutting down, despite us process switching into it. + // We can now allow the process switch to finish, and wait for the load to + // finish as well. + info("BrowserParent has been destroyed, finishing process switch"); + finishSwitch.resolve(); + await browserLoaded; + + info("Load complete"); + is( + browser.frameLoader.remoteTab.contentProcessId, + fileProcess, + "Should have loaded in the same file URI process" + ); + }); +}); diff --git a/dom/ipc/tests/file_dummy.html b/dom/ipc/tests/file_dummy.html new file mode 100644 index 000000000000..28939d8b3e25 --- /dev/null +++ b/dom/ipc/tests/file_dummy.html @@ -0,0 +1,4 @@ + +
+