/** * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ add_task(async function testSteps() { const storageDirName = "storage"; const persistenceTypeDefaultDirName = "default"; const persistenceTypePersistentDirName = "permanent"; const principal = getPrincipal("http://example.com"); const originDirName = "http+++example.com"; const clientLSDirName = "ls"; const dataFile = getRelativeFile( `${storageDirName}/${persistenceTypeDefaultDirName}/${originDirName}/` + `${clientLSDirName}/data.sqlite` ); const usageJournalFile = getRelativeFile( `${storageDirName}/${persistenceTypeDefaultDirName}/${originDirName}/` + `${clientLSDirName}/usage-journal` ); const usageFile = getRelativeFile( `${storageDirName}/${persistenceTypeDefaultDirName}/${originDirName}/` + `${clientLSDirName}/usage` ); const persistentLSDir = getRelativeFile( `${storageDirName}/${persistenceTypePersistentDirName}/${originDirName}/` + `${clientLSDirName}` ); const data = {}; data.key = "key1"; data.value = "value1"; data.usage = data.key.length + data.value.length; const usageFileCookie = 0x420a420a; async function createTestOrigin() { let storage = getLocalStorage(principal); storage.setItem(data.key, data.value); let request = reset(); await requestFinished(request); } async function createPersistentTestOrigin() { let database = getSimpleDatabase(principal, "persistent"); let request = database.open("data"); await requestFinished(request); request = reset(); await requestFinished(request); } function removeFile(file) { file.remove(false); } function createEmptyFile(file) { file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o0644); } function createEmptyDirectory(dir) { dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o0755); } function getBinaryOutputStream(file) { var ostream = Cc[ "@mozilla.org/network/file-output-stream;1" ].createInstance(Ci.nsIFileOutputStream); ostream.init(file, -1, parseInt("0644", 8), 0); let bstream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance( Ci.nsIBinaryOutputStream ); bstream.setOutputStream(ostream); return bstream; } async function initTestOrigin() { let request = initStorage(); await requestFinished(request); request = initTemporaryStorage(); await requestFinished(request); request = initTemporaryOrigin("default", principal); await requestFinished(request); } async function initPersistentTestOrigin() { let request = initStorage(); await requestFinished(request); request = initPersistentOrigin(principal); await requestFinished(request); } async function checkFiles(wantData, wantUsage) { let exists = dataFile.exists(); if (wantData) { ok(exists, "Data file does exist"); } else { ok(!exists, "Data file doesn't exist"); } exists = usageJournalFile.exists(); ok(!exists, "Usage journal file doesn't exist"); exists = usageFile.exists(); if (wantUsage) { ok(exists, "Usage file does exist"); } else { ok(!exists, "Usage file doesn't exist"); return; } let usage = await readUsageFromUsageFile(usageFile); Assert.equal(usage, data.usage, "Correct usage"); } async function clearTestOrigin() { let request = clearOrigin(principal, "default"); await requestFinished(request); } async function clearPersistentTestOrigin() { let request = clearOrigin(principal, "persistent"); await requestFinished(request); } info("Setting prefs"); Services.prefs.setBoolPref( "dom.storage.enable_unsupported_legacy_implementation", false ); info( "Stage 1 - " + "data.sqlite file doesn't exist, " + "usage-journal file doesn't exist, " + "any usage file exists" ); await createTestOrigin(); removeFile(dataFile); await initTestOrigin(); await checkFiles(/* wantData */ false, /* wantUsage */ false); await clearTestOrigin(); info( "Stage 2 - " + "data.sqlite file doesn't exist, " + "any usage-journal file exists, " + "any usage file exists" ); await createTestOrigin(); removeFile(dataFile); createEmptyFile(usageJournalFile); await initTestOrigin(); await checkFiles(/* wantData */ false, /* wantUsage */ false); await clearTestOrigin(); info( "Stage 3 - " + "valid data.sqlite file exists, " + "usage-journal file doesn't exist, " + "usage file doesn't exist" ); await createTestOrigin(); removeFile(usageFile); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 4 - " + "valid data.sqlite file exists, " + "usage-journal file doesn't exist, " + "invalid (wrong file size) usage file exists" ); await createTestOrigin(); removeFile(usageFile); createEmptyFile(usageFile); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 5 - " + "valid data.sqlite file exists, " + "usage-journal file doesn't exist, " + "invalid (wrong cookie) usage file exists" ); await createTestOrigin(); let stream = getBinaryOutputStream(usageFile); stream.write32(usageFileCookie - 1); stream.write64(data.usage); stream.close(); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 6 - " + "valid data.sqlite file exists, " + "usage-journal file doesn't exist, " + "valid usage file exists" ); await createTestOrigin(); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 7 - " + "valid data.sqlite file exists, " + "any usage-journal exists, " + "usage file doesn't exist" ); await createTestOrigin(); createEmptyFile(usageJournalFile); removeFile(usageFile); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 8 - " + "valid data.sqlite file exists, " + "any usage-journal exists, " + "invalid (wrong file size) usage file exists" ); await createTestOrigin(); createEmptyFile(usageJournalFile); removeFile(usageFile); createEmptyFile(usageFile); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 9 - " + "valid data.sqlite file exists, " + "any usage-journal exists, " + "invalid (wrong cookie) usage file exists" ); await createTestOrigin(); createEmptyFile(usageJournalFile); stream = getBinaryOutputStream(usageFile); stream.write32(usageFileCookie - 1); stream.write64(data.usage); stream.close(); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 10 - " + "valid data.sqlite file exists, " + "any usage-journal exists, " + "invalid (wrong usage) usage file exists" ); await createTestOrigin(); createEmptyFile(usageJournalFile); stream = getBinaryOutputStream(usageFile); stream.write32(usageFileCookie); stream.write64(data.usage - 1); stream.close(); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); info( "Stage 11 - " + "valid data.sqlite file exists, " + "any usage-journal exists, " + "valid usage file exists" ); await createTestOrigin(); createEmptyFile(usageJournalFile); await initTestOrigin(); await checkFiles(/* wantData */ true, /* wantUsage */ true); await clearTestOrigin(); // Verify that InitializeOrigin doesn't fail when a // storage/permanent/${origin}/ls exists. info( "Stage 12 - Testing initialization of ls directory placed in permanent " + "origin directory" ); await createPersistentTestOrigin(); createEmptyDirectory(persistentLSDir); try { await initPersistentTestOrigin(); ok(true, "Should not have thrown"); } catch (ex) { ok(false, "Should not have thrown"); } let exists = persistentLSDir.exists(); ok(exists, "ls directory in permanent origin directory does exist"); await clearPersistentTestOrigin(); });