summaryrefslogtreecommitdiffstats
path: root/dom/indexedDB/test/unit/test_connection_idle_maintenance.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/indexedDB/test/unit/test_connection_idle_maintenance.js')
-rw-r--r--dom/indexedDB/test/unit/test_connection_idle_maintenance.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/dom/indexedDB/test/unit/test_connection_idle_maintenance.js b/dom/indexedDB/test/unit/test_connection_idle_maintenance.js
new file mode 100644
index 0000000000..288f656c65
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_connection_idle_maintenance.js
@@ -0,0 +1,97 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/* exported testSteps */
+async function testSteps() {
+ // A constant used to deal with small decrease in usage when transactions are
+ // transferred from the WAL file back into the original database, also called
+ // as checkpointing.
+ const cosmologicalConstant = 31768;
+
+ // The length of time that database connections will be held open after all
+ // transactions have completed before doing idle maintenance.
+ const connectionIdleMaintenanceMS = 2 * 1000;
+
+ const name = "test_connection_idle_maintenance";
+ const abc = "abcdefghijklmnopqrstuvwxyz";
+
+ // IndexedDB on Android does `PRAGMA auto_vacuum = FULL`, so the freelist
+ // pages are moved to the end of the database file and the database file is
+ // truncated to remove the freelist pages at every transaction commit.
+ if (mozinfo.os == "android") {
+ info("Test disabled on Android for now");
+ return;
+ }
+
+ info("Creating database");
+
+ let request = indexedDB.open(name, 1);
+
+ let event = await expectingUpgrade(request);
+
+ let database = event.target.result;
+
+ let objectStore = database.createObjectStore(name);
+
+ // Add lots of data...
+ for (let i = 0; i < 10000; i++) {
+ objectStore.add(abc, i);
+ }
+
+ // And then clear it so that maintenance has some space to reclaim.
+ objectStore.clear();
+
+ await expectingSuccess(request);
+
+ info("Getting database usage before maintenance");
+
+ let databaseUsageBeforeMaintenance = await new Promise(function (resolve) {
+ getCurrentUsage(function (request) {
+ resolve(request.result.databaseUsage);
+ });
+ });
+
+ info("Waiting for maintenance to start");
+
+ // This time is a double of connectionIdleMaintenanceMS which should be
+ // pessimistic enough to work with randomly slowed down threads in the chaos
+ // mode.
+ await new Promise(function (resolve) {
+ do_timeout(2 * connectionIdleMaintenanceMS, resolve);
+ });
+
+ info("Waiting for maintenance to finish");
+
+ // This time is a double of connectionIdleMaintenanceMS which should be
+ // pessimistic enough to work with randomly slowed down threads in the chaos
+ // mode.
+ await new Promise(function (resolve) {
+ do_timeout(2 * connectionIdleMaintenanceMS, resolve);
+ });
+
+ info("Getting database usage after maintenance");
+
+ let databaseUsageAfterMaintenance = await new Promise(function (resolve) {
+ getCurrentUsage(function (request) {
+ resolve(request.result.databaseUsage);
+ });
+ });
+
+ info(
+ "Database usage before: " +
+ databaseUsageBeforeMaintenance +
+ ". " +
+ "Database usage after: " +
+ databaseUsageAfterMaintenance
+ );
+
+ // Checkpointing done immediately after the maintenance can slightly decrease
+ // the usage even when the maintenance was not run at all.
+ ok(
+ databaseUsageBeforeMaintenance - databaseUsageAfterMaintenance >=
+ cosmologicalConstant,
+ "Maintenance significantly decreased database usage"
+ );
+}