test_shutdownDuringAllTemporaryOriginsInitialization2.js (5458B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 6 const { PrincipalUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/dom/quota/test/modules/PrincipalUtils.sys.mjs" 8 ); 9 const { QuotaUtils } = ChromeUtils.importESModule( 10 "resource://testing-common/dom/quota/test/modules/QuotaUtils.sys.mjs" 11 ); 12 const { TestUtils } = ChromeUtils.importESModule( 13 "resource://testing-common/TestUtils.sys.mjs" 14 ); 15 16 /** 17 * This test verifies the behavior when a shutdown occurs during the 18 * initialization of all temporary origins in the background. 19 * 20 * Test Setup & Procedure: 21 * 1. Lazy Origin Initialization Enabled 22 * - The test runs with lazy origin initialization enabled, meaning that 23 * calling `Services.qms.initTemporaryStorage` does not initialize 24 * individual origins. 25 * 26 * 2. Preparation of Existing Profile 27 * - Two origins belonging to different eTLD+1 groups are created. 28 * 29 * 3. Triggering Initialization of All Temporary Origins 30 * - The test explicitly triggers the initialization of all temporary 31 * origins by calling `Services.qms.initializeAllTemporaryOrigins`. 32 * 33 * 4. Inducing a Controlled Shutdown 34 * - The test waits for the first origin to begin initialization. 35 * - Once initialization starts, shutdown is triggered. 36 * - A 2-second delay is introduced in origin initialization to ensure 37 * the shutdown signal has time to propagate. 38 * 39 * 5. Expected Behavior & Verification 40 * - Due to the shutdown, the second origin does not initialize. 41 * - Since active operations are not available during shutdown, the test 42 * verifies the shutdown behavior by waiting for the initialization of 43 * all temporary origins to finish and expecting an exception. 44 * - The operation is expected to fail with `NS_ERROR_ABORT`. 45 * 46 * Notes & Justification: 47 * - This approach has been successfully used in other tests to handle 48 * shutdown scenarios. 49 * - See also: 50 * https://searchfox.org/mozilla-central/rev/d5baa11e35e0186c3c867f4948010f0742198467/modules/libpref/init/StaticPrefList.yaml#3789-3846 51 */ 52 async function testShutdownDuringAllTemporaryOriginsInitialization2() { 53 // This test creates two origins belonging to different eTLD+1 groups on 54 // purpose to test specific shutdown check. 55 const principal1 = PrincipalUtils.createPrincipal("https://example1.com"); 56 const principal2 = PrincipalUtils.createPrincipal("https://example2.com"); 57 58 // Preparation phase: simulating an existing profile with pre-existing 59 // storage. At least two temporary origins must already exist. 60 info("Clearing storage"); 61 62 { 63 const request = Services.qms.clear(); 64 await QuotaUtils.requestFinished(request); 65 } 66 67 info("Initializing storage"); 68 69 { 70 const request = Services.qms.init(); 71 await QuotaUtils.requestFinished(request); 72 } 73 74 info("Initializing temporary storage"); 75 76 { 77 const request = Services.qms.initTemporaryStorage(); 78 await QuotaUtils.requestFinished(request); 79 } 80 81 info("Initializing temporary origin"); 82 83 { 84 const request = Services.qms.initializeTemporaryOrigin( 85 "default", 86 principal1, 87 /* aCreateIfNonExistent */ true 88 ); 89 await QuotaUtils.requestFinished(request); 90 } 91 92 info("Initializing temporary origin"); 93 94 { 95 const request = Services.qms.initializeTemporaryOrigin( 96 "default", 97 principal2, 98 /* aCreateIfNonExistent */ true 99 ); 100 await QuotaUtils.requestFinished(request); 101 } 102 103 // Restore the original uninitialized state to force reinitialization of both 104 // storage and temporary storage. 105 info("Shutting down storage"); 106 107 { 108 const request = Services.qms.reset(); 109 await QuotaUtils.requestFinished(request); 110 } 111 112 // Reinitialize storage and temporary storage. 113 info("Initializing storage"); 114 115 { 116 const request = Services.qms.init(); 117 await QuotaUtils.requestFinished(request); 118 } 119 120 info("Initializing temporary storage"); 121 122 { 123 const request = Services.qms.initTemporaryStorage(); 124 await QuotaUtils.requestFinished(request); 125 } 126 127 // Now trigger the initialization of all temporary origins, which normally 128 // happens automatically when incremental origin initialization is enabled 129 // and temporary storage initialization is complete. 130 info("Starting all temporary origins initialization"); 131 132 const initPromise = (async function () { 133 const request = Services.qms.initializeAllTemporaryOrigins(); 134 const promise = QuotaUtils.requestFinished(request); 135 return promise; 136 })(); 137 138 info("Waiting for group initialization to start"); 139 140 await TestUtils.topicObserved("QuotaManager::GroupInitializationStarted"); 141 142 info("Starting shutdown"); 143 144 QuotaUtils.startShutdown(); 145 146 info("Waiting for all temoporary origins initialization to finish"); 147 148 try { 149 await initPromise; 150 Assert.ok(false, "Should have thrown"); 151 } catch (e) { 152 Assert.ok(true, "Should have thrown"); 153 Assert.strictEqual( 154 e.resultCode, 155 Cr.NS_ERROR_ABORT, 156 "Threw right result code" 157 ); 158 } 159 } 160 161 /* exported testSteps */ 162 async function testSteps() { 163 add_task( 164 { 165 pref_set: [ 166 ["dom.quotaManager.temporaryStorage.lazyOriginInitialization", true], 167 ["dom.quotaManager.loadQuotaFromCache", false], 168 ["dom.quotaManager.groupInitialization.pauseOnIOThreadMs", 2000], 169 ], 170 }, 171 testShutdownDuringAllTemporaryOriginsInitialization2 172 ); 173 }