Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: sql/connection_unittest.cc

Issue 17726002: [sql] Callback and scoped-ignore tests for sql::Statement. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: prevent nesting, TODO. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sql/connection.cc ('k') | sql/sql.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/bind.h" 5 #include "base/bind.h"
6 #include "base/file_util.h" 6 #include "base/file_util.h"
7 #include "base/files/scoped_temp_dir.h" 7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "sql/connection.h" 9 #include "sql/connection.h"
10 #include "sql/meta_table.h" 10 #include "sql/meta_table.h"
11 #include "sql/statement.h" 11 #include "sql/statement.h"
12 #include "sql/test/error_callback_support.h"
12 #include "sql/test/scoped_error_ignorer.h" 13 #include "sql/test/scoped_error_ignorer.h"
13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/sqlite/sqlite3.h" 15 #include "third_party/sqlite/sqlite3.h"
15 16
16 namespace { 17 namespace {
17 18
18 // Helper to return the count of items in sqlite_master. Return -1 in 19 // Helper to return the count of items in sqlite_master. Return -1 in
19 // case of error. 20 // case of error.
20 int SqliteMasterCount(sql::Connection* db) { 21 int SqliteMasterCount(sql::Connection* db) {
21 const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master"; 22 const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
22 sql::Statement s(db->GetUniqueStatement(kMasterCount)); 23 sql::Statement s(db->GetUniqueStatement(kMasterCount));
23 return s.Step() ? s.ColumnInt(0) : -1; 24 return s.Step() ? s.ColumnInt(0) : -1;
24 } 25 }
25 26
27 // Track the number of valid references which share the same pointer.
28 // This is used to allow testing an implicitly use-after-free case by
29 // explicitly having the ref count live longer than the object.
30 class RefCounter {
31 public:
32 RefCounter(size_t* counter)
33 : counter_(counter) {
34 (*counter_)++;
35 }
36 RefCounter(const RefCounter& other)
37 : counter_(other.counter_) {
38 (*counter_)++;
39 }
40 ~RefCounter() {
41 (*counter_)--;
42 }
43
44 private:
45 size_t* counter_;
46
47 DISALLOW_ASSIGN(RefCounter);
48 };
49
50 // Empty callback for implementation of ErrorCallbackSetHelper().
51 void IgnoreErrorCallback(int error, sql::Statement* stmt) {
52 }
53
54 void ErrorCallbackSetHelper(sql::Connection* db,
55 size_t* counter,
56 const RefCounter& r,
57 int error, sql::Statement* stmt) {
58 // The ref count should not go to zero when changing the callback.
59 EXPECT_GT(*counter, 0u);
60 db->set_error_callback(base::Bind(&IgnoreErrorCallback));
61 EXPECT_GT(*counter, 0u);
62 }
63
64 void ErrorCallbackResetHelper(sql::Connection* db,
65 size_t* counter,
66 const RefCounter& r,
67 int error, sql::Statement* stmt) {
68 // The ref count should not go to zero when clearing the callback.
69 EXPECT_GT(*counter, 0u);
70 db->reset_error_callback();
71 EXPECT_GT(*counter, 0u);
72 }
73
26 class SQLConnectionTest : public testing::Test { 74 class SQLConnectionTest : public testing::Test {
27 public: 75 public:
28 SQLConnectionTest() {} 76 SQLConnectionTest() {}
29 77
30 virtual void SetUp() { 78 virtual void SetUp() {
31 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 79 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
32 ASSERT_TRUE(db_.Open(db_path())); 80 ASSERT_TRUE(db_.Open(db_path()));
33 } 81 }
34 82
35 virtual void TearDown() { 83 virtual void TearDown() {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)"; 208 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
161 ASSERT_TRUE(db().Execute(kCreateSql)); 209 ASSERT_TRUE(db().Execute(kCreateSql));
162 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 210 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
163 211
164 sql::ScopedErrorIgnorer ignore_errors; 212 sql::ScopedErrorIgnorer ignore_errors;
165 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); 213 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
166 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 214 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
167 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 215 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
168 } 216 }
169 217
218 TEST_F(SQLConnectionTest, ErrorCallback) {
219 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
220 ASSERT_TRUE(db().Execute(kCreateSql));
221 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
222
223 int error = SQLITE_OK;
224 {
225 sql::ScopedErrorCallback sec(
226 &db(), base::Bind(&sql::CaptureErrorCallback, &error));
227
228 // Inserting something other than a number into the primary key
229 // should result in the callback seeing SQLITE_MISMATCH.
230 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
231 EXPECT_EQ(SQLITE_CONSTRAINT, error);
232 }
233
234 // Callback is no longer in force due to reset.
235 {
236 error = SQLITE_OK;
237 sql::ScopedErrorIgnorer ignore_errors;
238 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
239 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
240 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
241 EXPECT_EQ(SQLITE_OK, error);
242 }
243
244 // base::Bind() can curry arguments to be passed by const reference
245 // to the callback function. If the callback function causes
246 // re/set_error_callback() to be called, the storage for those
247 // arguments can be deleted.
248 //
249 // RefCounter() counts how many objects are live using an external
250 // count. The same counter is passed to the callback, so that it
251 // can check directly even if the RefCounter object is no longer
252 // live.
253 {
254 size_t count = 0;
255 sql::ScopedErrorCallback sec(
256 &db(), base::Bind(&ErrorCallbackSetHelper,
257 &db(), &count, RefCounter(&count)));
258
259 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
260 }
261
262 // Same test, but reset_error_callback() case.
263 {
264 size_t count = 0;
265 sql::ScopedErrorCallback sec(
266 &db(), base::Bind(&ErrorCallbackResetHelper,
267 &db(), &count, RefCounter(&count)));
268
269 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
270 }
271 }
272
170 // Test that sql::Connection::Raze() results in a database without the 273 // Test that sql::Connection::Raze() results in a database without the
171 // tables from the original database. 274 // tables from the original database.
172 TEST_F(SQLConnectionTest, Raze) { 275 TEST_F(SQLConnectionTest, Raze) {
173 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 276 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
174 ASSERT_TRUE(db().Execute(kCreateSql)); 277 ASSERT_TRUE(db().Execute(kCreateSql));
175 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)")); 278 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
176 279
177 int pragma_auto_vacuum = 0; 280 int pragma_auto_vacuum = 0;
178 { 281 {
179 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum")); 282 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal")); 656 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
554 ASSERT_TRUE(file_util::PathExists(db_path())); 657 ASSERT_TRUE(file_util::PathExists(db_path()));
555 ASSERT_TRUE(file_util::PathExists(journal)); 658 ASSERT_TRUE(file_util::PathExists(journal));
556 659
557 sql::Connection::Delete(db_path()); 660 sql::Connection::Delete(db_path());
558 EXPECT_FALSE(file_util::PathExists(db_path())); 661 EXPECT_FALSE(file_util::PathExists(db_path()));
559 EXPECT_FALSE(file_util::PathExists(journal)); 662 EXPECT_FALSE(file_util::PathExists(journal));
560 } 663 }
561 664
562 } // namespace 665 } // namespace
OLDNEW
« no previous file with comments | « sql/connection.cc ('k') | sql/sql.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698