diff options
Diffstat (limited to 'dom/cache/test/mochitest/test_cache_updateUsage.html')
-rw-r--r-- | dom/cache/test/mochitest/test_cache_updateUsage.html | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/dom/cache/test/mochitest/test_cache_updateUsage.html b/dom/cache/test/mochitest/test_cache_updateUsage.html new file mode 100644 index 0000000000..5abc080f14 --- /dev/null +++ b/dom/cache/test/mochitest/test_cache_updateUsage.html @@ -0,0 +1,189 @@ +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <title>Test Cache update its usage to QuotaManager</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="large_url_list.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script class="testbody" type="text/javascript"> +function setupTestIframe() { + return new Promise(function(resolve) { + var iframe = document.createElement("iframe"); + iframe.src = "empty.html"; + iframe.onload = function() { + window.caches = iframe.contentWindow.caches; + resolve(); + }; + document.body.appendChild(iframe); + }); +} + +function clearStorage() { + return new Promise(function(resolve, reject) { + var qms = SpecialPowers.Services.qms; + var principal = SpecialPowers.wrap(document).nodePrincipal; + var request = qms.clearStoragesForPrincipal(principal); + var cb = SpecialPowers.wrapCallback(resolve); + request.callback = cb; + }); +} + +function resetStorage() { + return new Promise(function(resolve, reject) { + var qms = SpecialPowers.Services.qms; + var request = qms.reset(); + var cb = SpecialPowers.wrapCallback(resolve); + request.callback = cb; + }); +} + +function getStorageUsage(fromMemory) { + return new Promise(function(resolve, reject) { + var qms = SpecialPowers.Services.qms; + var principal = SpecialPowers.wrap(document).nodePrincipal; + var cb = SpecialPowers.wrapCallback(function(request) { + var result = request.result; + resolve(result.usage); + }); + + // Actually, the flag is used to distingulish getting group usage and origin + // usage, but we utilize this to get usage from in-memory and the disk. + // Default value for "fromMemory" is false. + qms.getUsageForPrincipal(principal, cb, !!fromMemory); + }); +} + +async function verifyUsage() { + // Although it returns group usage when passing true, it calculate the usage + // from tracking usage object (in-memory object) in QuotaManager. + let memoryUsage = await getStorageUsage(/* fromMemory */ true); + // This will returns the origin usage by re-calculating usage from directory. + let diskUsage = await getStorageUsage(/* fromMemory */ false); + + is(memoryUsage, diskUsage, + "In-memory usage and disk usage should be the same."); + return memoryUsage; +} + +async function waitForIOToComplete(cache, request) { + info("Wait for IO complete."); + // The following lines ensure we've deleted orphaned body. + // First, wait for cache operation delete the orphaned body. + await cache.match(request); + + // Finally, wait for -wal file finish its job. + return resetStorage(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({ + "set": [["dom.caches.enabled", true], + ["dom.caches.testing.enabled", true], + ["dom.quotaManager.testing", true], + ["privacy.partition.always_partition_third_party_non_cookie_storage", false]], +}, async function() { + // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5) + // Acquire storage access permission here so that the Cache API is avaialable + SpecialPowers.wrap(document).notifyUserGestureActivation(); + await SpecialPowers.addPermission("storageAccessAPI", true, window.location.href); + await SpecialPowers.wrap(document).requestStorageAccess(); + + const name = "cacheUpdateUsage"; + const url = "test_cache_add.js"; + const other_url = "test_cache_put.js"; + + // This test mainly ensure DOM Cache updates its usage to QuotaManager when + // executing an operation which creates/deletes files. To do this, we verify + // usage by calling getUsageFromPrincipal twice with different flag(aGroup). + // The reason is we get group usage by collecting in-memory data, and getting + // origin usage by collecting storage usage from files. + + await setupTestIframe(); + + info("Stage 1: Clean storage."); + await clearStorage(); + await verifyUsage(); + + info("Stage 2: Verify CacheStorage."); + info("Stage 2.1: Verify caches.open."); + await caches.open(name); + await verifyUsage(); + + info("Stage 2.2: Verify caches.delete."); + var deleted = await caches.delete(name); + ok(deleted, "Cache storage should be deleted"); + // Reference from test_cache_orphanced_body.html. It ensures that all + // the runnables have been flushed through the threads. + await caches.has(name); + await resetStorage(); + await verifyUsage(); + + info("Stage 3: Verify Cache."); + let cache = await caches.open(name); + info("Stage 3.1: Verify cache.addAll."); + await cache.addAll([url, other_url]); + await verifyUsage(); + info("Stage 3.1.1: Delete all cached requests."); + await cache.delete(url); + await cache.delete(other_url); + await waitForIOToComplete(cache, other_url); + let emptyUsage1 = await verifyUsage(); + + info("Stage 3.2: Verify cache.add."); + cache = await caches.open(name); + await cache.add(url); + await verifyUsage(); + info("Stage 3.2.1: Delete cache."); + await cache.delete(url); + await waitForIOToComplete(cache, url); + let emptyUsage2 = await verifyUsage(); + + info("Stage 3.3: Verify cache.put."); + cache = await caches.open(name); + let response = await fetch(other_url); + await cache.put(other_url, response); + await verifyUsage(); + info("Stage 3.3.1: Delete cache."); + await cache.delete(other_url); + await waitForIOToComplete(cache, other_url); + let emptyUsage3 = await verifyUsage(); + + // Adding same requests twice will make Cache create morgue file twice, and + // then delete the previous one. + info("Stage 4: Add same request twice to make removing a morgue file."); + cache = await caches.open(name); + info("Stage 4.1: First cache.add."); + await cache.add(url); + await verifyUsage(); + + info("Stage 4.2: Second cache.add."); + await cache.add(url); + + // Since we trigger the action to delete orphaned body, we need to wait for + // the action is done. + await waitForIOToComplete(cache, url); + await verifyUsage(); + cache = await caches.open(name); + info("Stage 4.2.1: cache.delete."); + await cache.delete(url); + await waitForIOToComplete(cache, url); + let emptyUsage4 = await verifyUsage(); + + info("Stage 5: Clean caches."); + await caches.delete(name); + + info("Stage 6: Final Check."); + ok(emptyUsage1 == emptyUsage2 && + emptyUsage1 == emptyUsage3 && + emptyUsage1 == emptyUsage4, + "Empty usages should be the same"); + + await SimpleTest.finish(); +}); +</script> +</body> +</html> |