Bug 1591014 - IDB: Add a test for orphaned files; r=ttung

Differential Revision: https://phabricator.services.mozilla.com/D50447

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan Varga 2019-10-24 12:59:41 +00:00
parent 96026b0667
commit edaf99b304
5 changed files with 95 additions and 12 deletions

Binary file not shown.

View File

@ -58,8 +58,8 @@ async function testSteps() {
createTestingEnvironment();
let request = await initChromeOrigin("persistent");
ok(request.resultCode == Cr.NS_OK, "Initialization succeed");
let request = initChromeOrigin("persistent");
await requestFinished(request);
let testingFiles = getTestingFiles();
ok(!testingFiles.dbFile.exists(), "The obsolete database file doesn't exist");

View File

@ -0,0 +1,58 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* The goal of this test is to prove that orphaned files are cleaned up during
* origin initialization. A file is orphaned when there's a file with zero size
* in the $dbName.files/journals directory and the file table in the database
* contains no records for given id. A file can become orphaned when we didn't
* have a chance to remove the file from disk during shutdown or the app just
* crashed.
*/
async function testSteps() {
const name = "test_orphaned_files.js";
const objectStoreName = "Blobs";
const blobData = { key: 1 };
info("Installing profile");
let request = clearAllDatabases();
await requestFinished(request);
// The profile contains one initialized origin directory (with an IndexedDB
// database and an orphaned file), a script for origin initialization and the
// storage database:
// - storage/permanent/chrome
// - create_db.js
// - storage.sqlite
// The file create_db.js in the package was run locally, specifically it was
// temporarily added to xpcshell.ini and then executed:
// mach xpcshell-test --interactive dom/indexedDB/test/unit/create_db.js
// Note: to make it become the profile in the test, additional manual steps
// are needed.
// 1. Remove the file "storage/ls-archive.sqlite".
installPackagedProfile("orphaned_files_profile");
info("Opening database");
request = indexedDB.open(name);
await expectingSuccess(request);
info("Getting data");
request = request.result
.transaction([objectStoreName])
.objectStore(objectStoreName)
.get(blobData.key);
await requestSucceeded(request);
info("Verifying data");
ok(request.result === undefined, "Correct result");
}

View File

@ -252,6 +252,13 @@ function setTimeout(fun, timeout) {
return timer;
}
function initChromeOrigin(persistence) {
let principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
Ci.nsIPrincipal
);
return Services.qms.initStoragesForPrincipal(principal, persistence);
}
function resetOrClearAllDatabases(callback, clear) {
if (!SpecialPowers.isMainProcess()) {
throw new Error("clearAllDatabases not implemented for child processes!");
@ -284,14 +291,16 @@ function resetOrClearAllDatabases(callback, clear) {
}
request.callback = callback;
return request;
}
function resetAllDatabases(callback) {
resetOrClearAllDatabases(callback, false);
return resetOrClearAllDatabases(callback, false);
}
function clearAllDatabases(callback) {
resetOrClearAllDatabases(callback, true);
return resetOrClearAllDatabases(callback, true);
}
function installPackagedProfile(packageName) {
@ -546,6 +555,19 @@ function getPrincipal(url) {
return Services.scriptSecurityManager.createContentPrincipal(uri, {});
}
function requestFinished(request) {
return new Promise(function(resolve, reject) {
request.callback = function(req) {
if (req.resultCode == Cr.NS_OK) {
resolve(req.result);
} else {
reject(req.resultCode);
}
};
});
}
// TODO: Rename to openDBRequestSucceeded ?
function expectingSuccess(request) {
return new Promise(function(resolve, reject) {
request.onerror = function(event) {
@ -562,6 +584,7 @@ function expectingSuccess(request) {
});
}
// TODO: Rename to openDBRequestUpgradeNeeded ?
function expectingUpgrade(request) {
return new Promise(function(resolve, reject) {
request.onerror = function(event) {
@ -578,14 +601,14 @@ function expectingUpgrade(request) {
});
}
function initChromeOrigin(persistence) {
let principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
Ci.nsIPrincipal
);
return new Promise(function(resolve) {
let request = Services.qms.initStoragesForPrincipal(principal, persistence);
request.callback = function() {
return resolve(request);
function requestSucceeded(request) {
return new Promise(function(resolve, reject) {
request.onerror = function(event) {
ok(false, "indexedDB error, '" + event.target.error.name + "'");
reject(event);
};
request.onsuccess = function(event) {
resolve(event);
};
});
}

View File

@ -13,6 +13,7 @@ support-files =
idbSubdirUpgrade2_profile.zip
mutableFileUpgrade_profile.zip
obsoleteOriginAttributes_profile.zip
orphaned_files_profile.zip
oldDirectories_profile.zip
GlobalObjectsChild.js
GlobalObjectsComponent.js
@ -33,6 +34,7 @@ support-files =
[test_bad_origin_directory.js]
[test_obsoleteOriginAttributesUpgrade.js]
[test_orphaned_files.js]
[test_blob_file_backed.js]
[test_bug1056939.js]
[test_cleanup_transaction.js]