const NS_PLACES_INIT_COMPLETE_TOPIC = "places-init-complete"; let gLockedConn; add_task(async function setup() { // Create a dummy places.sqlite and open an unshared connection on it let db = Services.dirsvc.get("ProfD", Ci.nsIFile); db.append("places.sqlite"); gLockedConn = Services.storage.openUnsharedDatabase(db); Assert.ok(db.exists(), "The database should have been created"); // We need an exclusive lock on the db gLockedConn.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE"); // Exclusive locking is lazy applied, we need to make a write to activate it gLockedConn.executeSimpleSQL("PRAGMA USER_VERSION = 1"); }); add_task(async function locked() { // Try to create history service while the db is locked. // It should be possible to create the service, but any method using the // database will fail. let resolved = false; let promiseComplete = promiseTopicObserved( NS_PLACES_INIT_COMPLETE_TOPIC ).then(() => (resolved = true)); let history = Cc["@mozilla.org/browser/nav-history-service;1"].createInstance( Ci.nsINavHistoryService ); // The notification shouldn't happen until something tries to use the database. await new Promise(resolve => do_timeout(100, resolve)); Assert.equal( resolved, false, "The notification should not have been fired yet" ); // This will initialize the database. Assert.equal(history.databaseStatus, history.DATABASE_STATUS_LOCKED); await promiseComplete; // Close our connection and try to cleanup the file (could fail on Windows) gLockedConn.close(); let db = Services.dirsvc.get("ProfD", Ci.nsIFile); db.append("places.sqlite"); if (db.exists()) { try { db.remove(false); } catch (e) { info("Unable to remove dummy places.sqlite"); } } });