browser_content_shutdown_with_endless_js.js (2719B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const EMPTY_PAGE = 8 "http://mochi.test:8888/browser/dom/ipc/tests/file_dummy.html"; 9 10 const HANG_PAGE = 11 "http://mochi.test:8888/browser/dom/ipc/tests/file_endless_js.html"; 12 13 function pushPref(name, val) { 14 return SpecialPowers.pushPrefEnv({ set: [[name, val]] }); 15 } 16 17 async function createAndShutdownContentProcess(url) { 18 info("Create and shutdown a content process for " + url); 19 20 // Launch a new process and load url. Sets up a promise that will resolve 21 // on shutdown. 22 let browserDestroyed = Promise.withResolvers(); 23 await BrowserTestUtils.withNewTab( 24 { 25 gBrowser, 26 opening: url, 27 waitForLoad: true, 28 forceNewProcess: true, 29 }, 30 async function (otherBrowser) { 31 let remoteTab = otherBrowser.frameLoader.remoteTab; 32 33 ok(true, "Content process created."); 34 35 browserDestroyed.resolve( 36 TestUtils.topicObserved( 37 "ipc:browser-destroyed", 38 subject => subject === remoteTab 39 ) 40 ); 41 42 // Trigger onmessage in the content browser 43 await SpecialPowers.spawn(otherBrowser, [], function () { 44 content.postMessage("LoadedMessage", "*"); 45 }); 46 47 // Give the content process some extra time before we start its shutdown. 48 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout 49 await new Promise(resolve => setTimeout(resolve, 50)); 50 51 // withNewTab will start the shutdown of the child process for us 52 } 53 ); 54 55 // Now wait for it to really shut down. 56 // If the HANG_PAGE JS is not canceled we will hang here. 57 await browserDestroyed.promise; 58 59 // If we do not hang and get here, we are fine. 60 ok(true, "Shutdown of content process."); 61 } 62 63 add_task(async () => { 64 // This test is only relevant in e10s. 65 if (!gMultiProcessBrowser) { 66 ok(true, "We are not in multiprocess mode, skipping test."); 67 return; 68 } 69 70 await pushPref("dom.abort_script_on_child_shutdown", true); 71 72 // Ensure the process cache cannot interfere. 73 pushPref("dom.ipc.processPreload.enabled", false); 74 // Ensure we have no cached processes from previous tests. 75 Services.ppmm.releaseCachedProcesses(); 76 77 // First let's do a dry run that should always succeed. 78 await createAndShutdownContentProcess(EMPTY_PAGE); 79 80 // Now we will start a shutdown of our content process while our content 81 // script is running an endless loop. 82 // 83 // If the JS does not get interrupted on shutdown, it will cause this test 84 // to hang. 85 await createAndShutdownContentProcess(HANG_PAGE); 86 });