Source code
Revision control
Copy as Markdown
Other Tools
/**
* Any copyright is dedicated to the Public Domain.
*/
const { PrincipalUtils } = ChromeUtils.importESModule(
);
const { QuotaUtils } = ChromeUtils.importESModule(
);
const { TestUtils } = ChromeUtils.importESModule(
);
/**
* This test verifies the behavior when a shutdown occurs during the
* initialization of all temporary origins in the background.
*
* Test Setup & Procedure:
* 1. Lazy Origin Initialization Enabled
* - The test runs with lazy origin initialization enabled, meaning that
* calling `Services.qms.initTemporaryStorage` does not initialize
* individual origins.
*
* 2. Preparation of Existing Profile
* - Two origins belonging to different eTLD+1 groups are created.
*
* 3. Triggering Initialization of All Temporary Origins
* - The test explicitly triggers the initialization of all temporary
* origins by calling `Services.qms.initializeAllTemporaryOrigins`.
*
* 4. Inducing a Controlled Shutdown
* - The test waits for the first origin to begin initialization.
* - Once initialization starts, shutdown is triggered.
* - A 2-second delay is introduced in origin initialization to ensure
* the shutdown signal has time to propagate.
*
* 5. Expected Behavior & Verification
* - Due to the shutdown, the second origin does not initialize.
* - Since active operations are not available during shutdown, the test
* verifies the shutdown behavior by waiting for the initialization of
* all temporary origins to finish and expecting an exception.
* - The operation is expected to fail with `NS_ERROR_ABORT`.
*
* Notes & Justification:
* - This approach has been successfully used in other tests to handle
* shutdown scenarios.
* - See also:
*/
async function testShutdownDuringAllTemporaryOriginsInitialization2() {
// This test creates two origins belonging to different eTLD+1 groups on
// purpose to test specific shutdown check.
// Preparation phase: simulating an existing profile with pre-existing
// storage. At least two temporary origins must already exist.
info("Clearing storage");
{
const request = Services.qms.clear();
await QuotaUtils.requestFinished(request);
}
info("Initializing storage");
{
const request = Services.qms.init();
await QuotaUtils.requestFinished(request);
}
info("Initializing temporary storage");
{
const request = Services.qms.initTemporaryStorage();
await QuotaUtils.requestFinished(request);
}
info("Initializing temporary origin");
{
const request = Services.qms.initializeTemporaryOrigin(
"default",
principal1,
/* aCreateIfNonExistent */ true
);
await QuotaUtils.requestFinished(request);
}
info("Initializing temporary origin");
{
const request = Services.qms.initializeTemporaryOrigin(
"default",
principal2,
/* aCreateIfNonExistent */ true
);
await QuotaUtils.requestFinished(request);
}
// Restore the original uninitialized state to force reinitialization of both
// storage and temporary storage.
info("Shutting down storage");
{
const request = Services.qms.reset();
await QuotaUtils.requestFinished(request);
}
// Reinitialize storage and temporary storage.
info("Initializing storage");
{
const request = Services.qms.init();
await QuotaUtils.requestFinished(request);
}
info("Initializing temporary storage");
{
const request = Services.qms.initTemporaryStorage();
await QuotaUtils.requestFinished(request);
}
// Now trigger the initialization of all temporary origins, which normally
// happens automatically when incremental origin initialization is enabled
// and temporary storage initialization is complete.
info("Starting all temporary origins initialization");
const initPromise = (async function () {
const request = Services.qms.initializeAllTemporaryOrigins();
const promise = QuotaUtils.requestFinished(request);
return promise;
})();
info("Waiting for group initialization to start");
await TestUtils.topicObserved("QuotaManager::GroupInitializationStarted");
info("Starting shutdown");
QuotaUtils.startShutdown();
info("Waiting for all temoporary origins initialization to finish");
try {
await initPromise;
Assert.ok(false, "Should have thrown");
} catch (e) {
Assert.ok(true, "Should have thrown");
Assert.strictEqual(
e.resultCode,
Cr.NS_ERROR_ABORT,
"Threw right result code"
);
}
}
/* exported testSteps */
async function testSteps() {
add_task(
{
pref_set: [
["dom.quotaManager.temporaryStorage.lazyOriginInitialization", true],
["dom.quotaManager.loadQuotaFromCache", false],
["dom.quotaManager.groupInitialization.pauseOnIOThreadMs", 2000],
],
},
testShutdownDuringAllTemporaryOriginsInitialization2
);
}