netwerk/test/unit/test_pinned_app_cache.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: Javasript; indent-tab-mode: nil; js-indent-level: 2 -*- */
michael@0 2 /*
michael@0 3 * This testcase performs 3 requests against the offline cache. They
michael@0 4 * are
michael@0 5 *
michael@0 6 * - start_cache_nonpinned_app1()
michael@0 7 *
michael@0 8 * - Request nsOfflineCacheService to skip pages (4) of app1 on
michael@0 9 * the cache storage.
michael@0 10 *
michael@0 11 * - The offline cache storage is empty at this monent.
michael@0 12 *
michael@0 13 * - start_cache_nonpinned_app2_for_partial()
michael@0 14 *
michael@0 15 * - Request nsOfflineCacheService to skip pages of app2 on the
michael@0 16 * cache storage.
michael@0 17 *
michael@0 18 * - The offline cache storage has only enough space for one more
michael@0 19 * additional page. Only first of pages is really in the cache.
michael@0 20 *
michael@0 21 * - start_cache_pinned_app2_for_success()
michael@0 22 *
michael@0 23 * - Request nsOfflineCacheService to skip pages of app2 on the
michael@0 24 * cache storage.
michael@0 25 *
michael@0 26 * - The offline cache storage has only enough space for one
michael@0 27 * additional page. But, this is a pinned request,
michael@0 28 * nsOfflineCacheService will make more space for this request
michael@0 29 * by discarding app1 (non-pinned)
michael@0 30 *
michael@0 31 */
michael@0 32
michael@0 33 Cu.import("resource://testing-common/httpd.js");
michael@0 34
michael@0 35 // const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
michael@0 36
michael@0 37 Cu.import("resource://gre/modules/Services.jsm");
michael@0 38
michael@0 39 const kNS_OFFLINECACHEUPDATESERVICE_CONTRACTID =
michael@0 40 "@mozilla.org/offlinecacheupdate-service;1";
michael@0 41
michael@0 42 const kManifest1 = "CACHE MANIFEST\n" +
michael@0 43 "/pages/foo1\n" +
michael@0 44 "/pages/foo2\n" +
michael@0 45 "/pages/foo3\n" +
michael@0 46 "/pages/foo4\n";
michael@0 47 const kManifest2 = "CACHE MANIFEST\n" +
michael@0 48 "/pages/foo5\n" +
michael@0 49 "/pages/foo6\n" +
michael@0 50 "/pages/foo7\n" +
michael@0 51 "/pages/foo8\n";
michael@0 52
michael@0 53 const kDataFileSize = 1024; // file size for each content page
michael@0 54 const kCacheSize = kDataFileSize * 5; // total space for offline cache storage
michael@0 55
michael@0 56 XPCOMUtils.defineLazyGetter(this, "kHttpLocation", function() {
michael@0 57 return "http://localhost:" + httpServer.identity.primaryPort + "/";
michael@0 58 });
michael@0 59
michael@0 60 XPCOMUtils.defineLazyGetter(this, "kHttpLocation_ip", function() {
michael@0 61 return "http://127.0.0.1:" + httpServer.identity.primaryPort + "/";
michael@0 62 });
michael@0 63
michael@0 64 function manifest1_handler(metadata, response) {
michael@0 65 do_print("manifest1\n");
michael@0 66 response.setHeader("content-type", "text/cache-manifest");
michael@0 67
michael@0 68 response.write(kManifest1);
michael@0 69 }
michael@0 70
michael@0 71 function manifest2_handler(metadata, response) {
michael@0 72 do_print("manifest2\n");
michael@0 73 response.setHeader("content-type", "text/cache-manifest");
michael@0 74
michael@0 75 response.write(kManifest2);
michael@0 76 }
michael@0 77
michael@0 78 function app_handler(metadata, response) {
michael@0 79 do_print("app_handler\n");
michael@0 80 response.setHeader("content-type", "text/html");
michael@0 81
michael@0 82 response.write("<html></html>");
michael@0 83 }
michael@0 84
michael@0 85 function datafile_handler(metadata, response) {
michael@0 86 do_print("datafile_handler\n");
michael@0 87 let data = "";
michael@0 88
michael@0 89 while(data.length < kDataFileSize) {
michael@0 90 data = data + Math.random().toString(36).substring(2, 15);
michael@0 91 }
michael@0 92
michael@0 93 response.setHeader("content-type", "text/plain");
michael@0 94 response.write(data.substring(0, kDataFileSize));
michael@0 95 }
michael@0 96
michael@0 97 var httpServer;
michael@0 98
michael@0 99 function init_profile() {
michael@0 100 var ps = Cc["@mozilla.org/preferences-service;1"]
michael@0 101 .getService(Ci.nsIPrefBranch);
michael@0 102 dump(ps.getBoolPref("browser.cache.offline.enable"));
michael@0 103 ps.setBoolPref("browser.cache.offline.enable", true);
michael@0 104 ps.setComplexValue("browser.cache.offline.parent_directory",
michael@0 105 Ci.nsILocalFile, do_get_profile());
michael@0 106 }
michael@0 107
michael@0 108 function init_http_server() {
michael@0 109 httpServer = new HttpServer();
michael@0 110 httpServer.registerPathHandler("/app1", app_handler);
michael@0 111 httpServer.registerPathHandler("/app2", app_handler);
michael@0 112 httpServer.registerPathHandler("/app1.appcache", manifest1_handler);
michael@0 113 httpServer.registerPathHandler("/app2.appcache", manifest2_handler);
michael@0 114 for (i = 1; i <= 8; i++) {
michael@0 115 httpServer.registerPathHandler("/pages/foo" + i, datafile_handler);
michael@0 116 }
michael@0 117 httpServer.start(-1);
michael@0 118 }
michael@0 119
michael@0 120 function init_cache_capacity() {
michael@0 121 let prefs = Cc["@mozilla.org/preferences-service;1"]
michael@0 122 .getService(Components.interfaces.nsIPrefBranch);
michael@0 123 prefs.setIntPref("browser.cache.offline.capacity", kCacheSize / 1024);
michael@0 124 }
michael@0 125
michael@0 126 function clean_app_cache() {
michael@0 127 evict_cache_entries("appcache");
michael@0 128 }
michael@0 129
michael@0 130 function do_app_cache(manifestURL, pageURL, pinned) {
michael@0 131 let update_service = Cc[kNS_OFFLINECACHEUPDATESERVICE_CONTRACTID].
michael@0 132 getService(Ci.nsIOfflineCacheUpdateService);
michael@0 133
michael@0 134 Services.perms.add(manifestURL,
michael@0 135 "pin-app",
michael@0 136 pinned ?
michael@0 137 Ci.nsIPermissionManager.ALLOW_ACTION :
michael@0 138 Ci.nsIPermissionManager.DENY_ACTION);
michael@0 139
michael@0 140 let update =
michael@0 141 update_service.scheduleUpdate(manifestURL,
michael@0 142 pageURL,
michael@0 143 null); /* no window */
michael@0 144
michael@0 145 return update;
michael@0 146 }
michael@0 147
michael@0 148 function watch_update(update, stateChangeHandler, cacheAvailHandler) {
michael@0 149 let observer = {
michael@0 150 QueryInterface: function QueryInterface(iftype) {
michael@0 151 return this;
michael@0 152 },
michael@0 153
michael@0 154 updateStateChanged: stateChangeHandler,
michael@0 155 applicationCacheAvailable: cacheAvailHandler
michael@0 156 };
michael@0 157 update.addObserver(observer, false);
michael@0 158
michael@0 159 return update;
michael@0 160 }
michael@0 161
michael@0 162 function start_and_watch_app_cache(manifestURL,
michael@0 163 pageURL,
michael@0 164 pinned,
michael@0 165 stateChangeHandler,
michael@0 166 cacheAvailHandler) {
michael@0 167 let ioService = Cc["@mozilla.org/network/io-service;1"].
michael@0 168 getService(Ci.nsIIOService);
michael@0 169 let update = do_app_cache(ioService.newURI(manifestURL, null, null),
michael@0 170 ioService.newURI(pageURL, null, null),
michael@0 171 pinned);
michael@0 172 watch_update(update, stateChangeHandler, cacheAvailHandler);
michael@0 173 return update;
michael@0 174 }
michael@0 175
michael@0 176 const {STATE_FINISHED: STATE_FINISHED,
michael@0 177 STATE_CHECKING: STATE_CHECKING,
michael@0 178 STATE_ERROR: STATE_ERROR } = Ci.nsIOfflineCacheUpdateObserver;
michael@0 179
michael@0 180 /*
michael@0 181 * Start caching app1 as a non-pinned app.
michael@0 182 */
michael@0 183 function start_cache_nonpinned_app() {
michael@0 184 do_print("Start non-pinned App1");
michael@0 185 start_and_watch_app_cache(kHttpLocation + "app1.appcache",
michael@0 186 kHttpLocation + "app1",
michael@0 187 false,
michael@0 188 function (update, state) {
michael@0 189 switch(state) {
michael@0 190 case STATE_FINISHED:
michael@0 191 start_cache_nonpinned_app2_for_partial();
michael@0 192 break;
michael@0 193
michael@0 194 case STATE_ERROR:
michael@0 195 do_throw("App1 cache state = " + state);
michael@0 196 break;
michael@0 197 }
michael@0 198 },
michael@0 199 function (appcahe) {
michael@0 200 do_print("app1 avail " + appcache + "\n");
michael@0 201 });
michael@0 202 }
michael@0 203
michael@0 204 /*
michael@0 205 * Start caching app2 as a non-pinned app.
michael@0 206 *
michael@0 207 * This cache request is supposed to be saved partially in the cache
michael@0 208 * storage for running out of the cache storage. The offline cache
michael@0 209 * storage can hold 5 files at most. (kDataFileSize bytes for each
michael@0 210 * file)
michael@0 211 */
michael@0 212 function start_cache_nonpinned_app2_for_partial() {
michael@0 213 let error_count = [0];
michael@0 214 do_print("Start non-pinned App2 for partial\n");
michael@0 215 start_and_watch_app_cache(kHttpLocation_ip + "app2.appcache",
michael@0 216 kHttpLocation_ip + "app2",
michael@0 217 false,
michael@0 218 function (update, state) {
michael@0 219 switch(state) {
michael@0 220 case STATE_FINISHED:
michael@0 221 start_cache_pinned_app2_for_success();
michael@0 222 break;
michael@0 223
michael@0 224 case STATE_ERROR:
michael@0 225 do_throw("App2 cache state = " + state);
michael@0 226 break;
michael@0 227 }
michael@0 228 },
michael@0 229 function (appcahe) {
michael@0 230 });
michael@0 231 }
michael@0 232
michael@0 233 /*
michael@0 234 * Start caching app2 as a pinned app.
michael@0 235 *
michael@0 236 * This request use IP address (127.0.0.1) as the host name instead of
michael@0 237 * the one used by app1. Because, app1 is also pinned when app2 is
michael@0 238 * pinned if they have the same host name (localhost).
michael@0 239 */
michael@0 240 function start_cache_pinned_app2_for_success() {
michael@0 241 let error_count = [0];
michael@0 242 do_print("Start pinned App2 for success\n");
michael@0 243 start_and_watch_app_cache(kHttpLocation_ip + "app2.appcache",
michael@0 244 kHttpLocation_ip + "app2",
michael@0 245 true,
michael@0 246 function (update, state) {
michael@0 247 switch(state) {
michael@0 248 case STATE_FINISHED:
michael@0 249 do_check_true(error_count[0] == 0,
michael@0 250 "Do not discard app1?");
michael@0 251 httpServer.stop(do_test_finished);
michael@0 252 break;
michael@0 253
michael@0 254 case STATE_ERROR:
michael@0 255 do_print("STATE_ERROR\n");
michael@0 256 error_count[0]++;
michael@0 257 break;
michael@0 258 }
michael@0 259 },
michael@0 260 function (appcahe) {
michael@0 261 do_print("app2 avail " + appcache + "\n");
michael@0 262 });
michael@0 263 }
michael@0 264
michael@0 265 function run_test() {
michael@0 266 if (typeof _XPCSHELL_PROCESS == "undefined" ||
michael@0 267 _XPCSHELL_PROCESS != "child") {
michael@0 268 init_profile();
michael@0 269 init_cache_capacity();
michael@0 270 clean_app_cache();
michael@0 271 }
michael@0 272
michael@0 273 init_http_server();
michael@0 274 start_cache_nonpinned_app();
michael@0 275 do_test_pending();
michael@0 276 }

mercurial