1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/unit/test_offlinecache_custom-directory.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,146 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/** 1.9 + * This test executes nsIOfflineCacheUpdateService.scheduleAppUpdate API 1.10 + * 1. preloads an app with a manifest to a custom sudir in the profile (for simplicity) 1.11 + * 2. observes progress and completion of the update 1.12 + * 3. checks presence of index.sql and files in the expected location 1.13 + */ 1.14 + 1.15 +Cu.import("resource://testing-common/httpd.js"); 1.16 + 1.17 +var httpServer = null; 1.18 +var cacheUpdateObserver = null; 1.19 + 1.20 +function make_channel(url, callback, ctx) { 1.21 + var ios = Cc["@mozilla.org/network/io-service;1"]. 1.22 + getService(Ci.nsIIOService); 1.23 + return ios.newChannel(url, "", null); 1.24 +} 1.25 + 1.26 +function make_uri(url) { 1.27 + var ios = Cc["@mozilla.org/network/io-service;1"]. 1.28 + getService(Ci.nsIIOService); 1.29 + return ios.newURI(url, null, null); 1.30 +} 1.31 + 1.32 +// start the test with loading this master entry referencing the manifest 1.33 +function masterEntryHandler(metadata, response) 1.34 +{ 1.35 + var masterEntryContent = "<html manifest='/manifest'></html>"; 1.36 + response.setHeader("Content-Type", "text/html"); 1.37 + response.bodyOutputStream.write(masterEntryContent, masterEntryContent.length); 1.38 +} 1.39 + 1.40 +// manifest defines fallback namespace from any /redirect path to /content 1.41 +function manifestHandler(metadata, response) 1.42 +{ 1.43 + var manifestContent = "CACHE MANIFEST\n"; 1.44 + response.setHeader("Content-Type", "text/cache-manifest"); 1.45 + response.bodyOutputStream.write(manifestContent, manifestContent.length); 1.46 +} 1.47 + 1.48 +// finally check we got fallback content 1.49 +function finish_test(customDir) 1.50 +{ 1.51 + var offlineCacheDir = customDir.clone(); 1.52 + offlineCacheDir.append("OfflineCache"); 1.53 + 1.54 + var indexSqlFile = offlineCacheDir.clone(); 1.55 + indexSqlFile.append('index.sqlite'); 1.56 + do_check_eq(indexSqlFile.exists(), true); 1.57 + 1.58 + var file1 = offlineCacheDir.clone(); 1.59 + file1.append("2"); 1.60 + file1.append("E"); 1.61 + file1.append("2C99DE6E7289A5-0"); 1.62 + do_check_eq(file1.exists(), true); 1.63 + 1.64 + var file2 = offlineCacheDir.clone(); 1.65 + file2.append("8"); 1.66 + file2.append("6"); 1.67 + file2.append("0B457F75198B29-0"); 1.68 + do_check_eq(file2.exists(), true); 1.69 + 1.70 + // This must not throw an exception. After the update has finished 1.71 + // the index file can be freely removed. This way we check this process 1.72 + // is no longer keeping the file open. Check like this will probably 1.73 + // work only Windows systems. 1.74 + 1.75 + // This test could potentially randomaly fail when we start closing 1.76 + // the offline cache database off the main thread. Tries in a loop 1.77 + // may be a solution then. 1.78 + try { 1.79 + indexSqlFile.remove(false); 1.80 + do_check_true(true); 1.81 + } 1.82 + catch (ex) { 1.83 + do_throw("Could not remove the sqlite.index file, we still keep it open \n" + ex + "\n"); 1.84 + } 1.85 + 1.86 + httpServer.stop(do_test_finished); 1.87 +} 1.88 + 1.89 +function run_test() 1.90 +{ 1.91 + httpServer = new HttpServer(); 1.92 + httpServer.registerPathHandler("/masterEntry", masterEntryHandler); 1.93 + httpServer.registerPathHandler("/manifest", manifestHandler); 1.94 + httpServer.start(4444); 1.95 + 1.96 + var profileDir = do_get_profile(); 1.97 + var customDir = profileDir.clone(); 1.98 + customDir.append("customOfflineCacheDir" + Math.random()); 1.99 + 1.100 + var pm = Cc["@mozilla.org/permissionmanager;1"] 1.101 + .getService(Ci.nsIPermissionManager); 1.102 + var uri = make_uri("http://localhost:4444"); 1.103 + var principal = Cc["@mozilla.org/scriptsecuritymanager;1"] 1.104 + .getService(Ci.nsIScriptSecurityManager) 1.105 + .getNoAppCodebasePrincipal(uri); 1.106 + 1.107 + if (pm.testPermissionFromPrincipal(principal, "offline-app") != 0) { 1.108 + dump("Previous test failed to clear offline-app permission! Expect failures.\n"); 1.109 + } 1.110 + pm.addFromPrincipal(principal, "offline-app", Ci.nsIPermissionManager.ALLOW_ACTION); 1.111 + 1.112 + var ps = Cc["@mozilla.org/preferences-service;1"] 1.113 + .getService(Ci.nsIPrefBranch); 1.114 + ps.setBoolPref("browser.cache.offline.enable", true); 1.115 + // Set this pref to mimic the default browser behavior. 1.116 + ps.setComplexValue("browser.cache.offline.parent_directory", Ci.nsILocalFile, profileDir); 1.117 + 1.118 + var us = Cc["@mozilla.org/offlinecacheupdate-service;1"]. 1.119 + getService(Ci.nsIOfflineCacheUpdateService); 1.120 + var update = us.scheduleAppUpdate( 1.121 + make_uri("http://localhost:4444/manifest"), 1.122 + make_uri("http://localhost:4444/masterEntry"), 1.123 + 0 /* no AppID */, false /* not in browser*/, 1.124 + customDir); 1.125 + 1.126 + var expectedStates = [ 1.127 + Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING, 1.128 + Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED, 1.129 + Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS, 1.130 + Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMCOMPLETED, 1.131 + Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED 1.132 + ]; 1.133 + 1.134 + update.addObserver({ 1.135 + updateStateChanged: function(update, state) 1.136 + { 1.137 + do_check_eq(state, expectedStates.shift()); 1.138 + 1.139 + if (state == Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED) 1.140 + finish_test(customDir); 1.141 + }, 1.142 + 1.143 + applicationCacheAvailable: function(appCache) 1.144 + { 1.145 + } 1.146 + }, false); 1.147 + 1.148 + do_test_pending(); 1.149 +}