Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/**
* Any copyright is dedicated to the Public Domain.
*/
/* eslint-disable mozilla/no-arbitrary-setTimeout */
/* exported testGenerator */
var testGenerator = testSteps();
function* testSteps() {
let uri = Services.io.newURI("https://www.example.com");
let principal = Services.scriptSecurityManager.createContentPrincipal(
uri,
{}
);
info("Setting permissions");
Services.perms.addFromPrincipal(
principal,
"indexedDB",
Ci.nsIPermissionManager.ALLOW_ACTION
);
// The idle-daily notification is disabled in xpchsell tests, so we don't
// need to do anything special to disable it for this test.
info("Activating real idle service");
do_get_idle();
info("Creating databases");
// Keep at least one database open.
let req = indexedDB.open("foo-a", 1);
req.onerror = errorHandler;
req.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
// Keep at least one factory operation alive by deleting a database that is
// stil open.
req = indexedDB.open("foo-b", 1);
req.onerror = errorHandler;
req.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
indexedDB.deleteDatabase("foo-b");
// Create a database which we will later try to open while maintenance is
// performed.
req = indexedDB.open("foo-c", 1);
req.onerror = errorHandler;
req.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let dbC = event.target.result;
dbC.close();
let dbCount = 0;
for (let persistence of ["persistent", "temporary", "default"]) {
for (let i = 1; i <= 5; i++) {
let dbName = "foo-" + i;
let dbPersistence = persistence;
let req = indexedDB.openForPrincipal(principal, dbName, {
version: 1,
storage: dbPersistence,
});
req.onerror = event => {
if (dbPersistence != "persistent") {
errorHandler(event);
return;
}
// Explicit persistence is currently blocked on mobile.
info(
"Failed to create persistent database '" +
dbPersistence +
"/" +
dbName +
"', hopefully this is on mobile!"
);
event.preventDefault();
if (!--dbCount) {
continueToNextStep();
}
};
req.onupgradeneeded = event => {
let db = event.target.result;
let objectStore = db.createObjectStore("foo");
// Add lots of data...
for (let j = 0; j < 100; j++) {
objectStore.add("abcdefghijklmnopqrstuvwxyz0123456789", j);
}
// And then clear it so that maintenance has some space to reclaim.
objectStore.clear();
};
req.onsuccess = event => {
let db = event.target.result;
ok(db, "Created database '" + dbPersistence + "/" + dbName + "'");
db.close();
if (!--dbCount) {
continueToNextStep();
}
};
dbCount++;
}
}
yield undefined;
info("Getting usage before maintenance");
let usageBeforeMaintenance;
Services.qms.getUsageForPrincipal(principal, request => {
let usage = request.result.usage;
ok(usage > 0, "Usage is non-zero");
usageBeforeMaintenance = usage;
continueToNextStep();
});
yield undefined;
info("Sending fake 'idle-daily' notification to QuotaManager");
let observer = Services.qms.QueryInterface(Ci.nsIObserver);
observer.observe(null, "idle-daily", "");
info("Opening database while maintenance is performed");
req = indexedDB.open("foo-c", 1);
req.onerror = errorHandler;
req.onsuccess = grabEventAndContinueHandler;
yield undefined;
info("Waiting for maintenance to start");
// This time is totally arbitrary. Most likely directory scanning will have
// completed, QuotaManager locks will be acquired, and maintenance tasks will
// be scheduled before this time has elapsed, so we will be testing the
// maintenance code. However, if something is slow then this will test
// shutting down in the middle of maintenance.
setTimeout(continueToNextStep, 10000);
yield undefined;
info("Getting usage after maintenance");
let usageAfterMaintenance;
Services.qms.getUsageForPrincipal(principal, request => {
let usage = request.result.usage;
ok(usage > 0, "Usage is non-zero");
usageAfterMaintenance = usage;
continueToNextStep();
});
yield undefined;
info(
"Usage before: " +
usageBeforeMaintenance +
". " +
"Usage after: " +
usageAfterMaintenance
);
ok(
usageAfterMaintenance <= usageBeforeMaintenance,
"Maintenance decreased file sizes or left them the same"
);
finishTest();
yield undefined;
}