diff options
Diffstat (limited to 'dom/indexedDB/test/unit/test_temporary_storage.js')
-rw-r--r-- | dom/indexedDB/test/unit/test_temporary_storage.js | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/dom/indexedDB/test/unit/test_temporary_storage.js b/dom/indexedDB/test/unit/test_temporary_storage.js new file mode 100644 index 0000000000..4853ebbd14 --- /dev/null +++ b/dom/indexedDB/test/unit/test_temporary_storage.js @@ -0,0 +1,279 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ + +var testGenerator = testSteps(); + +function* testSteps() { + const name = this.window + ? window.location.pathname + : "test_temporary_storage.js"; + const finalVersion = 2; + + const tempStorageLimitKB = 1024; + const checkpointSleepTimeSec = 5; + + function getSpec(index) { + return "http://foo" + index + ".com"; + } + + for (let temporary of [true, false]) { + info("Testing '" + (temporary ? "temporary" : "default") + "' storage"); + + setTemporaryStorageLimit(tempStorageLimitKB); + + clearAllDatabases(continueToNextStepSync); + yield undefined; + + info("Stage 1 - Creating empty databases until we reach the quota limit"); + + let databases = []; + let options = { version: finalVersion }; + if (temporary) { + options.storage = "temporary"; + } + + while (true) { + let spec = getSpec(databases.length); + + info("Opening database for " + spec + " with version " + options.version); + + let gotUpgradeIncomplete = false; + let gotUpgradeComplete = false; + + let request = indexedDB.openForPrincipal( + getPrincipal(spec), + name, + options + ); + request.onerror = function (event) { + is( + request.error.name, + gotUpgradeIncomplete ? "AbortError" : "QuotaExceededError", + "Reached quota limit" + ); + event.preventDefault(); + testGenerator.next(false); + }; + request.onupgradeneeded = function (event) { + event.target.transaction.onabort = function (e) { + gotUpgradeIncomplete = true; + is(e.target.error.name, "QuotaExceededError", "Reached quota limit"); + }; + event.target.transaction.oncomplete = function () { + gotUpgradeComplete = true; + }; + }; + request.onsuccess = function (event) { + let db = event.target.result; + is(db.version, finalVersion, "Correct version " + finalVersion); + databases.push(db); + testGenerator.next(true); + }; + + let shouldContinue = yield undefined; + if (shouldContinue) { + is(gotUpgradeComplete, true, "Got upgradeneeded event"); + ok(true, "Got success event"); + } else { + break; + } + } + + while (true) { + info( + "Sleeping for " + + checkpointSleepTimeSec + + " seconds to let all " + + "checkpoints finish so that we know we have reached quota limit" + ); + setTimeout(continueToNextStepSync, checkpointSleepTimeSec * 1000); + yield undefined; + + let spec = getSpec(databases.length); + + info("Opening database for " + spec + " with version " + options.version); + + let gotUpgradeIncomplete = false; + let gotUpgradeComplete = false; + + let request = indexedDB.openForPrincipal( + getPrincipal(spec), + name, + options + ); + request.onerror = function (event) { + is( + request.error.name, + gotUpgradeIncomplete ? "AbortError" : "QuotaExceededError", + "Reached quota limit" + ); + event.preventDefault(); + testGenerator.next(false); + }; + request.onupgradeneeded = function (event) { + event.target.transaction.onabort = function (e) { + gotUpgradeIncomplete = true; + is(e.target.error.name, "QuotaExceededError", "Reached quota limit"); + }; + event.target.transaction.oncomplete = function () { + gotUpgradeComplete = true; + }; + }; + request.onsuccess = function (event) { + let db = event.target.result; + is(db.version, finalVersion, "Correct version " + finalVersion); + databases.push(db); + testGenerator.next(true); + }; + + let shouldContinue = yield undefined; + if (shouldContinue) { + is(gotUpgradeComplete, true, "Got upgradeneeded event"); + ok(true, "Got success event"); + } else { + break; + } + } + + let databaseCount = databases.length; + info("Created " + databaseCount + " databases before quota limit reached"); + + info( + "Stage 2 - " + + "Closing all databases and then attempting to create one more, then " + + "verifying that the oldest origin was cleared" + ); + + for (let i = 0; i < databases.length; i++) { + info("Closing database for " + getSpec(i)); + databases[i].close(); + + // Timer resolution on Windows is low so wait for 40ms just to be safe. + setTimeout(continueToNextStepSync, 40); + yield undefined; + } + databases = null; + + let spec = getSpec(databaseCount); + info("Opening database for " + spec + " with version " + options.version); + + let request = indexedDB.openForPrincipal(getPrincipal(spec), name, options); + request.onerror = errorHandler; + request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = unexpectedSuccessHandler; + let event = yield undefined; + + is(event.type, "upgradeneeded", "Got upgradeneeded event"); + + request.onupgradeneeded = unexpectedSuccessHandler; + request.onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + is(event.type, "success", "Got success event"); + + let db = event.target.result; + is(db.version, finalVersion, "Correct version " + finalVersion); + db.close(); + db = null; + + setTemporaryStorageLimit(tempStorageLimitKB * 2); + + resetAllDatabases(continueToNextStepSync); + yield undefined; + + delete options.version; + + spec = getSpec(0); + info("Opening database for " + spec + " with unspecified version"); + + request = indexedDB.openForPrincipal(getPrincipal(spec), name, options); + request.onerror = errorHandler; + request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = unexpectedSuccessHandler; + event = yield undefined; + + is(event.type, "upgradeneeded", "Got upgradeneeded event"); + + request.onupgradeneeded = unexpectedSuccessHandler; + request.onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + is(event.type, "success", "Got success event"); + + db = event.target.result; + is(db.version, 1, "Correct version 1 (database was recreated)"); + db.close(); + db = null; + + info( + "Stage 3 - " + + "Cutting storage limit in half to force deletion of some databases" + ); + + setTemporaryStorageLimit(tempStorageLimitKB / 2); + + resetAllDatabases(continueToNextStepSync); + yield undefined; + + info("Opening database for " + spec + " with unspecified version"); + + // Open the same db again to force QM to delete others. The first origin (0) + // should be the most recent so it should not be deleted and we should not + // get an upgradeneeded event here. + request = indexedDB.openForPrincipal(getPrincipal(spec), name, options); + request.onerror = errorHandler; + request.onupgradeneeded = unexpectedSuccessHandler; + request.onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + is(event.type, "success", "Got correct event type"); + + db = event.target.result; + is(db.version, 1, "Correct version 1"); + db.close(); + db = null; + + setTemporaryStorageLimit(tempStorageLimitKB * 2); + + resetAllDatabases(continueToNextStepSync); + yield undefined; + + options.version = finalVersion; + + let newDatabaseCount = 0; + for (let i = 0; i < databaseCount; i++) { + let spec = getSpec(i); + info("Opening database for " + spec + " with version " + options.version); + + let request = indexedDB.openForPrincipal( + getPrincipal(spec), + name, + options + ); + request.onerror = errorHandler; + request.onupgradeneeded = function (event) { + if (!event.oldVersion) { + newDatabaseCount++; + } + }; + request.onsuccess = grabEventAndContinueHandler; + let event = yield undefined; + + is(event.type, "success", "Got correct event type"); + + let db = request.result; + is(db.version, finalVersion, "Correct version " + finalVersion); + db.close(); + } + + info("Needed to recreate " + newDatabaseCount + " databases"); + ok(newDatabaseCount, "Created some new databases"); + ok(newDatabaseCount < databaseCount, "Didn't recreate all databases"); + } + + finishTest(); + yield undefined; +} |