Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- Manifest: dom/quota/test/xpcshell/xpcshell.toml
/**
* Any copyright is dedicated to the Public Domain.
*/
/**
* Verify that a stale caches.sqlite in an origin's cache/ directory does not
* kill temporary storage initialization. This reproduces the CI failure seen
* with conditioned profiles where the cache DB schema version differs from
* kLatestSchemaVersion.
*/
async function testSteps() {
const origin = "https+++www.example.com";
const originDirPath = "storage/default/" + origin;
const cacheDirPath = originDirPath + "/cache";
const cachesSQLitePath = cacheDirPath + "/caches.sqlite";
Services.prefs.setBoolPref("dom.quotaManager.loadQuotaFromCache", false);
Services.fog.initializeFOG();
let request = init();
await requestFinished(request);
async function runScenario(schemaVersion, label, expectedLabel) {
Services.fog.testResetFOG();
info("Creating origin and cache directory structure");
let cacheDir = getRelativeFile(cacheDirPath);
cacheDir.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
info(`Creating caches.sqlite with schema version ${schemaVersion}`);
let dbFile = getRelativeFile(cachesSQLitePath);
let conn = Services.storage.openUnsharedDatabase(dbFile);
// Match the pragma setup that InitializeConnection does for real cache DBs,
// so that the debug-only auto_vacuum check passes.
conn.executeSimpleSQL("PRAGMA auto_vacuum = INCREMENTAL;");
conn.executeSimpleSQL("PRAGMA journal_mode = WAL;");
if (schemaVersion > 0) {
// Create the tables that the usage queries read from so that a
// mismatched-version DB behaves like a real one (tables present, just a
// different schema version number).
conn.executeSimpleSQL(
"CREATE TABLE IF NOT EXISTS entries (" +
"id INTEGER NOT NULL PRIMARY KEY, " +
"response_padding_size INTEGER NULL" +
")"
);
conn.executeSimpleSQL(
"CREATE TABLE IF NOT EXISTS usage_info (" +
"id INTEGER NOT NULL PRIMARY KEY, " +
"total_disk_usage INTEGER NOT NULL" +
")"
);
conn.executeSimpleSQL("INSERT OR IGNORE INTO usage_info VALUES(1, 0)");
conn.schemaVersion = schemaVersion;
}
conn.close();
info("Calling initTemporaryStorage - should not throw");
request = initTemporaryStorage();
try {
await requestFinished(request);
info("initTemporaryStorage succeeded");
} catch (e) {
ok(
false,
`initTemporaryStorage should not fail for ${label}. ` +
`Got: ${e.resultName}`
);
}
if (expectedLabel) {
Assert.equal(
Glean.cache.schemaInitError[expectedLabel].testGetValue(),
1,
`Should record one ${expectedLabel} schema init error for ${label}`
);
} else {
Assert.equal(
Glean.cache.schemaInitError.future_version.testGetValue(),
undefined,
`Should not record future_version error for ${label}`
);
Assert.equal(
Glean.cache.schemaInitError.other.testGetValue(),
undefined,
`Should not record other error for ${label}`
);
}
}
const scenarios = [
[99, "future schema version (99)", "future_version"],
[30, "old but valid schema version (30)", "other"],
[0, "no schema (version 0)", null],
];
for (const [version, label, expectedLabel] of scenarios) {
info(`Scenario: ${label}`);
await runScenario(version, label, expectedLabel);
info("Clearing for next scenario");
request = clear();
await requestFinished(request);
request = init();
await requestFinished(request);
}
}