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