1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is Private Browsing Tests.
16 * The Initial Developer of the Original Code is
18 * Portions created by the Initial Developer are Copyright (C) 2008
19 * the Initial Developer. All Rights Reserved.
22 * Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 const Cc = Components.classes;
39 const Ci = Components.interfaces;
40 const Cr = Components.results;
42 // names for cache devices
43 const kDiskDevice = "disk";
44 const kMemoryDevice = "memory";
45 const kOfflineDevice = "offline";
47 // the name for our cache session
48 const kPrivateBrowsing = "PrivateBrowsing";
51 function get_privatebrowsing_service() {
56 _PBSvc = Cc["@mozilla.org/privatebrowsing;1"].
57 getService(Ci.nsIPrivateBrowsingService);
64 function get_cache_service() {
68 return _CSvc = Cc["@mozilla.org/network/cache-service;1"].
69 getService(Ci.nsICacheService);
72 function setup_profile_dir() {
73 var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
74 getService(Ci.nsIProperties);
75 var leafRandomName = "Cache" + Math.floor(Math.random() * 10000);
76 var dir = dirSvc.get("TmpD", Ci.nsILocalFile);
77 dir.append(leafRandomName);
78 dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0700);
80 getFile: function(prop, persistent) {
81 persistent.value = true;
82 if (prop == "ProfLD" ||
86 throw Cr.NS_ERROR_FAILURE;
88 QueryInterface: function(iid) {
89 if (iid.equals(Ci.nsIDirectoryProvider) ||
90 iid.equals(Ci.nsISupports)) {
93 throw Cr.NS_ERROR_NO_INTERFACE;
96 dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
99 function check_devices_available(devices) {
100 var cs = get_cache_service();
101 var found_devices = [];
104 visitDevice: function (deviceID, deviceInfo) {
105 found_devices.push(deviceID);
108 visitEntry: function (deviceID, entryInfo) {
109 do_throw("nsICacheVisitor.visitEntry should not be called " +
110 "when checking the availability of devices");
114 // get the list of active devices
115 cs.visitEntries(visitor);
117 // see if any of the required devices was missing
118 if (devices.sort().toString() != found_devices.sort().toString()) {
119 do_throw("Expected to find these devices: \"" + devices.sort().toString() +
120 "\", but found these instead: \"" + found_devices.sort().toString() + "\"");
123 // see if any extra devices have been found
124 if (found_devices.length > devices.length) {
125 do_throw("Expected to find these devices: [" + devices.join(", ") +
126 "], but instead got: [" + found_devices.join(", ") + "]");
130 function get_device_entry_count(device) {
131 var cs = get_cache_service();
132 var entry_count = -1;
135 visitDevice: function (deviceID, deviceInfo) {
136 if (device == deviceID)
137 entry_count = deviceInfo.entryCount;
140 visitEntry: function (deviceID, entryInfo) {
141 do_throw("nsICacheVisitor.visitEntry should not be called " +
142 "when checking the availability of devices");
146 // get the device entry count
147 cs.visitEntries(visitor);
152 function store_in_cache(aKey, aContent, aWhere) {
153 var storageFlag, streaming = true;
154 if (aWhere == kDiskDevice)
155 storageFlag = Ci.nsICache.STORE_ON_DISK;
156 else if (aWhere == kOfflineDevice)
157 storageFlag = Ci.nsICache.STORE_OFFLINE;
158 else if (aWhere == kMemoryDevice)
159 storageFlag = Ci.nsICache.STORE_IN_MEMORY;
161 var cache = get_cache_service();
162 var session = cache.createSession(kPrivateBrowsing, storageFlag, streaming);
163 var cacheEntry = session.openCacheEntry(aKey, Ci.nsICache.ACCESS_WRITE, true);
165 var oStream = cacheEntry.openOutputStream(0);
167 var written = oStream.write(aContent, aContent.length);
168 if (written != aContent.length) {
169 do_throw("oStream.write has not written all data!\n" +
170 " Expected: " + aContent.length + "\n" +
171 " Actual: " + written + "\n");
177 function make_input_stream_scriptable(input) {
178 var wrapper = Cc["@mozilla.org/scriptableinputstream;1"].
179 createInstance(Ci.nsIScriptableInputStream);
184 function retrieve_from_cache(aKey, aWhere) {
185 var storageFlag, streaming = true;
186 if (aWhere == kDiskDevice)
187 storageFlag = Ci.nsICache.STORE_ANYWHERE;
188 else if (aWhere == kOfflineDevice)
189 storageFlag = Ci.nsICache.STORE_OFFLINE;
190 else if (aWhere == kMemoryDevice)
191 storageFlag = Ci.nsICache.STORE_ANYWHERE;
193 var cache = get_cache_service();
194 var session = cache.createSession(kPrivateBrowsing, storageFlag, streaming);
196 var cacheEntry = session.openCacheEntry(aKey, Ci.nsICache.ACCESS_READ, true);
198 if (e.result == Cr.NS_ERROR_CACHE_KEY_NOT_FOUND ||
199 e.result == Cr.NS_ERROR_FAILURE)
200 // a key not found error is expected here, so we will simply return null
201 // to let the caller know that no data was retrieved. We also expect
202 // a generic failure error in case of the offline cache.
205 do_throw(e); // throw the textual error description
208 var iStream = make_input_stream_scriptable(cacheEntry.openInputStream(0));
210 var read = iStream.read(iStream.available());
217 function run_test() {
218 var pb = get_privatebrowsing_service();
219 if (pb) { // Private Browsing might not be available
220 var prefBranch = Cc["@mozilla.org/preferences-service;1"].
221 getService(Ci.nsIPrefBranch);
222 prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
224 const kCacheA = "cache-A",
227 kTestContent = "test content";
229 // Simulate a profile dir for xpcshell
232 var cs = get_cache_service();
234 // Start off with an empty cache
235 cs.evictEntries(Ci.nsICache.STORE_ANYWHERE);
237 // Store cache-A, cache-B and cache-C
238 store_in_cache(kCacheA, kTestContent, kMemoryDevice);
239 store_in_cache(kCacheB, kTestContent, kDiskDevice);
240 store_in_cache(kCacheC, kTestContent, kOfflineDevice);
242 // Make sure all three cache devices are available initially
243 check_devices_available([kMemoryDevice, kDiskDevice, kOfflineDevice]);
245 // Check if cache-A, cache-B and cache-C are avilable
246 do_check_eq(retrieve_from_cache(kCacheA, kMemoryDevice), kTestContent);
247 do_check_eq(retrieve_from_cache(kCacheB, kDiskDevice), kTestContent);
248 do_check_eq(retrieve_from_cache(kCacheC, kOfflineDevice), kTestContent);
250 // Enter private browsing mode
251 pb.privateBrowsingEnabled = true;
253 // Make sure none of cache-A, cache-B and cache-C are available
254 do_check_eq(retrieve_from_cache(kCacheA, kMemoryDevice), null);
255 do_check_eq(retrieve_from_cache(kCacheB, kDiskDevice), null);
256 do_check_eq(retrieve_from_cache(kCacheC, kOfflineDevice), null);
258 // Make sure only the memory device is available
259 check_devices_available([kMemoryDevice]);
261 // Make sure the memory device is empty
262 do_check_eq(get_device_entry_count(kMemoryDevice), 0);
264 // Exit private browsing mode
265 pb.privateBrowsingEnabled = false;
267 // Make sure all three cache devices are available after leaving the private mode
268 check_devices_available([kMemoryDevice, kDiskDevice, kOfflineDevice]);
270 // Check if cache-A is gone, and cache-B and cache-C are still avilable
271 do_check_eq(retrieve_from_cache(kCacheA, kMemoryDevice), null);
272 do_check_eq(retrieve_from_cache(kCacheB, kDiskDevice), kTestContent);
273 do_check_eq(retrieve_from_cache(kCacheC, kOfflineDevice), kTestContent);
275 prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");