зеркало из https://github.com/mozilla/gecko-dev.git
315 строки
9.8 KiB
JavaScript
315 строки
9.8 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
*/
|
|
|
|
// This file tests the Vacuum Manager.
|
|
|
|
/**
|
|
* Loads a test component that will register as a vacuum-participant.
|
|
* If other participants are found they will be unregistered, to avoid conflicts
|
|
* with the test itself.
|
|
*/
|
|
function load_test_vacuum_component() {
|
|
const CATEGORY_NAME = "vacuum-participant";
|
|
|
|
do_load_manifest("vacuumParticipant.manifest");
|
|
|
|
// This is a lazy check, there could be more participants than just this test
|
|
// we just mind that the test exists though.
|
|
const EXPECTED_ENTRIES = ["vacuumParticipant"];
|
|
let {catMan} = Services;
|
|
let found = false;
|
|
for (let {data: entry} of catMan.enumerateCategory(CATEGORY_NAME)) {
|
|
print("Check if the found category entry (" + entry + ") is expected.");
|
|
if (EXPECTED_ENTRIES.includes(entry)) {
|
|
print("Check that only one test entry exists.");
|
|
Assert.ok(!found);
|
|
found = true;
|
|
} else {
|
|
// Temporary unregister other participants for this test.
|
|
catMan.deleteCategoryEntry("vacuum-participant", entry, false);
|
|
}
|
|
}
|
|
print("Check the test entry exists.");
|
|
Assert.ok(found);
|
|
}
|
|
|
|
/**
|
|
* Sends a fake idle-daily notification to the VACUUM Manager.
|
|
*/
|
|
function synthesize_idle_daily() {
|
|
let vm = Cc["@mozilla.org/storage/vacuum;1"].getService(Ci.nsIObserver);
|
|
vm.observe(null, "idle-daily", null);
|
|
}
|
|
|
|
/**
|
|
* Returns a new nsIFile reference for a profile database.
|
|
* @param filename for the database, excluded the .sqlite extension.
|
|
*/
|
|
function new_db_file(name) {
|
|
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
|
file.append(name + ".sqlite");
|
|
return file;
|
|
}
|
|
|
|
function run_test() {
|
|
do_test_pending();
|
|
|
|
// Change initial page size. Do it immediately since it would require an
|
|
// additional vacuum op to do it later. As a bonus this makes the page size
|
|
// change test really fast since it only has to check results.
|
|
let conn = getDatabase(new_db_file("testVacuum"));
|
|
conn.executeSimpleSQL("PRAGMA page_size = 1024");
|
|
print("Check current page size.");
|
|
let stmt = conn.createStatement("PRAGMA page_size");
|
|
try {
|
|
while (stmt.executeStep()) {
|
|
Assert.equal(stmt.row.page_size, 1024);
|
|
}
|
|
} finally {
|
|
stmt.finalize();
|
|
}
|
|
|
|
load_test_vacuum_component();
|
|
|
|
run_next_test();
|
|
}
|
|
|
|
const TESTS = [
|
|
|
|
function test_common_vacuum() {
|
|
print("\n*** Test that a VACUUM correctly happens and all notifications are fired.");
|
|
// Wait for VACUUM begin.
|
|
let beginVacuumReceived = false;
|
|
Services.obs.addObserver(function onVacuum(aSubject, aTopic, aData) {
|
|
Services.obs.removeObserver(onVacuum, aTopic);
|
|
beginVacuumReceived = true;
|
|
}, "test-begin-vacuum");
|
|
|
|
// Wait for heavy IO notifications.
|
|
let heavyIOTaskBeginReceived = false;
|
|
let heavyIOTaskEndReceived = false;
|
|
Services.obs.addObserver(function onVacuum(aSubject, aTopic, aData) {
|
|
if (heavyIOTaskBeginReceived && heavyIOTaskEndReceived) {
|
|
Services.obs.removeObserver(onVacuum, aTopic);
|
|
}
|
|
|
|
if (aData == "vacuum-begin") {
|
|
heavyIOTaskBeginReceived = true;
|
|
} else if (aData == "vacuum-end") {
|
|
heavyIOTaskEndReceived = true;
|
|
}
|
|
}, "heavy-io-task");
|
|
|
|
// Wait for VACUUM end.
|
|
Services.obs.addObserver(function onVacuum(aSubject, aTopic, aData) {
|
|
Services.obs.removeObserver(onVacuum, aTopic);
|
|
print("Check we received onBeginVacuum");
|
|
Assert.ok(beginVacuumReceived);
|
|
print("Check we received heavy-io-task notifications");
|
|
Assert.ok(heavyIOTaskBeginReceived);
|
|
Assert.ok(heavyIOTaskEndReceived);
|
|
print("Received onEndVacuum");
|
|
run_next_test();
|
|
}, "test-end-vacuum");
|
|
|
|
synthesize_idle_daily();
|
|
},
|
|
|
|
function test_skipped_if_recent_vacuum() {
|
|
print("\n*** Test that a VACUUM is skipped if it was run recently.");
|
|
Services.prefs.setIntPref("storage.vacuum.last.testVacuum.sqlite",
|
|
parseInt(Date.now() / 1000));
|
|
|
|
// Wait for VACUUM begin.
|
|
let vacuumObserver = {
|
|
gotNotification: false,
|
|
observe: function VO_observe(aSubject, aTopic, aData) {
|
|
this.gotNotification = true;
|
|
},
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
|
|
};
|
|
Services.obs.addObserver(vacuumObserver, "test-begin-vacuum");
|
|
|
|
// Check after a couple seconds that no VACUUM has been run.
|
|
do_timeout(2000, function() {
|
|
print("Check VACUUM did not run.");
|
|
Assert.ok(!vacuumObserver.gotNotification);
|
|
Services.obs.removeObserver(vacuumObserver, "test-begin-vacuum");
|
|
run_next_test();
|
|
});
|
|
|
|
synthesize_idle_daily();
|
|
},
|
|
|
|
function test_page_size_change() {
|
|
print("\n*** Test that a VACUUM changes page_size");
|
|
|
|
// We did setup the database with a small page size, the previous vacuum
|
|
// should have updated it.
|
|
print("Check that page size was updated.");
|
|
let conn = getDatabase(new_db_file("testVacuum"));
|
|
let stmt = conn.createStatement("PRAGMA page_size");
|
|
try {
|
|
while (stmt.executeStep()) {
|
|
Assert.equal(stmt.row.page_size, conn.defaultPageSize);
|
|
}
|
|
} finally {
|
|
stmt.finalize();
|
|
}
|
|
|
|
run_next_test();
|
|
},
|
|
|
|
function test_skipped_optout_vacuum() {
|
|
print("\n*** Test that a VACUUM is skipped if the participant wants to opt-out.");
|
|
Services.obs.notifyObservers(null, "test-options", "opt-out");
|
|
|
|
// Wait for VACUUM begin.
|
|
let vacuumObserver = {
|
|
gotNotification: false,
|
|
observe: function VO_observe(aSubject, aTopic, aData) {
|
|
this.gotNotification = true;
|
|
},
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
|
|
};
|
|
Services.obs.addObserver(vacuumObserver, "test-begin-vacuum");
|
|
|
|
// Check after a couple seconds that no VACUUM has been run.
|
|
do_timeout(2000, function() {
|
|
print("Check VACUUM did not run.");
|
|
Assert.ok(!vacuumObserver.gotNotification);
|
|
Services.obs.removeObserver(vacuumObserver, "test-begin-vacuum");
|
|
run_next_test();
|
|
});
|
|
|
|
synthesize_idle_daily();
|
|
},
|
|
|
|
/* Changing page size on WAL is not supported till Bug 634374 is properly fixed.
|
|
function test_page_size_change_with_wal()
|
|
{
|
|
print("\n*** Test that a VACUUM changes page_size with WAL mode");
|
|
Services.obs.notifyObservers(null, "test-options", "wal");
|
|
|
|
// Set a small page size.
|
|
let conn = getDatabase(new_db_file("testVacuum2"));
|
|
conn.executeSimpleSQL("PRAGMA page_size = 1024");
|
|
let stmt = conn.createStatement("PRAGMA page_size");
|
|
try {
|
|
while (stmt.executeStep()) {
|
|
do_check_eq(stmt.row.page_size, 1024);
|
|
}
|
|
}
|
|
finally {
|
|
stmt.finalize();
|
|
}
|
|
|
|
// Use WAL journal mode.
|
|
conn.executeSimpleSQL("PRAGMA journal_mode = WAL");
|
|
stmt = conn.createStatement("PRAGMA journal_mode");
|
|
try {
|
|
while (stmt.executeStep()) {
|
|
do_check_eq(stmt.row.journal_mode, "wal");
|
|
}
|
|
}
|
|
finally {
|
|
stmt.finalize();
|
|
}
|
|
|
|
// Wait for VACUUM end.
|
|
let vacuumObserver = {
|
|
observe: function VO_observe(aSubject, aTopic, aData) {
|
|
Services.obs.removeObserver(this, aTopic);
|
|
print("Check page size has been updated.");
|
|
let stmt = conn.createStatement("PRAGMA page_size");
|
|
try {
|
|
while (stmt.executeStep()) {
|
|
do_check_eq(stmt.row.page_size, Ci.mozIStorageConnection.DEFAULT_PAGE_SIZE);
|
|
}
|
|
}
|
|
finally {
|
|
stmt.finalize();
|
|
}
|
|
|
|
print("Check journal mode has been restored.");
|
|
stmt = conn.createStatement("PRAGMA journal_mode");
|
|
try {
|
|
while (stmt.executeStep()) {
|
|
do_check_eq(stmt.row.journal_mode, "wal");
|
|
}
|
|
}
|
|
finally {
|
|
stmt.finalize();
|
|
}
|
|
|
|
run_next_test();
|
|
},
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver])
|
|
}
|
|
Services.obs.addObserver(vacuumObserver, "test-end-vacuum", false);
|
|
|
|
synthesize_idle_daily();
|
|
},
|
|
*/
|
|
|
|
function test_memory_database_crash() {
|
|
print("\n*** Test that we don't crash trying to vacuum a memory database");
|
|
Services.obs.notifyObservers(null, "test-options", "memory");
|
|
|
|
// Wait for VACUUM begin.
|
|
let vacuumObserver = {
|
|
gotNotification: false,
|
|
observe: function VO_observe(aSubject, aTopic, aData) {
|
|
this.gotNotification = true;
|
|
},
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
|
|
};
|
|
Services.obs.addObserver(vacuumObserver, "test-begin-vacuum");
|
|
|
|
// Check after a couple seconds that no VACUUM has been run.
|
|
do_timeout(2000, function() {
|
|
print("Check VACUUM did not run.");
|
|
Assert.ok(!vacuumObserver.gotNotification);
|
|
Services.obs.removeObserver(vacuumObserver, "test-begin-vacuum");
|
|
run_next_test();
|
|
});
|
|
|
|
synthesize_idle_daily();
|
|
},
|
|
|
|
/* Changing page size on WAL is not supported till Bug 634374 is properly fixed.
|
|
function test_wal_restore_fail()
|
|
{
|
|
print("\n*** Test that a failing WAL restoration notifies failure");
|
|
Services.obs.notifyObservers(null, "test-options", "wal-fail");
|
|
|
|
// Wait for VACUUM end.
|
|
let vacuumObserver = {
|
|
observe: function VO_observe(aSubject, aTopic, aData) {
|
|
Services.obs.removeObserver(vacuumObserver, "test-end-vacuum");
|
|
print("Check WAL restoration failed.");
|
|
do_check_false(aData);
|
|
run_next_test();
|
|
},
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver])
|
|
}
|
|
Services.obs.addObserver(vacuumObserver, "test-end-vacuum", false);
|
|
|
|
synthesize_idle_daily();
|
|
},
|
|
*/
|
|
];
|
|
|
|
function run_next_test() {
|
|
if (TESTS.length == 0) {
|
|
Services.obs.notifyObservers(null, "test-options", "dispose");
|
|
do_test_finished();
|
|
} else {
|
|
// Set last VACUUM to a date in the past.
|
|
Services.prefs.setIntPref("storage.vacuum.last.testVacuum.sqlite",
|
|
parseInt(Date.now() / 1000 - 31 * 86400));
|
|
executeSoon(TESTS.shift());
|
|
}
|
|
}
|