blob: 1e6239b7de0109b22f4cc876f711881ccee8c898 [file] [log] [blame]
[email protected]3a305db2011-04-12 13:40:531// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]e5ffd0e42009-09-11 21:30:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Scott Graham47ed2c32017-09-15 02:17:075#include "sql/transaction.h"
Victor Costan49a903a2021-05-07 22:21:006
thestig22dfc4012014-09-05 08:29:447#include "base/files/file_util.h"
[email protected]ea1a3f62012-11-16 20:34:238#include "base/files/scoped_temp_dir.h"
Victor Costancfbfa602018-08-01 23:24:469#include "sql/database.h"
[email protected]f0a54b22011-07-19 18:40:2110#include "sql/statement.h"
[email protected]e5ffd0e42009-09-11 21:30:5611#include "testing/gtest/include/gtest/gtest.h"
[email protected]e33cba42010-08-18 23:37:0312#include "third_party/sqlite/sqlite3.h"
[email protected]e5ffd0e42009-09-11 21:30:5613
Victor Costan49a903a2021-05-07 22:21:0014namespace sql {
Victor Costan525b30a2021-05-05 17:54:1015
Victor Costan49a903a2021-05-07 22:21:0016namespace {
17
18class SQLTransactionTest : public testing::Test {
19 public:
20 ~SQLTransactionTest() override = default;
21
22 void SetUp() override {
23 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
24 ASSERT_TRUE(
25 db_.Open(temp_dir_.GetPath().AppendASCII("transaction_test.sqlite")));
26
27 ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a, b)"));
[email protected]e5ffd0e42009-09-11 21:30:5628 }
29
[email protected]e5ffd0e42009-09-11 21:30:5630 // Returns the number of rows in table "foo".
31 int CountFoo() {
Victor Costan49a903a2021-05-07 22:21:0032 Statement count(db_.GetUniqueStatement("SELECT count(*) FROM foo"));
[email protected]e5ffd0e42009-09-11 21:30:5633 count.Step();
34 return count.ColumnInt(0);
35 }
Victor Costan49a903a2021-05-07 22:21:0036
37 protected:
38 base::ScopedTempDir temp_dir_;
39 Database db_;
[email protected]e5ffd0e42009-09-11 21:30:5640};
41
42TEST_F(SQLTransactionTest, Commit) {
43 {
Victor Costan628afca2021-09-21 02:36:0944 Transaction transaction(&db_);
45 EXPECT_FALSE(db_.HasActiveTransactions());
46 EXPECT_FALSE(transaction.IsActiveForTesting());
[email protected]e5ffd0e42009-09-11 21:30:5647
Victor Costan628afca2021-09-21 02:36:0948 ASSERT_TRUE(transaction.Begin());
49 EXPECT_TRUE(db_.HasActiveTransactions());
50 EXPECT_TRUE(transaction.IsActiveForTesting());
[email protected]e5ffd0e42009-09-11 21:30:5651
Victor Costan628afca2021-09-21 02:36:0952 ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
53 ASSERT_EQ(1, CountFoo()) << "INSERT did not work as intended";
54
55 transaction.Commit();
56 EXPECT_FALSE(db_.HasActiveTransactions());
57 EXPECT_FALSE(transaction.IsActiveForTesting());
[email protected]e5ffd0e42009-09-11 21:30:5658 }
59
Victor Costan628afca2021-09-21 02:36:0960 EXPECT_FALSE(db_.HasActiveTransactions());
61 EXPECT_EQ(1, CountFoo()) << "Transaction changes not committed";
[email protected]e5ffd0e42009-09-11 21:30:5662}
63
Victor Costan628afca2021-09-21 02:36:0964TEST_F(SQLTransactionTest, RollbackOnDestruction) {
65 EXPECT_FALSE(db_.HasActiveTransactions());
[email protected]e5ffd0e42009-09-11 21:30:5666
Victor Costan628afca2021-09-21 02:36:0967 {
68 Transaction transaction(&db_);
69 EXPECT_FALSE(db_.HasActiveTransactions());
70 EXPECT_FALSE(transaction.IsActiveForTesting());
71
72 ASSERT_TRUE(transaction.Begin());
73 EXPECT_TRUE(db_.HasActiveTransactions());
74 EXPECT_TRUE(transaction.IsActiveForTesting());
75
76 ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
77 ASSERT_EQ(1, CountFoo()) << "INSERT did not work as intended";
[email protected]e5ffd0e42009-09-11 21:30:5678 }
79
Victor Costan628afca2021-09-21 02:36:0980 EXPECT_FALSE(db_.HasActiveTransactions());
81 EXPECT_EQ(0, CountFoo()) << "Transaction changes not rolled back";
82}
[email protected]e5ffd0e42009-09-11 21:30:5683
Victor Costan628afca2021-09-21 02:36:0984TEST_F(SQLTransactionTest, ExplicitRollback) {
85 EXPECT_FALSE(db_.HasActiveTransactions());
[email protected]e5ffd0e42009-09-11 21:30:5686
Victor Costan628afca2021-09-21 02:36:0987 {
88 Transaction transaction(&db_);
89 EXPECT_FALSE(db_.HasActiveTransactions());
90 EXPECT_FALSE(transaction.IsActiveForTesting());
[email protected]e5ffd0e42009-09-11 21:30:5691
Victor Costan628afca2021-09-21 02:36:0992 ASSERT_TRUE(transaction.Begin());
93 EXPECT_TRUE(db_.HasActiveTransactions());
94 EXPECT_TRUE(transaction.IsActiveForTesting());
95
96 ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
97 ASSERT_EQ(1, CountFoo()) << "INSERT did not work as intended";
98
99 transaction.Rollback();
100 EXPECT_FALSE(db_.HasActiveTransactions());
101 EXPECT_FALSE(transaction.IsActiveForTesting());
102 EXPECT_EQ(0, CountFoo()) << "Transaction changes not rolled back";
103 }
104
105 EXPECT_FALSE(db_.HasActiveTransactions());
106 EXPECT_EQ(0, CountFoo()) << "Transaction changes not rolled back";
[email protected]e5ffd0e42009-09-11 21:30:56107}
108
109// Rolling back any part of a transaction should roll back all of them.
110TEST_F(SQLTransactionTest, NestedRollback) {
Victor Costan628afca2021-09-21 02:36:09111 EXPECT_FALSE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00112 EXPECT_EQ(0, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56113
114 // Outermost transaction.
115 {
Victor Costan628afca2021-09-21 02:36:09116 Transaction outer_txn(&db_);
117 EXPECT_FALSE(db_.HasActiveTransactions());
118 EXPECT_EQ(0, db_.transaction_nesting());
119
120 ASSERT_TRUE(outer_txn.Begin());
121 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00122 EXPECT_EQ(1, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56123
Victor Costan628afca2021-09-21 02:36:09124 // First inner transaction is committed.
[email protected]e5ffd0e42009-09-11 21:30:56125 {
Victor Costan628afca2021-09-21 02:36:09126 Transaction committed_inner_txn(&db_);
127 EXPECT_TRUE(db_.HasActiveTransactions());
128 EXPECT_EQ(1, db_.transaction_nesting());
129
130 ASSERT_TRUE(committed_inner_txn.Begin());
131 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00132 EXPECT_EQ(2, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56133
Victor Costan628afca2021-09-21 02:36:09134 ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
135 ASSERT_EQ(1, CountFoo()) << "INSERT did not work as intended";
136
137 committed_inner_txn.Commit();
138 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00139 EXPECT_EQ(1, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56140 }
141
Victor Costan628afca2021-09-21 02:36:09142 EXPECT_TRUE(db_.HasActiveTransactions());
143 EXPECT_EQ(1, db_.transaction_nesting());
144 EXPECT_EQ(1, CountFoo()) << "First inner transaction did not commit";
[email protected]e5ffd0e42009-09-11 21:30:56145
Victor Costan628afca2021-09-21 02:36:09146 // Second inner transaction is rolled back.
[email protected]e5ffd0e42009-09-11 21:30:56147 {
Victor Costan628afca2021-09-21 02:36:09148 Transaction rolled_back_inner_txn(&db_);
149 EXPECT_TRUE(db_.HasActiveTransactions());
150 EXPECT_EQ(1, db_.transaction_nesting());
151
152 ASSERT_TRUE(rolled_back_inner_txn.Begin());
153 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00154 EXPECT_EQ(2, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56155
Victor Costan628afca2021-09-21 02:36:09156 ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (2, 3)"));
157 ASSERT_EQ(2, CountFoo()) << "INSERT did not work as intended";
158
159 rolled_back_inner_txn.Rollback();
160 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00161 EXPECT_EQ(1, db_.transaction_nesting());
Victor Costan628afca2021-09-21 02:36:09162 EXPECT_EQ(2, CountFoo())
163 << "Nested transaction rollback deferred to top-level transaction";
[email protected]e5ffd0e42009-09-11 21:30:56164 }
165
Victor Costan628afca2021-09-21 02:36:09166 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00167 EXPECT_EQ(1, db_.transaction_nesting());
Victor Costan628afca2021-09-21 02:36:09168 EXPECT_EQ(2, CountFoo())
169 << "Nested transaction rollback deferred to top-level transaction";
170
171 // Third inner transaction fails in Begin(), because a nested transaction
172 // has already been rolled back.
[email protected]e5ffd0e42009-09-11 21:30:56173 {
Victor Costan628afca2021-09-21 02:36:09174 Transaction failed_inner_txn(&db_);
175 EXPECT_TRUE(db_.HasActiveTransactions());
176 EXPECT_EQ(1, db_.transaction_nesting());
177
178 EXPECT_FALSE(failed_inner_txn.Begin());
179 EXPECT_TRUE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00180 EXPECT_EQ(1, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56181 }
182 }
Victor Costan628afca2021-09-21 02:36:09183
184 EXPECT_FALSE(db_.HasActiveTransactions());
Victor Costan49a903a2021-05-07 22:21:00185 EXPECT_EQ(0, db_.transaction_nesting());
[email protected]e5ffd0e42009-09-11 21:30:56186 EXPECT_EQ(0, CountFoo());
187}
Victor Costan49a903a2021-05-07 22:21:00188
189} // namespace
190
191} // namespace sql