diff options
Diffstat (limited to 'netwerk/test/browser/browser_child_resource.js')
-rw-r--r-- | netwerk/test/browser/browser_child_resource.js | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/netwerk/test/browser/browser_child_resource.js b/netwerk/test/browser/browser_child_resource.js new file mode 100644 index 0000000000..1d8c4b6c2f --- /dev/null +++ b/netwerk/test/browser/browser_child_resource.js @@ -0,0 +1,246 @@ +/* +Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ +"use strict"; + +// This must be loaded in the remote process for this test to be useful +const TEST_URL = "https://example.com/browser/netwerk/test/browser/dummy.html"; + +const expectedRemote = gMultiProcessBrowser ? "true" : ""; + +const resProtocol = Cc[ + "@mozilla.org/network/protocol;1?name=resource" +].getService(Ci.nsIResProtocolHandler); + +function waitForEvent(obj, name, capturing, chromeEvent) { + info("Waiting for " + name); + return new Promise(resolve => { + function listener(event) { + info("Saw " + name); + obj.removeEventListener(name, listener, capturing, chromeEvent); + resolve(event); + } + + obj.addEventListener(name, listener, capturing, chromeEvent); + }); +} + +function resolveURI(uri) { + uri = Services.io.newURI(uri); + try { + return resProtocol.resolveURI(uri); + } catch (e) { + return null; + } +} + +function remoteResolveURI(uri) { + return SpecialPowers.spawn(gBrowser.selectedBrowser, [uri], uriToResolve => { + let resProtocol = Cc[ + "@mozilla.org/network/protocol;1?name=resource" + ].getService(Ci.nsIResProtocolHandler); + + uriToResolve = Services.io.newURI(uriToResolve); + try { + return resProtocol.resolveURI(uriToResolve); + } catch (e) {} + return null; + }); +} + +// Restarts the child process by crashing it then reloading the tab +var restart = async function() { + let browser = gBrowser.selectedBrowser; + // If the tab isn't remote this would crash the main process so skip it + if (browser.getAttribute("remote") != "true") { + return browser; + } + + await BrowserTestUtils.crashFrame(browser); + + browser.reload(); + + await BrowserTestUtils.browserLoaded(browser); + is( + browser.getAttribute("remote"), + expectedRemote, + "Browser should be in the right process" + ); + return browser; +}; + +// Sanity check that this test is going to be useful +add_task(async function() { + await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); + + // This must be loaded in the remote process for this test to be useful + is( + gBrowser.selectedBrowser.getAttribute("remote"), + expectedRemote, + "Browser should be in the right process" + ); + + let local = resolveURI("resource://gre/modules/AppConstants.jsm"); + let remote = await remoteResolveURI( + "resource://gre/modules/AppConstants.jsm" + ); + is(local, remote, "AppConstants.jsm should resolve in both processes"); + + gBrowser.removeCurrentTab(); +}); + +// Add a mapping, update it then remove it +add_task(async function() { + await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); + + info("Set"); + resProtocol.setSubstitution( + "testing", + Services.io.newURI("chrome://global/content") + ); + let local = resolveURI("resource://testing/test.js"); + let remote = await remoteResolveURI("resource://testing/test.js"); + is( + local, + "chrome://global/content/test.js", + "Should resolve in main process" + ); + is( + remote, + "chrome://global/content/test.js", + "Should resolve in child process" + ); + + info("Change"); + resProtocol.setSubstitution( + "testing", + Services.io.newURI("chrome://global/skin") + ); + local = resolveURI("resource://testing/test.js"); + remote = await remoteResolveURI("resource://testing/test.js"); + is(local, "chrome://global/skin/test.js", "Should resolve in main process"); + is(remote, "chrome://global/skin/test.js", "Should resolve in child process"); + + info("Clear"); + resProtocol.setSubstitution("testing", null); + local = resolveURI("resource://testing/test.js"); + remote = await remoteResolveURI("resource://testing/test.js"); + is(local, null, "Shouldn't resolve in main process"); + is(remote, null, "Shouldn't resolve in child process"); + + gBrowser.removeCurrentTab(); +}); + +// Add a mapping, restart the child process then check it is still there +add_task(async function() { + await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); + + info("Set"); + resProtocol.setSubstitution( + "testing", + Services.io.newURI("chrome://global/content") + ); + let local = resolveURI("resource://testing/test.js"); + let remote = await remoteResolveURI("resource://testing/test.js"); + is( + local, + "chrome://global/content/test.js", + "Should resolve in main process" + ); + is( + remote, + "chrome://global/content/test.js", + "Should resolve in child process" + ); + + await restart(); + + local = resolveURI("resource://testing/test.js"); + remote = await remoteResolveURI("resource://testing/test.js"); + is( + local, + "chrome://global/content/test.js", + "Should resolve in main process" + ); + is( + remote, + "chrome://global/content/test.js", + "Should resolve in child process" + ); + + info("Change"); + resProtocol.setSubstitution( + "testing", + Services.io.newURI("chrome://global/skin") + ); + + await restart(); + + local = resolveURI("resource://testing/test.js"); + remote = await remoteResolveURI("resource://testing/test.js"); + is(local, "chrome://global/skin/test.js", "Should resolve in main process"); + is(remote, "chrome://global/skin/test.js", "Should resolve in child process"); + + info("Clear"); + resProtocol.setSubstitution("testing", null); + + await restart(); + + local = resolveURI("resource://testing/test.js"); + remote = await remoteResolveURI("resource://testing/test.js"); + is(local, null, "Shouldn't resolve in main process"); + is(remote, null, "Shouldn't resolve in child process"); + + gBrowser.removeCurrentTab(); +}); + +// Adding a mapping to a resource URI should work +add_task(async function() { + await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); + + info("Set"); + resProtocol.setSubstitution( + "testing", + Services.io.newURI("chrome://global/content") + ); + resProtocol.setSubstitution( + "testing2", + Services.io.newURI("resource://testing") + ); + let local = resolveURI("resource://testing2/test.js"); + let remote = await remoteResolveURI("resource://testing2/test.js"); + is( + local, + "chrome://global/content/test.js", + "Should resolve in main process" + ); + is( + remote, + "chrome://global/content/test.js", + "Should resolve in child process" + ); + + info("Clear"); + resProtocol.setSubstitution("testing", null); + local = resolveURI("resource://testing2/test.js"); + remote = await remoteResolveURI("resource://testing2/test.js"); + is( + local, + "chrome://global/content/test.js", + "Should resolve in main process" + ); + is( + remote, + "chrome://global/content/test.js", + "Should resolve in child process" + ); + + resProtocol.setSubstitution("testing2", null); + local = resolveURI("resource://testing2/test.js"); + remote = await remoteResolveURI("resource://testing2/test.js"); + is(local, null, "Shouldn't resolve in main process"); + is(remote, null, "Shouldn't resolve in child process"); + + gBrowser.removeCurrentTab(); +}); |