storage/test/unit/test_vacuum.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 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/
michael@0 3 */
michael@0 4
michael@0 5 // This file tests the Vacuum Manager.
michael@0 6
michael@0 7 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 8 Components.utils.import("resource://gre/modules/Services.jsm");
michael@0 9
michael@0 10 /**
michael@0 11 * Loads a test component that will register as a vacuum-participant.
michael@0 12 * If other participants are found they will be unregistered, to avoid conflicts
michael@0 13 * with the test itself.
michael@0 14 */
michael@0 15 function load_test_vacuum_component()
michael@0 16 {
michael@0 17 const CATEGORY_NAME = "vacuum-participant";
michael@0 18
michael@0 19 do_load_manifest("vacuumParticipant.manifest");
michael@0 20
michael@0 21 // This is a lazy check, there could be more participants than just this test
michael@0 22 // we just mind that the test exists though.
michael@0 23 const EXPECTED_ENTRIES = ["vacuumParticipant"];
michael@0 24 let catMan = Cc["@mozilla.org/categorymanager;1"].
michael@0 25 getService(Ci.nsICategoryManager);
michael@0 26 let found = false;
michael@0 27 let entries = catMan.enumerateCategory(CATEGORY_NAME);
michael@0 28 while (entries.hasMoreElements()) {
michael@0 29 let entry = entries.getNext().QueryInterface(Ci.nsISupportsCString).data;
michael@0 30 print("Check if the found category entry (" + entry + ") is expected.");
michael@0 31 if (EXPECTED_ENTRIES.indexOf(entry) != -1) {
michael@0 32 print("Check that only one test entry exists.");
michael@0 33 do_check_false(found);
michael@0 34 found = true;
michael@0 35 }
michael@0 36 else {
michael@0 37 // Temporary unregister other participants for this test.
michael@0 38 catMan.deleteCategoryEntry("vacuum-participant", entry, false);
michael@0 39 }
michael@0 40 }
michael@0 41 print("Check the test entry exists.");
michael@0 42 do_check_true(found);
michael@0 43 }
michael@0 44
michael@0 45 /**
michael@0 46 * Sends a fake idle-daily notification to the VACUUM Manager.
michael@0 47 */
michael@0 48 function synthesize_idle_daily()
michael@0 49 {
michael@0 50 let vm = Cc["@mozilla.org/storage/vacuum;1"].getService(Ci.nsIObserver);
michael@0 51 vm.observe(null, "idle-daily", null);
michael@0 52 }
michael@0 53
michael@0 54 /**
michael@0 55 * Returns a new nsIFile reference for a profile database.
michael@0 56 * @param filename for the database, excluded the .sqlite extension.
michael@0 57 */
michael@0 58 function new_db_file(name)
michael@0 59 {
michael@0 60 let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
michael@0 61 file.append(name + ".sqlite");
michael@0 62 return file;
michael@0 63 }
michael@0 64
michael@0 65 function run_test()
michael@0 66 {
michael@0 67 do_test_pending();
michael@0 68
michael@0 69 // Change initial page size. Do it immediately since it would require an
michael@0 70 // additional vacuum op to do it later. As a bonus this makes the page size
michael@0 71 // change test really fast since it only has to check results.
michael@0 72 let conn = getDatabase(new_db_file("testVacuum"));
michael@0 73 conn.executeSimpleSQL("PRAGMA page_size = 1024");
michael@0 74 print("Check current page size.");
michael@0 75 let stmt = conn.createStatement("PRAGMA page_size");
michael@0 76 try {
michael@0 77 while (stmt.executeStep()) {
michael@0 78 do_check_eq(stmt.row.page_size, 1024);
michael@0 79 }
michael@0 80 }
michael@0 81 finally {
michael@0 82 stmt.finalize();
michael@0 83 }
michael@0 84
michael@0 85 load_test_vacuum_component();
michael@0 86
michael@0 87 run_next_test();
michael@0 88 }
michael@0 89
michael@0 90 function run_next_test()
michael@0 91 {
michael@0 92 if (TESTS.length == 0) {
michael@0 93 Services.obs.notifyObservers(null, "test-options", "dispose");
michael@0 94 do_test_finished();
michael@0 95 }
michael@0 96 else {
michael@0 97 // Set last VACUUM to a date in the past.
michael@0 98 Services.prefs.setIntPref("storage.vacuum.last.testVacuum.sqlite",
michael@0 99 parseInt(Date.now() / 1000 - 31 * 86400));
michael@0 100 do_execute_soon(TESTS.shift());
michael@0 101 }
michael@0 102 }
michael@0 103
michael@0 104 const TESTS = [
michael@0 105
michael@0 106 function test_common_vacuum()
michael@0 107 {
michael@0 108 print("\n*** Test that a VACUUM correctly happens and all notifications are fired.");
michael@0 109 // Wait for VACUUM begin.
michael@0 110 let beginVacuumReceived = false;
michael@0 111 Services.obs.addObserver(function onVacuum(aSubject, aTopic, aData) {
michael@0 112 Services.obs.removeObserver(onVacuum, aTopic);
michael@0 113 beginVacuumReceived = true;
michael@0 114 }, "test-begin-vacuum", false);
michael@0 115
michael@0 116 // Wait for heavy IO notifications.
michael@0 117 let heavyIOTaskBeginReceived = false;
michael@0 118 let heavyIOTaskEndReceived = false;
michael@0 119 Services.obs.addObserver(function onVacuum(aSubject, aTopic, aData) {
michael@0 120 if (heavyIOTaskBeginReceived && heavyIOTaskEndReceived) {
michael@0 121 Services.obs.removeObserver(onVacuum, aTopic);
michael@0 122 }
michael@0 123
michael@0 124 if (aData == "vacuum-begin") {
michael@0 125 heavyIOTaskBeginReceived = true;
michael@0 126 }
michael@0 127 else if (aData == "vacuum-end") {
michael@0 128 heavyIOTaskEndReceived = true;
michael@0 129 }
michael@0 130 }, "heavy-io-task", false);
michael@0 131
michael@0 132 // Wait for VACUUM end.
michael@0 133 Services.obs.addObserver(function onVacuum(aSubject, aTopic, aData) {
michael@0 134 Services.obs.removeObserver(onVacuum, aTopic);
michael@0 135 print("Check we received onBeginVacuum");
michael@0 136 do_check_true(beginVacuumReceived);
michael@0 137 print("Check we received heavy-io-task notifications");
michael@0 138 do_check_true(heavyIOTaskBeginReceived);
michael@0 139 do_check_true(heavyIOTaskEndReceived);
michael@0 140 print("Received onEndVacuum");
michael@0 141 run_next_test();
michael@0 142 }, "test-end-vacuum", false);
michael@0 143
michael@0 144 synthesize_idle_daily();
michael@0 145 },
michael@0 146
michael@0 147 function test_skipped_if_recent_vacuum()
michael@0 148 {
michael@0 149 print("\n*** Test that a VACUUM is skipped if it was run recently.");
michael@0 150 Services.prefs.setIntPref("storage.vacuum.last.testVacuum.sqlite",
michael@0 151 parseInt(Date.now() / 1000));
michael@0 152
michael@0 153 // Wait for VACUUM begin.
michael@0 154 let vacuumObserver = {
michael@0 155 gotNotification: false,
michael@0 156 observe: function VO_observe(aSubject, aTopic, aData) {
michael@0 157 this.gotNotification = true;
michael@0 158 },
michael@0 159 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
michael@0 160 }
michael@0 161 Services.obs.addObserver(vacuumObserver, "test-begin-vacuum", false);
michael@0 162
michael@0 163 // Check after a couple seconds that no VACUUM has been run.
michael@0 164 do_timeout(2000, function () {
michael@0 165 print("Check VACUUM did not run.");
michael@0 166 do_check_false(vacuumObserver.gotNotification);
michael@0 167 Services.obs.removeObserver(vacuumObserver, "test-begin-vacuum");
michael@0 168 run_next_test();
michael@0 169 });
michael@0 170
michael@0 171 synthesize_idle_daily();
michael@0 172 },
michael@0 173
michael@0 174 function test_page_size_change()
michael@0 175 {
michael@0 176 print("\n*** Test that a VACUUM changes page_size");
michael@0 177
michael@0 178 // We did setup the database with a small page size, the previous vacuum
michael@0 179 // should have updated it.
michael@0 180 print("Check that page size was updated.");
michael@0 181 let conn = getDatabase(new_db_file("testVacuum"));
michael@0 182 let stmt = conn.createStatement("PRAGMA page_size");
michael@0 183 try {
michael@0 184 while (stmt.executeStep()) {
michael@0 185 do_check_eq(stmt.row.page_size, conn.defaultPageSize);
michael@0 186 }
michael@0 187 }
michael@0 188 finally {
michael@0 189 stmt.finalize();
michael@0 190 }
michael@0 191
michael@0 192 run_next_test();
michael@0 193 },
michael@0 194
michael@0 195 function test_skipped_optout_vacuum()
michael@0 196 {
michael@0 197 print("\n*** Test that a VACUUM is skipped if the participant wants to opt-out.");
michael@0 198 Services.obs.notifyObservers(null, "test-options", "opt-out");
michael@0 199
michael@0 200 // Wait for VACUUM begin.
michael@0 201 let vacuumObserver = {
michael@0 202 gotNotification: false,
michael@0 203 observe: function VO_observe(aSubject, aTopic, aData) {
michael@0 204 this.gotNotification = true;
michael@0 205 },
michael@0 206 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
michael@0 207 }
michael@0 208 Services.obs.addObserver(vacuumObserver, "test-begin-vacuum", false);
michael@0 209
michael@0 210 // Check after a couple seconds that no VACUUM has been run.
michael@0 211 do_timeout(2000, function () {
michael@0 212 print("Check VACUUM did not run.");
michael@0 213 do_check_false(vacuumObserver.gotNotification);
michael@0 214 Services.obs.removeObserver(vacuumObserver, "test-begin-vacuum");
michael@0 215 run_next_test();
michael@0 216 });
michael@0 217
michael@0 218 synthesize_idle_daily();
michael@0 219 },
michael@0 220
michael@0 221 /* Changing page size on WAL is not supported till Bug 634374 is properly fixed.
michael@0 222 function test_page_size_change_with_wal()
michael@0 223 {
michael@0 224 print("\n*** Test that a VACUUM changes page_size with WAL mode");
michael@0 225 Services.obs.notifyObservers(null, "test-options", "wal");
michael@0 226
michael@0 227 // Set a small page size.
michael@0 228 let conn = getDatabase(new_db_file("testVacuum2"));
michael@0 229 conn.executeSimpleSQL("PRAGMA page_size = 1024");
michael@0 230 let stmt = conn.createStatement("PRAGMA page_size");
michael@0 231 try {
michael@0 232 while (stmt.executeStep()) {
michael@0 233 do_check_eq(stmt.row.page_size, 1024);
michael@0 234 }
michael@0 235 }
michael@0 236 finally {
michael@0 237 stmt.finalize();
michael@0 238 }
michael@0 239
michael@0 240 // Use WAL journal mode.
michael@0 241 conn.executeSimpleSQL("PRAGMA journal_mode = WAL");
michael@0 242 stmt = conn.createStatement("PRAGMA journal_mode");
michael@0 243 try {
michael@0 244 while (stmt.executeStep()) {
michael@0 245 do_check_eq(stmt.row.journal_mode, "wal");
michael@0 246 }
michael@0 247 }
michael@0 248 finally {
michael@0 249 stmt.finalize();
michael@0 250 }
michael@0 251
michael@0 252 // Wait for VACUUM end.
michael@0 253 let vacuumObserver = {
michael@0 254 observe: function VO_observe(aSubject, aTopic, aData) {
michael@0 255 Services.obs.removeObserver(this, aTopic);
michael@0 256 print("Check page size has been updated.");
michael@0 257 let stmt = conn.createStatement("PRAGMA page_size");
michael@0 258 try {
michael@0 259 while (stmt.executeStep()) {
michael@0 260 do_check_eq(stmt.row.page_size, Ci.mozIStorageConnection.DEFAULT_PAGE_SIZE);
michael@0 261 }
michael@0 262 }
michael@0 263 finally {
michael@0 264 stmt.finalize();
michael@0 265 }
michael@0 266
michael@0 267 print("Check journal mode has been restored.");
michael@0 268 stmt = conn.createStatement("PRAGMA journal_mode");
michael@0 269 try {
michael@0 270 while (stmt.executeStep()) {
michael@0 271 do_check_eq(stmt.row.journal_mode, "wal");
michael@0 272 }
michael@0 273 }
michael@0 274 finally {
michael@0 275 stmt.finalize();
michael@0 276 }
michael@0 277
michael@0 278 run_next_test();
michael@0 279 },
michael@0 280 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
michael@0 281 }
michael@0 282 Services.obs.addObserver(vacuumObserver, "test-end-vacuum", false);
michael@0 283
michael@0 284 synthesize_idle_daily();
michael@0 285 },
michael@0 286 */
michael@0 287
michael@0 288 function test_memory_database_crash()
michael@0 289 {
michael@0 290 print("\n*** Test that we don't crash trying to vacuum a memory database");
michael@0 291 Services.obs.notifyObservers(null, "test-options", "memory");
michael@0 292
michael@0 293 // Wait for VACUUM begin.
michael@0 294 let vacuumObserver = {
michael@0 295 gotNotification: false,
michael@0 296 observe: function VO_observe(aSubject, aTopic, aData) {
michael@0 297 this.gotNotification = true;
michael@0 298 },
michael@0 299 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
michael@0 300 }
michael@0 301 Services.obs.addObserver(vacuumObserver, "test-begin-vacuum", false);
michael@0 302
michael@0 303 // Check after a couple seconds that no VACUUM has been run.
michael@0 304 do_timeout(2000, function () {
michael@0 305 print("Check VACUUM did not run.");
michael@0 306 do_check_false(vacuumObserver.gotNotification);
michael@0 307 Services.obs.removeObserver(vacuumObserver, "test-begin-vacuum");
michael@0 308 run_next_test();
michael@0 309 });
michael@0 310
michael@0 311 synthesize_idle_daily();
michael@0 312 },
michael@0 313
michael@0 314 /* Changing page size on WAL is not supported till Bug 634374 is properly fixed.
michael@0 315 function test_wal_restore_fail()
michael@0 316 {
michael@0 317 print("\n*** Test that a failing WAL restoration notifies failure");
michael@0 318 Services.obs.notifyObservers(null, "test-options", "wal-fail");
michael@0 319
michael@0 320 // Wait for VACUUM end.
michael@0 321 let vacuumObserver = {
michael@0 322 observe: function VO_observe(aSubject, aTopic, aData) {
michael@0 323 Services.obs.removeObserver(vacuumObserver, "test-end-vacuum");
michael@0 324 print("Check WAL restoration failed.");
michael@0 325 do_check_false(aData);
michael@0 326 run_next_test();
michael@0 327 },
michael@0 328 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
michael@0 329 }
michael@0 330 Services.obs.addObserver(vacuumObserver, "test-end-vacuum", false);
michael@0 331
michael@0 332 synthesize_idle_daily();
michael@0 333 },
michael@0 334 */
michael@0 335 ];

mercurial