summaryrefslogtreecommitdiffstats
path: root/dom/indexedDB/test/unit/test_temporary_storage.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/indexedDB/test/unit/test_temporary_storage.js')
-rw-r--r--dom/indexedDB/test/unit/test_temporary_storage.js279
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;
+}