Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / test / unit / test_cookies_sync_failure.js
bloba807237a622dafbe20709f4c417a74ef4921392c
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 // Test the various ways opening a cookie database can fail in a synchronous
5 // (i.e. immediate) manner, and that the database is renamed and recreated
6 // under each circumstance. These circumstances are, in no particular order:
7 //
8 // 1) A corrupt database, such that opening the connection fails.
9 // 2) The 'moz_cookies' table doesn't exist.
10 // 3) Not all of the expected columns exist, and statement creation fails when:
11 // a) The schema version is larger than the current version.
12 // b) The schema version is less than or equal to the current version.
13 // 4) Migration fails. This will have different modes depending on the initial
14 // version:
15 // a) Schema 1: the 'lastAccessed' column already exists.
16 // b) Schema 2: the 'baseDomain' column already exists; or 'baseDomain'
17 // cannot be computed for a particular host.
18 // c) Schema 3: the 'creationTime' column already exists; or the
19 // 'moz_uniqueid' index already exists.
21 "use strict";
23 let profile;
24 let cookieFile;
25 let backupFile;
26 let sub_generator;
27 let now;
28 let futureExpiry;
29 let cookie;
31 var COOKIE_DATABASE_SCHEMA_CURRENT = 14;
33 var test_generator = do_run_test();
35 function run_test() {
36 do_test_pending();
37 do_run_generator(test_generator);
40 function finish_test() {
41 executeSoon(function () {
42 test_generator.return();
43 do_test_finished();
44 });
47 function* do_run_test() {
48 // Set up a profile.
49 profile = do_get_profile();
51 // Allow all cookies.
52 Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
53 Services.prefs.setBoolPref(
54 "network.cookieJarSettings.unblocked_for_testing",
55 true
58 // Get the cookie file and the backup file.
59 cookieFile = profile.clone();
60 cookieFile.append("cookies.sqlite");
61 backupFile = profile.clone();
62 backupFile.append("cookies.sqlite.bak");
63 Assert.ok(!cookieFile.exists());
64 Assert.ok(!backupFile.exists());
66 // Create a cookie object for testing.
67 now = Date.now() * 1000;
68 futureExpiry = Math.round(now / 1e6 + 1000);
69 cookie = new Cookie(
70 "oh",
71 "hai",
72 "bar.com",
73 "/",
74 futureExpiry,
75 now,
76 now,
77 false,
78 false,
79 false
82 sub_generator = run_test_1(test_generator);
83 sub_generator.next();
84 yield;
86 sub_generator = run_test_2(test_generator);
87 sub_generator.next();
88 yield;
90 sub_generator = run_test_3(test_generator, 99);
91 sub_generator.next();
92 yield;
94 sub_generator = run_test_3(test_generator, COOKIE_DATABASE_SCHEMA_CURRENT);
95 sub_generator.next();
96 yield;
98 sub_generator = run_test_3(test_generator, 4);
99 sub_generator.next();
100 yield;
102 sub_generator = run_test_3(test_generator, 3);
103 sub_generator.next();
104 yield;
106 sub_generator = run_test_4_exists(
107 test_generator,
109 "ALTER TABLE moz_cookies ADD lastAccessed INTEGER"
111 sub_generator.next();
112 yield;
114 sub_generator = run_test_4_exists(
115 test_generator,
117 "ALTER TABLE moz_cookies ADD baseDomain TEXT"
119 sub_generator.next();
120 yield;
122 sub_generator = run_test_4_baseDomain(test_generator);
123 sub_generator.next();
124 yield;
126 sub_generator = run_test_4_exists(
127 test_generator,
129 "ALTER TABLE moz_cookies ADD creationTime INTEGER"
131 sub_generator.next();
132 yield;
134 sub_generator = run_test_4_exists(
135 test_generator,
137 "CREATE UNIQUE INDEX moz_uniqueid ON moz_cookies (name, host, path)"
139 sub_generator.next();
140 yield;
142 finish_test();
145 const garbage = "hello thar!";
147 function create_garbage_file(file) {
148 // Create an empty database file.
149 file.create(Ci.nsIFile.NORMAL_FILE_TYPE, -1);
150 Assert.ok(file.exists());
151 Assert.equal(file.fileSize, 0);
153 // Write some garbage to it.
154 let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
155 Ci.nsIFileOutputStream
157 ostream.init(file, -1, -1, 0);
158 ostream.write(garbage, garbage.length);
159 ostream.flush();
160 ostream.close();
162 file = file.clone(); // Windows maintains a stat cache. It's lame.
163 Assert.equal(file.fileSize, garbage.length);
166 function check_garbage_file(file) {
167 Assert.ok(file.exists());
168 Assert.equal(file.fileSize, garbage.length);
169 file.remove(false);
170 Assert.ok(!file.exists());
173 function* run_test_1(generator) {
174 // Create a garbage database file.
175 create_garbage_file(cookieFile);
177 let uri = NetUtil.newURI("http://foo.com/");
178 const channel = NetUtil.newChannel({
179 uri,
180 loadUsingSystemPrincipal: true,
181 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
184 // Load the profile and populate it.
185 Services.cookies.setCookieStringFromHttp(
186 uri,
187 "oh=hai; max-age=1000",
188 channel
191 // Fake a profile change.
192 do_close_profile(sub_generator);
193 yield;
194 do_load_profile();
196 // Check that the new database contains the cookie, and the old file was
197 // renamed.
198 Assert.equal(do_count_cookies(), 1);
199 check_garbage_file(backupFile);
201 // Close the profile.
202 do_close_profile(sub_generator);
203 yield;
205 // Clean up.
206 cookieFile.remove(false);
207 Assert.ok(!cookieFile.exists());
208 do_run_generator(generator);
211 function* run_test_2(generator) {
212 // Load the profile and populate it.
213 do_load_profile();
214 let uri = NetUtil.newURI("http://foo.com/");
215 const channel = NetUtil.newChannel({
216 uri,
217 loadUsingSystemPrincipal: true,
218 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
220 Services.cookies.setCookieStringFromHttp(
221 uri,
222 "oh=hai; max-age=1000",
223 channel
226 // Fake a profile change.
227 do_close_profile(sub_generator);
228 yield;
230 // Drop the table.
231 let db = Services.storage.openDatabase(cookieFile);
232 db.executeSimpleSQL("DROP TABLE moz_cookies");
233 db.close();
235 // Load the profile and check that the table is recreated in-place.
236 do_load_profile();
237 Assert.equal(do_count_cookies(), 0);
238 Assert.ok(!backupFile.exists());
240 // Close the profile.
241 do_close_profile(sub_generator);
242 yield;
244 // Clean up.
245 cookieFile.remove(false);
246 Assert.ok(!cookieFile.exists());
247 do_run_generator(generator);
250 function* run_test_3(generator, schema) {
251 // Manually create a schema 2 database, populate it, and set the schema
252 // version to the desired number.
253 let schema2db = new CookieDatabaseConnection(do_get_cookie_file(profile), 2);
254 schema2db.insertCookie(cookie);
255 schema2db.db.schemaVersion = schema;
256 schema2db.close();
258 // Load the profile and check that the column existence test fails.
259 do_load_profile();
260 Assert.equal(do_count_cookies(), 0);
262 // Close the profile.
263 do_close_profile(sub_generator);
264 yield;
266 // Check that the schema version has been reset.
267 let db = Services.storage.openDatabase(cookieFile);
268 Assert.equal(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
269 db.close();
271 // Clean up.
272 cookieFile.remove(false);
273 Assert.ok(!cookieFile.exists());
274 do_run_generator(generator);
277 function* run_test_4_exists(generator, schema, stmt) {
278 // Manually create a database, populate it, and add the desired column.
279 let db = new CookieDatabaseConnection(do_get_cookie_file(profile), schema);
280 db.insertCookie(cookie);
281 db.db.executeSimpleSQL(stmt);
282 db.close();
284 // Load the profile and check that migration fails.
285 do_load_profile();
286 Assert.equal(do_count_cookies(), 0);
288 // Close the profile.
289 do_close_profile(sub_generator);
290 yield;
292 // Check that the schema version has been reset and the backup file exists.
293 db = Services.storage.openDatabase(cookieFile);
294 Assert.equal(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
295 db.close();
296 Assert.ok(backupFile.exists());
298 // Clean up.
299 cookieFile.remove(false);
300 backupFile.remove(false);
301 Assert.ok(!cookieFile.exists());
302 Assert.ok(!backupFile.exists());
303 do_run_generator(generator);
306 function* run_test_4_baseDomain(generator) {
307 // Manually create a database and populate it with a bad host.
308 let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 2);
309 let badCookie = new Cookie(
310 "oh",
311 "hai",
312 ".",
313 "/",
314 futureExpiry,
315 now,
316 now,
317 false,
318 false,
319 false
321 db.insertCookie(badCookie);
322 db.close();
324 // Load the profile and check that migration fails.
325 do_load_profile();
326 Assert.equal(do_count_cookies(), 0);
328 // Close the profile.
329 do_close_profile(sub_generator);
330 yield;
332 // Check that the schema version has been reset and the backup file exists.
333 db = Services.storage.openDatabase(cookieFile);
334 Assert.equal(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
335 db.close();
336 Assert.ok(backupFile.exists());
338 // Clean up.
339 cookieFile.remove(false);
340 backupFile.remove(false);
341 Assert.ok(!cookieFile.exists());
342 Assert.ok(!backupFile.exists());
343 do_run_generator(generator);