1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/indexedDB/test/unit/test_temporary_storage.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,225 @@ 1.4 +/** 1.5 + * Any copyright is dedicated to the Public Domain. 1.6 + * http://creativecommons.org/publicdomain/zero/1.0/ 1.7 + */ 1.8 + 1.9 +var testGenerator = testSteps(); 1.10 + 1.11 +function testSteps() 1.12 +{ 1.13 + const name = this.window ? window.location.pathname : "Splendid Test"; 1.14 + 1.15 + const urls = [ 1.16 + { url: "http://www.alpha.com", flags: [true, true, false, false] }, 1.17 + { url: "http://www.beta.com", flags: [true, false, false, false] }, 1.18 + { url: "http://www.gamma.com", flags: [true, true, false, false] }, 1.19 + { url: "http://www.delta.com", flags: [true, true, false, false] }, 1.20 + { url: "http://www.epsilon.com", flags: [true, true, false, false] }, 1.21 + { url: "http://www2.alpha.com", flags: [true, true, false, false] }, 1.22 + { url: "http://www2.beta.com", flags: [true, true, false, false] }, 1.23 + { url: "http://www2.gamma.com", flags: [true, true, true, false] }, 1.24 + { url: "http://www2.delta.com", flags: [true, true, true, true] }, 1.25 + { url: "http://www2.epsilon.com", flags: [true, true, true, true] }, 1.26 + { url: "http://joe.blog.alpha.com", flags: [true, true, true, true] }, 1.27 + { url: "http://joe.blog.beta.com", flags: [true, true, true, true] }, 1.28 + { url: "http://joe.blog.gamma.com", flags: [true, true, true, true] }, 1.29 + { url: "http://joe.blog.delta.com", flags: [true, true, true, true] }, 1.30 + { url: "http://joe.blog.epsilon.com", flags: [true, true, true, true] }, 1.31 + { url: "http://www.rudolf.org", flags: [true, true, true, true] }, 1.32 + { url: "http://www.pauline.org", flags: [true, true, true, true] }, 1.33 + { url: "http://www.marie.org", flags: [true, true, true, true] }, 1.34 + { url: "http://www.john.org", flags: [true, true, true, true] }, 1.35 + { url: "http://www.ema.org", flags: [true, true, true, true] }, 1.36 + { url: "http://www.trigger.com", flags: [false, true, true, true] } 1.37 + ]; 1.38 + const lastIndex = urls.length - 1; 1.39 + const lastUrl = urls[lastIndex].url; 1.40 + 1.41 + let quotaManager = 1.42 + Components.classes["@mozilla.org/dom/quota/manager;1"] 1.43 + .getService(Components.interfaces.nsIQuotaManager); 1.44 + 1.45 + let ioService = Components.classes["@mozilla.org/network/io-service;1"] 1.46 + .getService(Components.interfaces.nsIIOService); 1.47 + 1.48 + let dbSize = 0; 1.49 + 1.50 + let databases = []; 1.51 + 1.52 + function setLimit(limit) { 1.53 + if (limit) { 1.54 + SpecialPowers.setIntPref("dom.quotaManager.temporaryStorage.fixedLimit", 1.55 + limit); 1.56 + return; 1.57 + } 1.58 + SpecialPowers.clearUserPref("dom.quotaManager.temporaryStorage.fixedLimit"); 1.59 + } 1.60 + 1.61 + function getPrincipal(url) { 1.62 + let uri = ioService.newURI(url, null, null); 1.63 + return Components.classes["@mozilla.org/scriptsecuritymanager;1"] 1.64 + .getService(Components.interfaces.nsIScriptSecurityManager) 1.65 + .getNoAppCodebasePrincipal(uri); 1.66 + } 1.67 + 1.68 + function getUsageForUrl(url, usageHandler) { 1.69 + let uri = ioService.newURI(url, null, null); 1.70 + function callback(uri, usage, fileUsage) { 1.71 + usageHandler(usage, fileUsage); 1.72 + } 1.73 + quotaManager.getUsageForURI(uri, callback); 1.74 + } 1.75 + 1.76 + function grabUsageAndContinueHandler(usage, fileUsage) { 1.77 + testGenerator.send(usage); 1.78 + } 1.79 + 1.80 + function checkUsage(stageIndex) { 1.81 + let handledIndex = 0; 1.82 + 1.83 + function usageHandler(usage, fileUsage) { 1.84 + if (urls[handledIndex].flags[stageIndex - 1]) { 1.85 + ok(usage > 0, "Correct usage"); 1.86 + } 1.87 + else { 1.88 + ok(usage == 0, "Correct usage"); 1.89 + } 1.90 + if (++handledIndex == urls.length) { 1.91 + continueToNextStep(); 1.92 + } 1.93 + } 1.94 + 1.95 + for (let i = 0; i < urls.length; i++) { 1.96 + getUsageForUrl(urls[i].url, usageHandler); 1.97 + } 1.98 + } 1.99 + 1.100 + // Enable clear() and test() 1.101 + let testingEnabled = 1.102 + SpecialPowers.getBoolPref("dom.quotaManager.testing"); 1.103 + SpecialPowers.setBoolPref("dom.quotaManager.testing", true) 1.104 + 1.105 + // Calibration 1.106 + let request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, 1.107 + { storage: "temporary" }); 1.108 + request.onerror = errorHandler; 1.109 + request.onsuccess = grabEventAndContinueHandler; 1.110 + let event = yield undefined; 1.111 + 1.112 + getUsageForUrl(lastUrl, grabUsageAndContinueHandler); 1.113 + dbSize = yield undefined; 1.114 + 1.115 + setLimit(lastIndex * dbSize / 1024); 1.116 + quotaManager.clear(); 1.117 + 1.118 + // Stage 1 1.119 + for (let i = 0; i < lastIndex; i++) { 1.120 + let data = urls[i]; 1.121 + 1.122 + request = indexedDB.openForPrincipal(getPrincipal(data.url), name, 1.123 + { storage: "temporary" }); 1.124 + request.onerror = errorHandler; 1.125 + request.onupgradeneeded = grabEventAndContinueHandler; 1.126 + request.onsuccess = grabEventAndContinueHandler; 1.127 + event = yield undefined; 1.128 + 1.129 + is(event.type, "upgradeneeded", "Got correct event type"); 1.130 + 1.131 + let db = event.target.result; 1.132 + db.createObjectStore("foo", { }); 1.133 + 1.134 + event = yield undefined; 1.135 + 1.136 + is(event.type, "success", "Got correct event type"); 1.137 + 1.138 + databases.push(event.target.result); 1.139 + } 1.140 + 1.141 + request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, 1.142 + { storage: "temporary" }); 1.143 + request.addEventListener("error", new ExpectError("QuotaExceededError")); 1.144 + request.onsuccess = unexpectedSuccessHandler; 1.145 + event = yield undefined; 1.146 + 1.147 + checkUsage(1); 1.148 + yield undefined; 1.149 + 1.150 + // Stage 2 1.151 + for (let i = 1; i < urls.length; i++) { 1.152 + databases[i] = null; 1.153 + 1.154 + scheduleGC(); 1.155 + yield undefined; 1.156 + 1.157 + // The origin access time is set to the current system time when the first 1.158 + // database for an origin is registered or the last one is unregistered. 1.159 + // The registration happens when the database object is being created and 1.160 + // the unregistration when it is unlinked/garbage collected. 1.161 + // Some older windows systems have the system time limited to a maximum 1.162 + // resolution of 10 or 15 milliseconds, so without a pause here we would 1.163 + // end up with origins with the same access time which would cause random 1.164 + // failures. 1.165 + setTimeout(function() { testGenerator.next(); }, 20); 1.166 + yield undefined; 1.167 + } 1.168 + 1.169 + request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, 1.170 + { storage: "temporary" }); 1.171 + request.onerror = errorHandler; 1.172 + request.onupgradeneeded = grabEventAndContinueHandler; 1.173 + request.onsuccess = grabEventAndContinueHandler; 1.174 + event = yield undefined; 1.175 + 1.176 + is(event.type, "upgradeneeded", "Got correct event type"); 1.177 + 1.178 + let db = event.target.result; 1.179 + db.createObjectStore("foo", { }); 1.180 + 1.181 + event = yield undefined; 1.182 + 1.183 + is(event.type, "success", "Got correct event type"); 1.184 + 1.185 + checkUsage(2); 1.186 + yield undefined; 1.187 + 1.188 + // Stage 3 1.189 + setLimit(14 * dbSize / 1024); 1.190 + quotaManager.reset(); 1.191 + 1.192 + request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, 1.193 + { storage: "temporary" }); 1.194 + request.onerror = errorHandler; 1.195 + request.onsuccess = grabEventAndContinueHandler; 1.196 + event = yield undefined; 1.197 + 1.198 + is(event.type, "success", "Got correct event type"); 1.199 + 1.200 + let db = event.target.result; 1.201 + 1.202 + checkUsage(3); 1.203 + yield undefined; 1.204 + 1.205 + // Stage 4 1.206 + let trans = db.transaction(["foo"], "readwrite"); 1.207 + 1.208 + let blob = Blob(["bar"]); 1.209 + request = trans.objectStore("foo").add(blob, 42); 1.210 + request.onerror = errorHandler; 1.211 + request.onsuccess = grabEventAndContinueHandler; 1.212 + event = yield undefined; 1.213 + 1.214 + trans.oncomplete = grabEventAndContinueHandler; 1.215 + event = yield undefined; 1.216 + 1.217 + checkUsage(4); 1.218 + yield undefined; 1.219 + 1.220 + // Cleanup 1.221 + setLimit(); 1.222 + quotaManager.reset(); 1.223 + 1.224 + SpecialPowers.setBoolPref("dom.quotaManager.testing", testingEnabled); 1.225 + 1.226 + finishTest(); 1.227 + yield undefined; 1.228 +}