void test_drop_table_does_not_loop() { nsCOMPtr<mozIStorageConnection> db(getDatabase()); // Need to prepare our statement ahead of time so we make sure to only test // step and not prepare. nsCOMPtr<mozIStorageStatement> stmt; nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING( "SELECT * FROM test" ), getter_AddRefs(stmt)); do_check_success(rv); RefPtr<DatabaseTester> tester(new DatabaseTester(db, "DROP TABLE test")); do_check_true(tester); mozilla::ReentrantMonitorAutoEnter lock(tester->monitor); tester->RunInBackground(); // Hold a read lock on the database, and then let the tester try to execute. bool hasResult; rv = stmt->ExecuteStep(&hasResult); do_check_success(rv); do_check_true(hasResult); tester->Notify(READ_LOCK); // Make sure the tester finishes its test before we move on. tester->WaitFor(TEST_DONE); }
// HACK ALERT: this test fails if it runs after any of the other storage tests // because the storage service will have been initialized and the // do_GetService() call in ServiceInitializer::Run will succeed. So we need a // way to force it to run before all the other storage gtests. As it happens, // gtest has a concept of "death tests" that, among other things, run before // all non-death tests. By merely using a "DeathTest" suffix here this becomes // a death test -- even though it doesn't use any of the normal death test // features -- which ensures this is the first storage test to run. TEST(storage_service_init_background_thread_DeathTest, Test) { nsCOMPtr<nsIRunnable> event = new ServiceInitializer(); do_check_true(event); nsCOMPtr<nsIThread> thread; do_check_success(NS_NewThread(getter_AddRefs(thread))); do_check_success(thread->Dispatch(event, NS_DISPATCH_NORMAL)); // Shutting down the thread will spin the event loop until all work in its // event queue is completed. This will act as our thread synchronization. do_check_success(thread->Shutdown()); }
void test_SpinEventsLoopInHandleError() { nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); // Create a test table and populate it. nsCOMPtr<mozIStorageStatement> stmt; db->CreateStatement(NS_LITERAL_CSTRING( "CREATE TABLE test (id INTEGER PRIMARY KEY)" ), getter_AddRefs(stmt)); stmt->Execute(); stmt->Finalize(); db->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO test (id) VALUES (1)" ), getter_AddRefs(stmt)); stmt->Execute(); stmt->Finalize(); // This will cause a constraint error. db->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO test (id) VALUES (1)" ), getter_AddRefs(stmt)); nsCOMPtr<mozIStoragePendingStatement> ps; do_check_success(stmt->ExecuteAsync(new UnownedCallback(db), getter_AddRefs(ps))); stmt->Finalize(); spin_events_loop_until_true(&UnownedCallback::sError); }
void test_SpinEventsLoopInHandleResult() { nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); // Create a test table and populate it. nsCOMPtr<mozIStorageStatement> stmt; db->CreateStatement(NS_LITERAL_CSTRING( "CREATE TABLE test (id INTEGER PRIMARY KEY)" ), getter_AddRefs(stmt)); stmt->Execute(); stmt->Finalize(); db->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO test (id) VALUES (?)" ), getter_AddRefs(stmt)); for (int32_t i = 0; i < 30; ++i) { stmt->BindInt32ByIndex(0, i); stmt->Execute(); stmt->Reset(); } stmt->Finalize(); db->CreateStatement(NS_LITERAL_CSTRING( "SELECT * FROM test" ), getter_AddRefs(stmt)); nsCOMPtr<mozIStoragePendingStatement> ps; do_check_success(stmt->ExecuteAsync(new UnownedCallback(db), getter_AddRefs(ps))); stmt->Finalize(); spin_events_loop_until_true(&UnownedCallback::sResult); }
void WaitFor(State aState) { monitor.AssertCurrentThreadIn(); while (mState != aState) { do_check_success(monitor.Wait()); } }
void RunInBackground() { (void)NS_NewThread(getter_AddRefs(mThread)); do_check_true(mThread); do_check_success(mThread->Dispatch(this, NS_DISPATCH_NORMAL)); }
void test_step_locked_does_not_block_main_thread() { nsCOMPtr<mozIStorageConnection> db(getDatabase()); // Need to prepare our statement ahead of time so we make sure to only test // step and not prepare. nsCOMPtr<mozIStorageStatement> stmt; nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO test (data) VALUES ('test1')" ), getter_AddRefs(stmt)); do_check_success(rv); RefPtr<DatabaseLocker> locker(new DatabaseLocker("SELECT * FROM test")); do_check_true(locker); mozilla::ReentrantMonitorAutoEnter lock(locker->monitor); locker->RunInBackground(); // Wait for the locker to notify us that it has locked the database properly. locker->WaitFor(WRITE_LOCK); bool hasResult; rv = stmt->ExecuteStep(&hasResult); do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED); locker->Notify(TEST_DONE); }
NS_IMETHOD Run() { mozilla::ReentrantMonitorAutoEnter lock(monitor); nsCOMPtr<mozIStorageConnection> db(getDatabase()); nsCString sql(mSQL); nsCOMPtr<mozIStorageStatement> stmt; do_check_success(db->CreateStatement(sql, getter_AddRefs(stmt))); bool hasResult; do_check_success(stmt->ExecuteStep(&hasResult)); Notify(WRITE_LOCK); WaitFor(TEST_DONE); return NS_OK; }
void test_file_perms() { nsCOMPtr<mozIStorageConnection> db(getDatabase()); nsCOMPtr<nsIFile> dbFile; do_check_success(db->GetDatabaseFile(getter_AddRefs(dbFile))); PRUint32 perms = 0; do_check_success(dbFile->GetPermissions(&perms)); // This reflexts the permissions defined by SQLITE_DEFAULT_FILE_PERMISSIONS in // db/sqlite3/src/Makefile.in and must be kept in sync with that #ifdef ANDROID do_check_true(perms == (PR_IRUSR | PR_IWUSR)); #elif defined(XP_WIN) do_check_true(perms == (PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH | PR_IWOTH)); #else do_check_true(perms == (PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IROTH)); #endif }
void setup() { nsCOMPtr<mozIStorageConnection> db(getDatabase()); // Create and populate a dummy table. nsresult rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "CREATE TABLE test (id INTEGER PRIMARY KEY, data STRING)" )); do_check_success(rv); rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "INSERT INTO test (data) VALUES ('foo')" )); do_check_success(rv); rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "INSERT INTO test (data) VALUES ('bar')" )); do_check_success(rv); rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "CREATE UNIQUE INDEX unique_data ON test (data)" )); do_check_success(rv); }
NS_IMETHOD Run() { mozilla::ReentrantMonitorAutoEnter lock(monitor); WaitFor(READ_LOCK); nsCString sql(mSQL); nsCOMPtr<mozIStorageStatement> stmt; do_check_success(mConnection->CreateStatement(sql, getter_AddRefs(stmt))); bool hasResult; nsresult rv = stmt->ExecuteStep(&hasResult); do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED); // Finalize our statement and null out our connection before notifying to // ensure that we close on the proper thread. rv = stmt->Finalize(); do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED); mConnection = nullptr; Notify(TEST_DONE); return NS_OK; }
void Notify(State aState) { monitor.AssertCurrentThreadIn(); mState = aState; do_check_success(monitor.Notify()); }