Center distiller results on desktop
[chromium-blink-merge.git] / sql / connection_unittest.cc
blob24d21faa28f7806d66841f83aee89d1c27990ec2
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
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_file.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/logging.h"
10 #include "sql/connection.h"
11 #include "sql/meta_table.h"
12 #include "sql/statement.h"
13 #include "sql/test/error_callback_support.h"
14 #include "sql/test/scoped_error_ignorer.h"
15 #include "sql/test/test_helpers.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/sqlite/sqlite3.h"
19 namespace {
21 // Helper to return the count of items in sqlite_master. Return -1 in
22 // case of error.
23 int SqliteMasterCount(sql::Connection* db) {
24 const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
25 sql::Statement s(db->GetUniqueStatement(kMasterCount));
26 return s.Step() ? s.ColumnInt(0) : -1;
29 // Track the number of valid references which share the same pointer.
30 // This is used to allow testing an implicitly use-after-free case by
31 // explicitly having the ref count live longer than the object.
32 class RefCounter {
33 public:
34 RefCounter(size_t* counter)
35 : counter_(counter) {
36 (*counter_)++;
38 RefCounter(const RefCounter& other)
39 : counter_(other.counter_) {
40 (*counter_)++;
42 ~RefCounter() {
43 (*counter_)--;
46 private:
47 size_t* counter_;
49 DISALLOW_ASSIGN(RefCounter);
52 // Empty callback for implementation of ErrorCallbackSetHelper().
53 void IgnoreErrorCallback(int error, sql::Statement* stmt) {
56 void ErrorCallbackSetHelper(sql::Connection* db,
57 size_t* counter,
58 const RefCounter& r,
59 int error, sql::Statement* stmt) {
60 // The ref count should not go to zero when changing the callback.
61 EXPECT_GT(*counter, 0u);
62 db->set_error_callback(base::Bind(&IgnoreErrorCallback));
63 EXPECT_GT(*counter, 0u);
66 void ErrorCallbackResetHelper(sql::Connection* db,
67 size_t* counter,
68 const RefCounter& r,
69 int error, sql::Statement* stmt) {
70 // The ref count should not go to zero when clearing the callback.
71 EXPECT_GT(*counter, 0u);
72 db->reset_error_callback();
73 EXPECT_GT(*counter, 0u);
76 #if defined(OS_POSIX)
77 // Set a umask and restore the old mask on destruction. Cribbed from
78 // shared_memory_unittest.cc. Used by POSIX-only UserPermission test.
79 class ScopedUmaskSetter {
80 public:
81 explicit ScopedUmaskSetter(mode_t target_mask) {
82 old_umask_ = umask(target_mask);
84 ~ScopedUmaskSetter() { umask(old_umask_); }
85 private:
86 mode_t old_umask_;
87 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
89 #endif
91 class SQLConnectionTest : public testing::Test {
92 public:
93 void SetUp() override {
94 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
95 db_path_ = temp_dir_.path().AppendASCII("SQLConnectionTest.db");
96 ASSERT_TRUE(db_.Open(db_path_));
99 void TearDown() override { db_.Close(); }
101 sql::Connection& db() { return db_; }
102 const base::FilePath& db_path() { return db_path_; }
104 // Handle errors by blowing away the database.
105 void RazeErrorCallback(int expected_error, int error, sql::Statement* stmt) {
106 EXPECT_EQ(expected_error, error);
107 db_.RazeAndClose();
110 private:
111 sql::Connection db_;
112 base::FilePath db_path_;
113 base::ScopedTempDir temp_dir_;
116 TEST_F(SQLConnectionTest, Execute) {
117 // Valid statement should return true.
118 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
119 EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
121 // Invalid statement should fail.
122 ASSERT_EQ(SQLITE_ERROR,
123 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
124 EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
127 TEST_F(SQLConnectionTest, ExecuteWithErrorCode) {
128 ASSERT_EQ(SQLITE_OK,
129 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
130 ASSERT_EQ(SQLITE_ERROR,
131 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
132 ASSERT_EQ(SQLITE_ERROR,
133 db().ExecuteAndReturnErrorCode(
134 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
137 TEST_F(SQLConnectionTest, CachedStatement) {
138 sql::StatementID id1("foo", 12);
140 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
141 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
143 // Create a new cached statement.
145 sql::Statement s(db().GetCachedStatement(id1, "SELECT a FROM foo"));
146 ASSERT_TRUE(s.is_valid());
148 ASSERT_TRUE(s.Step());
149 EXPECT_EQ(12, s.ColumnInt(0));
152 // The statement should be cached still.
153 EXPECT_TRUE(db().HasCachedStatement(id1));
156 // Get the same statement using different SQL. This should ignore our
157 // SQL and use the cached one (so it will be valid).
158 sql::Statement s(db().GetCachedStatement(id1, "something invalid("));
159 ASSERT_TRUE(s.is_valid());
161 ASSERT_TRUE(s.Step());
162 EXPECT_EQ(12, s.ColumnInt(0));
165 // Make sure other statements aren't marked as cached.
166 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE));
169 TEST_F(SQLConnectionTest, IsSQLValidTest) {
170 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
171 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
172 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
175 TEST_F(SQLConnectionTest, DoesStuffExist) {
176 // Test DoesTableExist.
177 EXPECT_FALSE(db().DoesTableExist("foo"));
178 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
179 ASSERT_TRUE(db().Execute("CREATE INDEX foo_a ON foo (a)"));
180 EXPECT_TRUE(db().DoesTableExist("foo"));
181 EXPECT_TRUE(db().DoesIndexExist("foo_a"));
183 // Test DoesColumnExist.
184 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
185 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
187 // Testing for a column on a nonexistent table.
188 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
190 // Names are not case sensitive.
191 EXPECT_TRUE(db().DoesTableExist("FOO"));
192 EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
195 TEST_F(SQLConnectionTest, GetLastInsertRowId) {
196 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
198 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
200 // Last insert row ID should be valid.
201 int64 row = db().GetLastInsertRowId();
202 EXPECT_LT(0, row);
204 // It should be the primary key of the row we just inserted.
205 sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
206 s.BindInt64(0, row);
207 ASSERT_TRUE(s.Step());
208 EXPECT_EQ(12, s.ColumnInt(0));
211 TEST_F(SQLConnectionTest, Rollback) {
212 ASSERT_TRUE(db().BeginTransaction());
213 ASSERT_TRUE(db().BeginTransaction());
214 EXPECT_EQ(2, db().transaction_nesting());
215 db().RollbackTransaction();
216 EXPECT_FALSE(db().CommitTransaction());
217 EXPECT_TRUE(db().BeginTransaction());
220 // Test the scoped error ignorer by attempting to insert a duplicate
221 // value into an index.
222 TEST_F(SQLConnectionTest, ScopedIgnoreError) {
223 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
224 ASSERT_TRUE(db().Execute(kCreateSql));
225 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
228 sql::ScopedErrorIgnorer ignore_errors;
229 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
230 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
231 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
235 // Test that clients of GetUntrackedStatement() can test corruption-handling
236 // with ScopedErrorIgnorer.
237 TEST_F(SQLConnectionTest, ScopedIgnoreUntracked) {
238 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
239 ASSERT_TRUE(db().Execute(kCreateSql));
240 ASSERT_FALSE(db().DoesTableExist("bar"));
241 ASSERT_TRUE(db().DoesTableExist("foo"));
242 ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
243 db().Close();
245 // Corrupt the database so that nothing works, including PRAGMAs.
246 ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
249 sql::ScopedErrorIgnorer ignore_errors;
250 ignore_errors.IgnoreError(SQLITE_CORRUPT);
251 ASSERT_TRUE(db().Open(db_path()));
252 ASSERT_FALSE(db().DoesTableExist("bar"));
253 ASSERT_FALSE(db().DoesTableExist("foo"));
254 ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
255 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
259 TEST_F(SQLConnectionTest, ErrorCallback) {
260 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
261 ASSERT_TRUE(db().Execute(kCreateSql));
262 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
264 int error = SQLITE_OK;
266 sql::ScopedErrorCallback sec(
267 &db(), base::Bind(&sql::CaptureErrorCallback, &error));
268 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
270 // Later versions of SQLite throw SQLITE_CONSTRAINT_UNIQUE. The specific
271 // sub-error isn't really important.
272 EXPECT_EQ(SQLITE_CONSTRAINT, (error&0xff));
275 // Callback is no longer in force due to reset.
277 error = SQLITE_OK;
278 sql::ScopedErrorIgnorer ignore_errors;
279 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
280 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
281 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
282 EXPECT_EQ(SQLITE_OK, error);
285 // base::Bind() can curry arguments to be passed by const reference
286 // to the callback function. If the callback function calls
287 // re/set_error_callback(), the storage for those arguments can be
288 // deleted while the callback function is still executing.
290 // RefCounter() counts how many objects are live using an external
291 // count. The same counter is passed to the callback, so that it
292 // can check directly even if the RefCounter object is no longer
293 // live.
295 size_t count = 0;
296 sql::ScopedErrorCallback sec(
297 &db(), base::Bind(&ErrorCallbackSetHelper,
298 &db(), &count, RefCounter(&count)));
300 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
303 // Same test, but reset_error_callback() case.
305 size_t count = 0;
306 sql::ScopedErrorCallback sec(
307 &db(), base::Bind(&ErrorCallbackResetHelper,
308 &db(), &count, RefCounter(&count)));
310 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
314 // Test that sql::Connection::Raze() results in a database without the
315 // tables from the original database.
316 TEST_F(SQLConnectionTest, Raze) {
317 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
318 ASSERT_TRUE(db().Execute(kCreateSql));
319 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
321 int pragma_auto_vacuum = 0;
323 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
324 ASSERT_TRUE(s.Step());
325 pragma_auto_vacuum = s.ColumnInt(0);
326 ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
329 // If auto_vacuum is set, there's an extra page to maintain a freelist.
330 const int kExpectedPageCount = 2 + pragma_auto_vacuum;
333 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
334 ASSERT_TRUE(s.Step());
335 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
339 sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
340 ASSERT_TRUE(s.Step());
341 EXPECT_EQ("table", s.ColumnString(0));
342 EXPECT_EQ("foo", s.ColumnString(1));
343 EXPECT_EQ("foo", s.ColumnString(2));
344 // Table "foo" is stored in the last page of the file.
345 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3));
346 EXPECT_EQ(kCreateSql, s.ColumnString(4));
349 ASSERT_TRUE(db().Raze());
352 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
353 ASSERT_TRUE(s.Step());
354 EXPECT_EQ(1, s.ColumnInt(0));
357 ASSERT_EQ(0, SqliteMasterCount(&db()));
360 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
361 ASSERT_TRUE(s.Step());
362 // The new database has the same auto_vacuum as a fresh database.
363 EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
367 // Test that Raze() maintains page_size.
368 TEST_F(SQLConnectionTest, RazePageSize) {
369 // Fetch the default page size and double it for use in this test.
370 // Scoped to release statement before Close().
371 int default_page_size = 0;
373 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
374 ASSERT_TRUE(s.Step());
375 default_page_size = s.ColumnInt(0);
377 ASSERT_GT(default_page_size, 0);
378 const int kPageSize = 2 * default_page_size;
380 // Re-open the database to allow setting the page size.
381 db().Close();
382 db().set_page_size(kPageSize);
383 ASSERT_TRUE(db().Open(db_path()));
385 // page_size should match the indicated value.
386 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
387 ASSERT_TRUE(s.Step());
388 ASSERT_EQ(kPageSize, s.ColumnInt(0));
390 // After raze, page_size should still match the indicated value.
391 ASSERT_TRUE(db().Raze());
392 s.Reset(true);
393 ASSERT_TRUE(s.Step());
394 ASSERT_EQ(kPageSize, s.ColumnInt(0));
397 // Test that Raze() results are seen in other connections.
398 TEST_F(SQLConnectionTest, RazeMultiple) {
399 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
400 ASSERT_TRUE(db().Execute(kCreateSql));
402 sql::Connection other_db;
403 ASSERT_TRUE(other_db.Open(db_path()));
405 // Check that the second connection sees the table.
406 ASSERT_EQ(1, SqliteMasterCount(&other_db));
408 ASSERT_TRUE(db().Raze());
410 // The second connection sees the updated database.
411 ASSERT_EQ(0, SqliteMasterCount(&other_db));
414 TEST_F(SQLConnectionTest, RazeLocked) {
415 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
416 ASSERT_TRUE(db().Execute(kCreateSql));
418 // Open a transaction and write some data in a second connection.
419 // This will acquire a PENDING or EXCLUSIVE transaction, which will
420 // cause the raze to fail.
421 sql::Connection other_db;
422 ASSERT_TRUE(other_db.Open(db_path()));
423 ASSERT_TRUE(other_db.BeginTransaction());
424 const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
425 ASSERT_TRUE(other_db.Execute(kInsertSql));
427 ASSERT_FALSE(db().Raze());
429 // Works after COMMIT.
430 ASSERT_TRUE(other_db.CommitTransaction());
431 ASSERT_TRUE(db().Raze());
433 // Re-create the database.
434 ASSERT_TRUE(db().Execute(kCreateSql));
435 ASSERT_TRUE(db().Execute(kInsertSql));
437 // An unfinished read transaction in the other connection also
438 // blocks raze.
439 const char *kQuery = "SELECT COUNT(*) FROM foo";
440 sql::Statement s(other_db.GetUniqueStatement(kQuery));
441 ASSERT_TRUE(s.Step());
442 ASSERT_FALSE(db().Raze());
444 // Complete the statement unlocks the database.
445 ASSERT_FALSE(s.Step());
446 ASSERT_TRUE(db().Raze());
449 // Verify that Raze() can handle an empty file. SQLite should treat
450 // this as an empty database.
451 TEST_F(SQLConnectionTest, RazeEmptyDB) {
452 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
453 ASSERT_TRUE(db().Execute(kCreateSql));
454 db().Close();
457 base::ScopedFILE file(base::OpenFile(db_path(), "rb+"));
458 ASSERT_TRUE(file.get() != NULL);
459 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET));
460 ASSERT_TRUE(base::TruncateFile(file.get()));
463 ASSERT_TRUE(db().Open(db_path()));
464 ASSERT_TRUE(db().Raze());
465 EXPECT_EQ(0, SqliteMasterCount(&db()));
468 // Verify that Raze() can handle a file of junk.
469 TEST_F(SQLConnectionTest, RazeNOTADB) {
470 db().Close();
471 sql::Connection::Delete(db_path());
472 ASSERT_FALSE(base::PathExists(db_path()));
475 base::ScopedFILE file(base::OpenFile(db_path(), "wb"));
476 ASSERT_TRUE(file.get() != NULL);
478 const char* kJunk = "This is the hour of our discontent.";
479 fputs(kJunk, file.get());
481 ASSERT_TRUE(base::PathExists(db_path()));
483 // SQLite will successfully open the handle, but fail when running PRAGMA
484 // statements that access the database.
486 sql::ScopedErrorIgnorer ignore_errors;
488 // Earlier versions of Chromium compiled against SQLite 3.6.7.3, which
489 // returned SQLITE_IOERR_SHORT_READ in this case. Some platforms may still
490 // compile against an earlier SQLite via USE_SYSTEM_SQLITE.
491 if (ignore_errors.SQLiteLibVersionNumber() < 3008005) {
492 ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ);
493 } else {
494 ignore_errors.IgnoreError(SQLITE_NOTADB);
497 EXPECT_TRUE(db().Open(db_path()));
498 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
500 EXPECT_TRUE(db().Raze());
501 db().Close();
503 // Now empty, the open should open an empty database.
504 EXPECT_TRUE(db().Open(db_path()));
505 EXPECT_EQ(0, SqliteMasterCount(&db()));
508 // Verify that Raze() can handle a database overwritten with garbage.
509 TEST_F(SQLConnectionTest, RazeNOTADB2) {
510 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
511 ASSERT_TRUE(db().Execute(kCreateSql));
512 ASSERT_EQ(1, SqliteMasterCount(&db()));
513 db().Close();
516 base::ScopedFILE file(base::OpenFile(db_path(), "rb+"));
517 ASSERT_TRUE(file.get() != NULL);
518 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET));
520 const char* kJunk = "This is the hour of our discontent.";
521 fputs(kJunk, file.get());
524 // SQLite will successfully open the handle, but will fail with
525 // SQLITE_NOTADB on pragma statemenets which attempt to read the
526 // corrupted header.
528 sql::ScopedErrorIgnorer ignore_errors;
529 ignore_errors.IgnoreError(SQLITE_NOTADB);
530 EXPECT_TRUE(db().Open(db_path()));
531 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
533 EXPECT_TRUE(db().Raze());
534 db().Close();
536 // Now empty, the open should succeed with an empty database.
537 EXPECT_TRUE(db().Open(db_path()));
538 EXPECT_EQ(0, SqliteMasterCount(&db()));
541 // Test that a callback from Open() can raze the database. This is
542 // essential for cases where the Open() can fail entirely, so the
543 // Raze() cannot happen later. Additionally test that when the
544 // callback does this during Open(), the open is retried and succeeds.
545 TEST_F(SQLConnectionTest, RazeCallbackReopen) {
546 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
547 ASSERT_TRUE(db().Execute(kCreateSql));
548 ASSERT_EQ(1, SqliteMasterCount(&db()));
549 db().Close();
551 // Corrupt the database so that nothing works, including PRAGMAs.
552 ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
554 // Open() will succeed, even though the PRAGMA calls within will
555 // fail with SQLITE_CORRUPT, as will this PRAGMA.
557 sql::ScopedErrorIgnorer ignore_errors;
558 ignore_errors.IgnoreError(SQLITE_CORRUPT);
559 ASSERT_TRUE(db().Open(db_path()));
560 ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
561 db().Close();
562 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
565 db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback,
566 base::Unretained(this),
567 SQLITE_CORRUPT));
569 // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
570 // callback will call RazeAndClose(). Open() will then fail and be
571 // retried. The second Open() on the empty database will succeed
572 // cleanly.
573 ASSERT_TRUE(db().Open(db_path()));
574 ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
575 EXPECT_EQ(0, SqliteMasterCount(&db()));
578 // Basic test of RazeAndClose() operation.
579 TEST_F(SQLConnectionTest, RazeAndClose) {
580 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
581 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
583 // Test that RazeAndClose() closes the database, and that the
584 // database is empty when re-opened.
585 ASSERT_TRUE(db().Execute(kCreateSql));
586 ASSERT_TRUE(db().Execute(kPopulateSql));
587 ASSERT_TRUE(db().RazeAndClose());
588 ASSERT_FALSE(db().is_open());
589 db().Close();
590 ASSERT_TRUE(db().Open(db_path()));
591 ASSERT_EQ(0, SqliteMasterCount(&db()));
593 // Test that RazeAndClose() can break transactions.
594 ASSERT_TRUE(db().Execute(kCreateSql));
595 ASSERT_TRUE(db().Execute(kPopulateSql));
596 ASSERT_TRUE(db().BeginTransaction());
597 ASSERT_TRUE(db().RazeAndClose());
598 ASSERT_FALSE(db().is_open());
599 ASSERT_FALSE(db().CommitTransaction());
600 db().Close();
601 ASSERT_TRUE(db().Open(db_path()));
602 ASSERT_EQ(0, SqliteMasterCount(&db()));
605 // Test that various operations fail without crashing after
606 // RazeAndClose().
607 TEST_F(SQLConnectionTest, RazeAndCloseDiagnostics) {
608 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
609 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
610 const char* kSimpleSql = "SELECT 1";
612 ASSERT_TRUE(db().Execute(kCreateSql));
613 ASSERT_TRUE(db().Execute(kPopulateSql));
615 // Test baseline expectations.
616 db().Preload();
617 ASSERT_TRUE(db().DoesTableExist("foo"));
618 ASSERT_TRUE(db().IsSQLValid(kSimpleSql));
619 ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql));
620 ASSERT_TRUE(db().Execute(kSimpleSql));
621 ASSERT_TRUE(db().is_open());
623 sql::Statement s(db().GetUniqueStatement(kSimpleSql));
624 ASSERT_TRUE(s.Step());
627 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
628 ASSERT_TRUE(s.Step());
630 ASSERT_TRUE(db().BeginTransaction());
631 ASSERT_TRUE(db().CommitTransaction());
632 ASSERT_TRUE(db().BeginTransaction());
633 db().RollbackTransaction();
635 ASSERT_TRUE(db().RazeAndClose());
637 // At this point, they should all fail, but not crash.
638 db().Preload();
639 ASSERT_FALSE(db().DoesTableExist("foo"));
640 ASSERT_FALSE(db().IsSQLValid(kSimpleSql));
641 ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql));
642 ASSERT_FALSE(db().Execute(kSimpleSql));
643 ASSERT_FALSE(db().is_open());
645 sql::Statement s(db().GetUniqueStatement(kSimpleSql));
646 ASSERT_FALSE(s.Step());
649 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
650 ASSERT_FALSE(s.Step());
652 ASSERT_FALSE(db().BeginTransaction());
653 ASSERT_FALSE(db().CommitTransaction());
654 ASSERT_FALSE(db().BeginTransaction());
655 db().RollbackTransaction();
657 // Close normally to reset the poisoned flag.
658 db().Close();
660 // DEATH tests not supported on Android or iOS.
661 #if !defined(OS_ANDROID) && !defined(OS_IOS)
662 // Once the real Close() has been called, various calls enforce API
663 // usage by becoming fatal in debug mode. Since DEATH tests are
664 // expensive, just test one of them.
665 if (DLOG_IS_ON(FATAL)) {
666 ASSERT_DEATH({
667 db().IsSQLValid(kSimpleSql);
668 }, "Illegal use of connection without a db");
670 #endif
673 // TODO(shess): Spin up a background thread to hold other_db, to more
674 // closely match real life. That would also allow testing
675 // RazeWithTimeout().
677 #if defined(OS_ANDROID)
678 TEST_F(SQLConnectionTest, SetTempDirForSQL) {
680 sql::MetaTable meta_table;
681 // Below call needs a temporary directory in sqlite3
682 // On Android, it can pass only when the temporary directory is set.
683 // Otherwise, sqlite3 doesn't find the correct directory to store
684 // temporary files and will report the error 'unable to open
685 // database file'.
686 ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
688 #endif
690 TEST_F(SQLConnectionTest, Delete) {
691 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
692 db().Close();
694 // Should have both a main database file and a journal file because
695 // of journal_mode PERSIST.
696 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
697 ASSERT_TRUE(base::PathExists(db_path()));
698 ASSERT_TRUE(base::PathExists(journal));
700 sql::Connection::Delete(db_path());
701 EXPECT_FALSE(base::PathExists(db_path()));
702 EXPECT_FALSE(base::PathExists(journal));
705 #if defined(OS_POSIX)
706 // Test that set_restrict_to_user() trims database permissions so that
707 // only the owner (and root) can read.
708 TEST_F(SQLConnectionTest, UserPermission) {
709 // If the bots all had a restrictive umask setting such that
710 // databases are always created with only the owner able to read
711 // them, then the code could break without breaking the tests.
712 // Temporarily provide a more permissive umask.
713 db().Close();
714 sql::Connection::Delete(db_path());
715 ASSERT_FALSE(base::PathExists(db_path()));
716 ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
717 ASSERT_TRUE(db().Open(db_path()));
719 // Cause the journal file to be created. If the default
720 // journal_mode is changed back to DELETE, then parts of this test
721 // will need to be updated.
722 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
724 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
725 int mode;
727 // Given a permissive umask, the database is created with permissive
728 // read access for the database and journal.
729 ASSERT_TRUE(base::PathExists(db_path()));
730 ASSERT_TRUE(base::PathExists(journal));
731 mode = base::FILE_PERMISSION_MASK;
732 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
733 ASSERT_NE((mode & base::FILE_PERMISSION_USER_MASK), mode);
734 mode = base::FILE_PERMISSION_MASK;
735 EXPECT_TRUE(base::GetPosixFilePermissions(journal, &mode));
736 ASSERT_NE((mode & base::FILE_PERMISSION_USER_MASK), mode);
738 // Re-open with restricted permissions and verify that the modes
739 // changed for both the main database and the journal.
740 db().Close();
741 db().set_restrict_to_user();
742 ASSERT_TRUE(db().Open(db_path()));
743 ASSERT_TRUE(base::PathExists(db_path()));
744 ASSERT_TRUE(base::PathExists(journal));
745 mode = base::FILE_PERMISSION_MASK;
746 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
747 ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
748 mode = base::FILE_PERMISSION_MASK;
749 EXPECT_TRUE(base::GetPosixFilePermissions(journal, &mode));
750 ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
752 // Delete and re-create the database, the restriction should still apply.
753 db().Close();
754 sql::Connection::Delete(db_path());
755 ASSERT_TRUE(db().Open(db_path()));
756 ASSERT_TRUE(base::PathExists(db_path()));
757 ASSERT_FALSE(base::PathExists(journal));
758 mode = base::FILE_PERMISSION_MASK;
759 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
760 ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
762 // Verify that journal creation inherits the restriction.
763 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
764 ASSERT_TRUE(base::PathExists(journal));
765 mode = base::FILE_PERMISSION_MASK;
766 EXPECT_TRUE(base::GetPosixFilePermissions(journal, &mode));
767 ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
769 #endif // defined(OS_POSIX)
771 // Test that errors start happening once Poison() is called.
772 TEST_F(SQLConnectionTest, Poison) {
773 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
775 // Before the Poison() call, things generally work.
776 EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
777 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
779 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
780 ASSERT_TRUE(s.is_valid());
781 ASSERT_TRUE(s.Step());
784 // Get a statement which is valid before and will exist across Poison().
785 sql::Statement valid_statement(
786 db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
787 ASSERT_TRUE(valid_statement.is_valid());
788 ASSERT_TRUE(valid_statement.Step());
789 valid_statement.Reset(true);
791 db().Poison();
793 // After the Poison() call, things fail.
794 EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
795 EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
797 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
798 ASSERT_FALSE(s.is_valid());
799 ASSERT_FALSE(s.Step());
802 // The existing statement has become invalid.
803 ASSERT_FALSE(valid_statement.is_valid());
804 ASSERT_FALSE(valid_statement.Step());
807 // Test attaching and detaching databases from the connection.
808 TEST_F(SQLConnectionTest, Attach) {
809 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
811 // Create a database to attach to.
812 base::FilePath attach_path =
813 db_path().DirName().AppendASCII("SQLConnectionAttach.db");
814 const char kAttachmentPoint[] = "other";
816 sql::Connection other_db;
817 ASSERT_TRUE(other_db.Open(attach_path));
818 EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
819 EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
822 // Cannot see the attached database, yet.
823 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
825 // Attach fails in a transaction.
826 EXPECT_TRUE(db().BeginTransaction());
828 sql::ScopedErrorIgnorer ignore_errors;
829 ignore_errors.IgnoreError(SQLITE_ERROR);
830 EXPECT_FALSE(db().AttachDatabase(attach_path, kAttachmentPoint));
831 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
834 // Attach succeeds when the transaction is closed.
835 db().RollbackTransaction();
836 EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint));
837 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
839 // Queries can touch both databases.
840 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
842 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
843 ASSERT_TRUE(s.Step());
844 EXPECT_EQ(1, s.ColumnInt(0));
847 // Detach also fails in a transaction.
848 EXPECT_TRUE(db().BeginTransaction());
850 sql::ScopedErrorIgnorer ignore_errors;
851 ignore_errors.IgnoreError(SQLITE_ERROR);
852 EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint));
853 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
854 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
857 // Detach succeeds outside of a transaction.
858 db().RollbackTransaction();
859 EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint));
861 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
864 TEST_F(SQLConnectionTest, Basic_QuickIntegrityCheck) {
865 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
866 ASSERT_TRUE(db().Execute(kCreateSql));
867 EXPECT_TRUE(db().QuickIntegrityCheck());
868 db().Close();
870 ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
873 sql::ScopedErrorIgnorer ignore_errors;
874 ignore_errors.IgnoreError(SQLITE_CORRUPT);
875 ASSERT_TRUE(db().Open(db_path()));
876 EXPECT_FALSE(db().QuickIntegrityCheck());
877 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
881 TEST_F(SQLConnectionTest, Basic_FullIntegrityCheck) {
882 const std::string kOk("ok");
883 std::vector<std::string> messages;
885 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
886 ASSERT_TRUE(db().Execute(kCreateSql));
887 EXPECT_TRUE(db().FullIntegrityCheck(&messages));
888 EXPECT_EQ(1u, messages.size());
889 EXPECT_EQ(kOk, messages[0]);
890 db().Close();
892 ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
895 sql::ScopedErrorIgnorer ignore_errors;
896 ignore_errors.IgnoreError(SQLITE_CORRUPT);
897 ASSERT_TRUE(db().Open(db_path()));
898 EXPECT_TRUE(db().FullIntegrityCheck(&messages));
899 EXPECT_LT(1u, messages.size());
900 EXPECT_NE(kOk, messages[0]);
901 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
904 // TODO(shess): CorruptTableOrIndex could be used to produce a
905 // file that would pass the quick check and fail the full check.
908 } // namespace