test_cache_orphaned_cache.html (5047B)
1 <!-- Any copyright is dedicated to the Public Domain. 2 - http://creativecommons.org/publicdomain/zero/1.0/ --> 3 <!DOCTYPE HTML> 4 <html> 5 <head> 6 <title>Test Cache with QuotaManager Restart</title> 7 <script src="/tests/SimpleTest/SimpleTest.js"></script> 8 <script type="text/javascript" src="large_url_list.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 10 </head> 11 <body> 12 <script class="testbody" type="text/javascript"> 13 function setupTestIframe() { 14 return new Promise(function(resolve) { 15 var iframe = document.createElement("iframe"); 16 iframe.src = "empty.html"; 17 iframe.onload = function() { 18 window.caches = iframe.contentWindow.caches; 19 resolve(); 20 }; 21 document.body.appendChild(iframe); 22 }); 23 } 24 25 function clearStorage() { 26 return new Promise(function(resolve) { 27 var qms = SpecialPowers.Services.qms; 28 var principal = SpecialPowers.wrap(document).nodePrincipal; 29 var request = qms.clearStoragesForPrincipal(principal); 30 var cb = SpecialPowers.wrapCallback(resolve); 31 request.callback = cb; 32 }); 33 } 34 35 function storageUsage() { 36 return new Promise(function(resolve) { 37 var qms = SpecialPowers.Services.qms; 38 var principal = SpecialPowers.wrap(document).nodePrincipal; 39 var cb = SpecialPowers.wrapCallback(function(request) { 40 var result = request.result; 41 resolve(result.usage); 42 }); 43 qms.getUsageForPrincipal(principal, cb); 44 }); 45 } 46 47 function resetStorage() { 48 return new Promise(function(resolve) { 49 var qms = SpecialPowers.Services.qms; 50 var principal = SpecialPowers.wrap(document).nodePrincipal; 51 var request = qms.resetStoragesForPrincipal(principal); 52 var cb = SpecialPowers.wrapCallback(resolve); 53 request.callback = cb; 54 }); 55 } 56 57 function gc() { 58 return new Promise(function(resolve) { 59 SpecialPowers.exactGC(resolve); 60 }); 61 } 62 63 SimpleTest.waitForExplicitFinish(); 64 SpecialPowers.pushPrefEnv({ 65 "set": [["dom.caches.enabled", true], 66 ["dom.caches.testing.enabled", true], 67 ["dom.quotaManager.testing", true]], 68 }, function() { 69 var name = "toBeOrphaned"; 70 var cache = null; 71 var initialUsage = 0; 72 var fullUsage = 0; 73 var endUsage = 0; 74 var url = "test_cache_add.js"; 75 76 // start from a fresh origin directory so other tests do not influence our 77 // results 78 setupTestIframe().then(function() { 79 return clearStorage(); 80 }).then(function() { 81 return storageUsage(); 82 }).then(function(usage) { 83 is(0, usage, "disk usage should be zero to start"); 84 }) 85 86 // Initialize and populate an initial cache to get the base sqlite pages 87 // and directory structure allocated. 88 .then(function() { 89 return caches.open(name); 90 }).then(function(c) { 91 return c.add(url); 92 }).then(function() { 93 return gc(); 94 }).then(function() { 95 return caches.delete(name); 96 }).then(function(deleted) { 97 ok(deleted, "cache should be deleted"); 98 99 // This is a bit superfluous, but its necessary to make sure the Cache is 100 // fully deleted before we proceed. The deletion actually takes place in 101 // two async steps. We don't want to resetStorage() until the second step 102 // has taken place. This extra Cache operation ensure that all the 103 // runnables have been flushed through the threads, etc. 104 return caches.has(name); 105 }) 106 107 // Now measure initial disk usage 108 .then(function() { 109 return resetStorage(); 110 }).then(function() { 111 return storageUsage(); 112 }).then(function(usage) { 113 initialUsage = usage; 114 }) 115 116 // Now re-populate the Cache object 117 .then(function() { 118 return caches.open(name); 119 }).then(function(c) { 120 cache = c; 121 return cache.add(url); 122 }).then(function() { 123 return caches.delete(name); 124 }).then(function(deleted) { 125 ok(deleted, "cache should be deleted"); 126 }) 127 128 // Reset the quota dir while the cache is deleted, but still referenced 129 // from the DOM. This forces it to be orphaned. 130 .then(function() { 131 return resetStorage(); 132 }).then(function() { 133 return storageUsage(); 134 }).then(function(usage) { 135 fullUsage = usage; 136 ok(fullUsage > initialUsage, "disk usage should have grown"); 137 }) 138 139 // Now perform a new Cache operation that will reopen the origin. This 140 // should clean up the orphaned Cache data. 141 .then(function() { 142 return caches.has(name); 143 }).then(function(result) { 144 ok(!result, "cache should not exist in storage"); 145 }) 146 147 // Finally, verify orphaned data was cleaned up by re-checking the disk 148 // usage. Reset the storage first to ensure any WAL transaction files 149 // are flushed before measuring the usage. 150 .then(function() { 151 return resetStorage(); 152 }).then(function() { 153 return storageUsage(); 154 }).then(function(usage) { 155 endUsage = usage; 156 dump("### ### initial:" + initialUsage + ", full:" + fullUsage + 157 ", end:" + endUsage + "\n"); 158 ok(endUsage < fullUsage, "disk usage should have shrank"); 159 is(endUsage, initialUsage, "disk usage should return to original"); 160 SimpleTest.finish(); 161 }); 162 }); 163 </script> 164 </body> 165 </html>