gecko/dom/indexedDB/test/unit/test_temporary_storage.js
Jan Varga 67195df918 Bug 785884 - Implement support for temporary storage (aka shared pool). r=ehsan, r=bent
--HG--
rename : caps/tests/mochitest/test_principal_extendedorigin_appid_appstatus.html => caps/tests/mochitest/test_principal_jarprefix_origin_appid_appstatus.html
rename : dom/quota/UsageRunnable.h => dom/quota/UsageInfo.h
2013-09-11 06:18:36 +02:00

226 lines
7.4 KiB
JavaScript

/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function testSteps()
{
const name = this.window ? window.location.pathname : "Splendid Test";
const urls = [
{ url: "http://www.alpha.com", flags: [true, true, false, false] },
{ url: "http://www.beta.com", flags: [true, false, false, false] },
{ url: "http://www.gamma.com", flags: [true, true, false, false] },
{ url: "http://www.delta.com", flags: [true, true, false, false] },
{ url: "http://www.epsilon.com", flags: [true, true, false, false] },
{ url: "http://www2.alpha.com", flags: [true, true, false, false] },
{ url: "http://www2.beta.com", flags: [true, true, false, false] },
{ url: "http://www2.gamma.com", flags: [true, true, true, false] },
{ url: "http://www2.delta.com", flags: [true, true, true, true] },
{ url: "http://www2.epsilon.com", flags: [true, true, true, true] },
{ url: "http://joe.blog.alpha.com", flags: [true, true, true, true] },
{ url: "http://joe.blog.beta.com", flags: [true, true, true, true] },
{ url: "http://joe.blog.gamma.com", flags: [true, true, true, true] },
{ url: "http://joe.blog.delta.com", flags: [true, true, true, true] },
{ url: "http://joe.blog.epsilon.com", flags: [true, true, true, true] },
{ url: "http://www.rudolf.org", flags: [true, true, true, true] },
{ url: "http://www.pauline.org", flags: [true, true, true, true] },
{ url: "http://www.marie.org", flags: [true, true, true, true] },
{ url: "http://www.john.org", flags: [true, true, true, true] },
{ url: "http://www.ema.org", flags: [true, true, true, true] },
{ url: "http://www.trigger.com", flags: [false, true, true, true] }
];
const lastIndex = urls.length - 1;
const lastUrl = urls[lastIndex].url;
let quotaManager =
Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(Components.interfaces.nsIQuotaManager);
let ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
let dbSize = 0;
let databases = [];
function setLimit(limit) {
if (limit) {
SpecialPowers.setIntPref("dom.quotaManager.temporaryStorage.fixedLimit",
limit);
return;
}
SpecialPowers.clearUserPref("dom.quotaManager.temporaryStorage.fixedLimit");
}
function getPrincipal(url) {
let uri = ioService.newURI(url, null, null);
return Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
}
function getUsageForUrl(url, usageHandler) {
let uri = ioService.newURI(url, null, null);
function callback(uri, usage, fileUsage) {
usageHandler(usage, fileUsage);
}
quotaManager.getUsageForURI(uri, callback);
}
function grabUsageAndContinueHandler(usage, fileUsage) {
testGenerator.send(usage);
}
function checkUsage(stageIndex) {
let handledIndex = 0;
function usageHandler(usage, fileUsage) {
if (urls[handledIndex].flags[stageIndex - 1]) {
ok(usage > 0, "Correct usage");
}
else {
ok(usage == 0, "Correct usage");
}
if (++handledIndex == urls.length) {
continueToNextStep();
}
}
for (let i = 0; i < urls.length; i++) {
getUsageForUrl(urls[i].url, usageHandler);
}
}
// Enable clear() and test()
let testingEnabled =
SpecialPowers.getBoolPref("dom.quotaManager.testing");
SpecialPowers.setBoolPref("dom.quotaManager.testing", true)
// Calibration
let request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
getUsageForUrl(lastUrl, grabUsageAndContinueHandler);
dbSize = yield undefined;
setLimit(lastIndex * dbSize / 1024);
quotaManager.clear();
// Stage 1
for (let i = 0; i < lastIndex; i++) {
let data = urls[i];
request = indexedDB.openForPrincipal(getPrincipal(data.url), name,
{ storage: "temporary" });
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "upgradeneeded", "Got correct event type");
let db = event.target.result;
db.createObjectStore("foo", { });
event = yield undefined;
is(event.type, "success", "Got correct event type");
databases.push(event.target.result);
}
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.addEventListener("error", new ExpectError("QuotaExceededError"));
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
checkUsage(1);
yield undefined;
// Stage 2
for (let i = 1; i < urls.length; i++) {
databases[i] = null;
scheduleGC();
yield undefined;
// The origin access time is set to the current system time when the first
// database for an origin is registered or the last one is unregistered.
// The registration happens when the database object is being created and
// the unregistration when it is unlinked/garbage collected.
// Some older windows systems have the system time limited to a maximum
// resolution of 10 or 15 milliseconds, so without a pause here we would
// end up with origins with the same access time which would cause random
// failures.
setTimeout(function() { testGenerator.next(); }, 20);
yield undefined;
}
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "upgradeneeded", "Got correct event type");
let db = event.target.result;
db.createObjectStore("foo", { });
event = yield undefined;
is(event.type, "success", "Got correct event type");
checkUsage(2);
yield undefined;
// Stage 3
setLimit(14 * dbSize / 1024);
quotaManager.reset();
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Got correct event type");
let db = event.target.result;
checkUsage(3);
yield undefined;
// Stage 4
let trans = db.transaction(["foo"], "readwrite");
let blob = Blob(["bar"]);
request = trans.objectStore("foo").add(blob, 42);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
trans.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
checkUsage(4);
yield undefined;
// Cleanup
setLimit();
quotaManager.reset();
SpecialPowers.setBoolPref("dom.quotaManager.testing", testingEnabled);
finishTest();
yield undefined;
}