extensions/cookie/test/unit/test_cookies_sync_failure.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 // Test the various ways opening a cookie database can fail in a synchronous
michael@0 5 // (i.e. immediate) manner, and that the database is renamed and recreated
michael@0 6 // under each circumstance. These circumstances are, in no particular order:
michael@0 7 //
michael@0 8 // 1) A corrupt database, such that opening the connection fails.
michael@0 9 // 2) The 'moz_cookies' table doesn't exist.
michael@0 10 // 3) Not all of the expected columns exist, and statement creation fails when:
michael@0 11 // a) The schema version is larger than the current version.
michael@0 12 // b) The schema version is less than or equal to the current version.
michael@0 13 // 4) Migration fails. This will have different modes depending on the initial
michael@0 14 // version:
michael@0 15 // a) Schema 1: the 'lastAccessed' column already exists.
michael@0 16 // b) Schema 2: the 'baseDomain' column already exists; or 'baseDomain'
michael@0 17 // cannot be computed for a particular host.
michael@0 18 // c) Schema 3: the 'creationTime' column already exists; or the
michael@0 19 // 'moz_uniqueid' index already exists.
michael@0 20
michael@0 21 let COOKIE_DATABASE_SCHEMA_CURRENT = 5;
michael@0 22
michael@0 23 let test_generator = do_run_test();
michael@0 24
michael@0 25 function run_test() {
michael@0 26 do_test_pending();
michael@0 27 do_run_generator(test_generator);
michael@0 28 }
michael@0 29
michael@0 30 function finish_test() {
michael@0 31 do_execute_soon(function() {
michael@0 32 test_generator.close();
michael@0 33 do_test_finished();
michael@0 34 });
michael@0 35 }
michael@0 36
michael@0 37 function do_run_test() {
michael@0 38 // Set up a profile.
michael@0 39 this.profile = do_get_profile();
michael@0 40
michael@0 41 // Allow all cookies.
michael@0 42 Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
michael@0 43
michael@0 44 // Get the cookie file and the backup file.
michael@0 45 this.cookieFile = profile.clone();
michael@0 46 cookieFile.append("cookies.sqlite");
michael@0 47 this.backupFile = profile.clone();
michael@0 48 backupFile.append("cookies.sqlite.bak");
michael@0 49 do_check_false(cookieFile.exists());
michael@0 50 do_check_false(backupFile.exists());
michael@0 51
michael@0 52 // Create a cookie object for testing.
michael@0 53 this.now = Date.now() * 1000;
michael@0 54 this.futureExpiry = Math.round(this.now / 1e6 + 1000);
michael@0 55 this.cookie = new Cookie("oh", "hai", "bar.com", "/", this.futureExpiry,
michael@0 56 this.now, this.now, false, false, false);
michael@0 57
michael@0 58 this.sub_generator = run_test_1(test_generator);
michael@0 59 sub_generator.next();
michael@0 60 yield;
michael@0 61
michael@0 62 this.sub_generator = run_test_2(test_generator);
michael@0 63 sub_generator.next();
michael@0 64 yield;
michael@0 65
michael@0 66 this.sub_generator = run_test_3(test_generator, 99);
michael@0 67 sub_generator.next();
michael@0 68 yield;
michael@0 69
michael@0 70 this.sub_generator = run_test_3(test_generator, COOKIE_DATABASE_SCHEMA_CURRENT);
michael@0 71 sub_generator.next();
michael@0 72 yield;
michael@0 73
michael@0 74 this.sub_generator = run_test_3(test_generator, 4);
michael@0 75 sub_generator.next();
michael@0 76 yield;
michael@0 77
michael@0 78 this.sub_generator = run_test_3(test_generator, 3);
michael@0 79 sub_generator.next();
michael@0 80 yield;
michael@0 81
michael@0 82 this.sub_generator = run_test_4_exists(test_generator, 1,
michael@0 83 "ALTER TABLE moz_cookies ADD lastAccessed INTEGER");
michael@0 84 sub_generator.next();
michael@0 85 yield;
michael@0 86
michael@0 87 this.sub_generator = run_test_4_exists(test_generator, 2,
michael@0 88 "ALTER TABLE moz_cookies ADD baseDomain TEXT");
michael@0 89 sub_generator.next();
michael@0 90 yield;
michael@0 91
michael@0 92 this.sub_generator = run_test_4_baseDomain(test_generator);
michael@0 93 sub_generator.next();
michael@0 94 yield;
michael@0 95
michael@0 96 this.sub_generator = run_test_4_exists(test_generator, 3,
michael@0 97 "ALTER TABLE moz_cookies ADD creationTime INTEGER");
michael@0 98 sub_generator.next();
michael@0 99 yield;
michael@0 100
michael@0 101 this.sub_generator = run_test_4_exists(test_generator, 3,
michael@0 102 "CREATE UNIQUE INDEX moz_uniqueid ON moz_cookies (name, host, path)");
michael@0 103 sub_generator.next();
michael@0 104 yield;
michael@0 105
michael@0 106 finish_test();
michael@0 107 return;
michael@0 108 }
michael@0 109
michael@0 110 const garbage = "hello thar!";
michael@0 111
michael@0 112 function create_garbage_file(file)
michael@0 113 {
michael@0 114 // Create an empty database file.
michael@0 115 file.create(Ci.nsIFile.NORMAL_FILE_TYPE, -1);
michael@0 116 do_check_true(file.exists());
michael@0 117 do_check_eq(file.fileSize, 0);
michael@0 118
michael@0 119 // Write some garbage to it.
michael@0 120 let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
michael@0 121 createInstance(Ci.nsIFileOutputStream);
michael@0 122 ostream.init(file, -1, -1, 0);
michael@0 123 ostream.write(garbage, garbage.length);
michael@0 124 ostream.flush();
michael@0 125 ostream.close();
michael@0 126
michael@0 127 file = file.clone(); // Windows maintains a stat cache. It's lame.
michael@0 128 do_check_eq(file.fileSize, garbage.length);
michael@0 129 }
michael@0 130
michael@0 131 function check_garbage_file(file)
michael@0 132 {
michael@0 133 do_check_true(file.exists());
michael@0 134 do_check_eq(file.fileSize, garbage.length);
michael@0 135 file.remove(false);
michael@0 136 do_check_false(file.exists());
michael@0 137 }
michael@0 138
michael@0 139 function run_test_1(generator)
michael@0 140 {
michael@0 141 // Create a garbage database file.
michael@0 142 create_garbage_file(cookieFile);
michael@0 143
michael@0 144 // Load the profile and populate it.
michael@0 145 let uri = NetUtil.newURI("http://foo.com/");
michael@0 146 Services.cookies.setCookieString(uri, null, "oh=hai; max-age=1000", null);
michael@0 147
michael@0 148 // Fake a profile change.
michael@0 149 do_close_profile(sub_generator);
michael@0 150 yield;
michael@0 151 do_load_profile();
michael@0 152
michael@0 153 // Check that the new database contains the cookie, and the old file was
michael@0 154 // renamed.
michael@0 155 do_check_eq(do_count_cookies(), 1);
michael@0 156 check_garbage_file(backupFile);
michael@0 157
michael@0 158 // Close the profile.
michael@0 159 do_close_profile(sub_generator);
michael@0 160 yield;
michael@0 161
michael@0 162 // Clean up.
michael@0 163 cookieFile.remove(false);
michael@0 164 do_check_false(cookieFile.exists());
michael@0 165 do_run_generator(generator);
michael@0 166 }
michael@0 167
michael@0 168 function run_test_2(generator)
michael@0 169 {
michael@0 170 // Load the profile and populate it.
michael@0 171 do_load_profile();
michael@0 172 let uri = NetUtil.newURI("http://foo.com/");
michael@0 173 Services.cookies.setCookieString(uri, null, "oh=hai; max-age=1000", null);
michael@0 174
michael@0 175 // Fake a profile change.
michael@0 176 do_close_profile(sub_generator);
michael@0 177 yield;
michael@0 178
michael@0 179 // Drop the table.
michael@0 180 let db = Services.storage.openDatabase(cookieFile);
michael@0 181 db.executeSimpleSQL("DROP TABLE moz_cookies");
michael@0 182 db.close();
michael@0 183
michael@0 184 // Load the profile and check that the table is recreated in-place.
michael@0 185 do_load_profile();
michael@0 186 do_check_eq(do_count_cookies(), 0);
michael@0 187 do_check_false(backupFile.exists());
michael@0 188
michael@0 189 // Close the profile.
michael@0 190 do_close_profile(sub_generator);
michael@0 191 yield;
michael@0 192
michael@0 193 // Clean up.
michael@0 194 cookieFile.remove(false);
michael@0 195 do_check_false(cookieFile.exists());
michael@0 196 do_run_generator(generator);
michael@0 197 }
michael@0 198
michael@0 199 function run_test_3(generator, schema)
michael@0 200 {
michael@0 201 // Manually create a schema 2 database, populate it, and set the schema
michael@0 202 // version to the desired number.
michael@0 203 let schema2db = new CookieDatabaseConnection(do_get_cookie_file(profile), 2);
michael@0 204 schema2db.insertCookie(cookie);
michael@0 205 schema2db.db.schemaVersion = schema;
michael@0 206 schema2db.close();
michael@0 207
michael@0 208 // Load the profile and check that the column existence test fails.
michael@0 209 do_load_profile();
michael@0 210 do_check_eq(do_count_cookies(), 0);
michael@0 211
michael@0 212 // Close the profile.
michael@0 213 do_close_profile(sub_generator);
michael@0 214 yield;
michael@0 215
michael@0 216 // Check that the schema version has been reset.
michael@0 217 let db = Services.storage.openDatabase(cookieFile);
michael@0 218 do_check_eq(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
michael@0 219 db.close();
michael@0 220
michael@0 221 // Clean up.
michael@0 222 cookieFile.remove(false);
michael@0 223 do_check_false(cookieFile.exists());
michael@0 224 do_run_generator(generator);
michael@0 225 }
michael@0 226
michael@0 227 function run_test_4_exists(generator, schema, stmt)
michael@0 228 {
michael@0 229 // Manually create a database, populate it, and add the desired column.
michael@0 230 let db = new CookieDatabaseConnection(do_get_cookie_file(profile), schema);
michael@0 231 db.insertCookie(cookie);
michael@0 232 db.db.executeSimpleSQL(stmt);
michael@0 233 db.close();
michael@0 234
michael@0 235 // Load the profile and check that migration fails.
michael@0 236 do_load_profile();
michael@0 237 do_check_eq(do_count_cookies(), 0);
michael@0 238
michael@0 239 // Close the profile.
michael@0 240 do_close_profile(sub_generator);
michael@0 241 yield;
michael@0 242
michael@0 243 // Check that the schema version has been reset and the backup file exists.
michael@0 244 db = Services.storage.openDatabase(cookieFile);
michael@0 245 do_check_eq(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
michael@0 246 db.close();
michael@0 247 do_check_true(backupFile.exists());
michael@0 248
michael@0 249 // Clean up.
michael@0 250 cookieFile.remove(false);
michael@0 251 backupFile.remove(false);
michael@0 252 do_check_false(cookieFile.exists());
michael@0 253 do_check_false(backupFile.exists());
michael@0 254 do_run_generator(generator);
michael@0 255 }
michael@0 256
michael@0 257 function run_test_4_baseDomain(generator)
michael@0 258 {
michael@0 259 // Manually create a database and populate it with a bad host.
michael@0 260 let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 2);
michael@0 261 let badCookie = new Cookie("oh", "hai", ".", "/", this.futureExpiry, this.now,
michael@0 262 this.now, false, false, false);
michael@0 263 db.insertCookie(badCookie);
michael@0 264 db.close();
michael@0 265
michael@0 266 // Load the profile and check that migration fails.
michael@0 267 do_load_profile();
michael@0 268 do_check_eq(do_count_cookies(), 0);
michael@0 269
michael@0 270 // Close the profile.
michael@0 271 do_close_profile(sub_generator);
michael@0 272 yield;
michael@0 273
michael@0 274 // Check that the schema version has been reset and the backup file exists.
michael@0 275 db = Services.storage.openDatabase(cookieFile);
michael@0 276 do_check_eq(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
michael@0 277 db.close();
michael@0 278 do_check_true(backupFile.exists());
michael@0 279
michael@0 280 // Clean up.
michael@0 281 cookieFile.remove(false);
michael@0 282 backupFile.remove(false);
michael@0 283 do_check_false(cookieFile.exists());
michael@0 284 do_check_false(backupFile.exists());
michael@0 285 do_run_generator(generator);
michael@0 286 }

mercurial