storage/test/unit/test_vacuum.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial