test_transaction_helper.cpp (5829B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "storage_test_harness.h" 8 9 #include "mozStorageHelper.h" 10 #include "mozStorageConnection.h" 11 12 using namespace mozilla; 13 using namespace mozilla::storage; 14 15 bool has_transaction(mozIStorageConnection* aDB) { 16 return !(static_cast<Connection*>(aDB)->getAutocommit()); 17 } 18 19 /** 20 * This file tests our Transaction helper in mozStorageHelper.h. 21 */ 22 23 TEST(storage_transaction_helper, Commit) 24 { 25 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); 26 27 // Create a table in a transaction, call Commit, and make sure that it does 28 // exists after the transaction falls out of scope. 29 { 30 mozStorageTransaction transaction(db, false); 31 do_check_success(transaction.Start()); 32 do_check_true(has_transaction(db)); 33 (void)db->ExecuteSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns); 34 (void)transaction.Commit(); 35 } 36 do_check_false(has_transaction(db)); 37 38 bool exists = false; 39 (void)db->TableExists("test"_ns, &exists); 40 do_check_true(exists); 41 } 42 43 TEST(storage_transaction_helper, Rollback) 44 { 45 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); 46 47 // Create a table in a transaction, call Rollback, and make sure that it does 48 // not exists after the transaction falls out of scope. 49 { 50 mozStorageTransaction transaction(db, true); 51 do_check_success(transaction.Start()); 52 do_check_true(has_transaction(db)); 53 (void)db->ExecuteSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns); 54 (void)transaction.Rollback(); 55 } 56 do_check_false(has_transaction(db)); 57 58 bool exists = true; 59 (void)db->TableExists("test"_ns, &exists); 60 do_check_false(exists); 61 } 62 63 TEST(storage_transaction_helper, AutoCommit) 64 { 65 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); 66 67 // Create a table in a transaction, and make sure that it exists after the 68 // transaction falls out of scope. This means the Commit was successful. 69 { 70 mozStorageTransaction transaction(db, true); 71 do_check_success(transaction.Start()); 72 do_check_true(has_transaction(db)); 73 (void)db->ExecuteSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns); 74 } 75 do_check_false(has_transaction(db)); 76 77 bool exists = false; 78 (void)db->TableExists("test"_ns, &exists); 79 do_check_true(exists); 80 } 81 82 TEST(storage_transaction_helper, AutoRollback) 83 { 84 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); 85 86 // Create a table in a transaction, and make sure that it does not exists 87 // after the transaction falls out of scope. This means the Rollback was 88 // successful. 89 { 90 mozStorageTransaction transaction(db, false); 91 do_check_success(transaction.Start()); 92 do_check_true(has_transaction(db)); 93 (void)db->ExecuteSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns); 94 } 95 do_check_false(has_transaction(db)); 96 97 bool exists = true; 98 (void)db->TableExists("test"_ns, &exists); 99 do_check_false(exists); 100 } 101 102 TEST(storage_transaction_helper, null_database_connection) 103 { 104 // We permit the use of the Transaction helper when passing a null database 105 // in, so we need to make sure this still works without crashing. 106 mozStorageTransaction transaction(nullptr, false); 107 do_check_success(transaction.Start()); 108 do_check_true(NS_SUCCEEDED(transaction.Commit())); 109 do_check_true(NS_SUCCEEDED(transaction.Rollback())); 110 } 111 112 TEST(storage_transaction_helper, async_Commit) 113 { 114 HookSqliteMutex hook; 115 116 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); 117 118 // -- wedge the thread 119 nsCOMPtr<nsIThread> target(get_conn_async_thread(db)); 120 do_check_true(target); 121 RefPtr<ThreadWedger> wedger(new ThreadWedger(target)); 122 123 { 124 mozStorageTransaction transaction( 125 db, false, mozIStorageConnection::TRANSACTION_DEFERRED, true); 126 do_check_success(transaction.Start()); 127 do_check_true(has_transaction(db)); 128 (void)db->ExecuteSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns); 129 (void)transaction.Commit(); 130 } 131 do_check_true(has_transaction(db)); 132 133 // -- unwedge the async thread 134 wedger->unwedge(); 135 136 // Ensure the transaction has done its job by enqueueing an async execution. 137 nsCOMPtr<mozIStorageAsyncStatement> stmt; 138 (void)db->CreateAsyncStatement("SELECT NULL"_ns, getter_AddRefs(stmt)); 139 blocking_async_execute(stmt); 140 stmt->Finalize(); 141 do_check_false(has_transaction(db)); 142 bool exists = false; 143 (void)db->TableExists("test"_ns, &exists); 144 do_check_true(exists); 145 146 blocking_async_close(db); 147 } 148 149 TEST(storage_transaction_helper, Nesting) 150 { 151 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase()); 152 153 { 154 mozStorageTransaction transaction(db, false); 155 do_check_success(transaction.Start()); 156 do_check_true(has_transaction(db)); 157 do_check_success( 158 db->ExecuteSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns)); 159 160 { 161 mozStorageTransaction nestedTransaction(db, false); 162 do_check_success(nestedTransaction.Start()); 163 do_check_true(has_transaction(db)); 164 do_check_success(db->ExecuteSimpleSQL( 165 "CREATE TABLE nested_test (id INTEGER PRIMARY KEY)"_ns)); 166 167 #ifndef MOZ_DIAGNOSTIC_ASSERT_ENABLED 168 do_check_true(transaction.Commit() == NS_ERROR_NOT_AVAILABLE); 169 do_check_true(transaction.Rollback() == NS_ERROR_NOT_AVAILABLE); 170 #endif 171 } 172 173 bool exists = false; 174 do_check_success(db->TableExists("nested_test"_ns, &exists)); 175 do_check_false(exists); 176 177 (void)transaction.Commit(); 178 } 179 do_check_false(has_transaction(db)); 180 181 bool exists = false; 182 do_check_success(db->TableExists("test"_ns, &exists)); 183 do_check_true(exists); 184 }