cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / sql / connection_unittest.cc
blob09a47fb47fddca6f0954608a1a9d95ff52f11711
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/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "sql/connection.h"
10 #include "sql/meta_table.h"
11 #include "sql/statement.h"
12 #include "sql/test/error_callback_support.h"
13 #include "sql/test/scoped_error_ignorer.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/sqlite/sqlite3.h"
17 namespace {
19 // Helper to return the count of items in sqlite_master. Return -1 in
20 // case of error.
21 int SqliteMasterCount(sql::Connection* db) {
22 const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
23 sql::Statement s(db->GetUniqueStatement(kMasterCount));
24 return s.Step() ? s.ColumnInt(0) : -1;
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_)++;
36 RefCounter(const RefCounter& other)
37 : counter_(other.counter_) {
38 (*counter_)++;
40 ~RefCounter() {
41 (*counter_)--;
44 private:
45 size_t* counter_;
47 DISALLOW_ASSIGN(RefCounter);
50 // Empty callback for implementation of ErrorCallbackSetHelper().
51 void IgnoreErrorCallback(int error, sql::Statement* stmt) {
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);
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);
74 #if defined(OS_POSIX)
75 // Set a umask and restore the old mask on destruction. Cribbed from
76 // shared_memory_unittest.cc. Used by POSIX-only UserPermission test.
77 class ScopedUmaskSetter {
78 public:
79 explicit ScopedUmaskSetter(mode_t target_mask) {
80 old_umask_ = umask(target_mask);
82 ~ScopedUmaskSetter() { umask(old_umask_); }
83 private:
84 mode_t old_umask_;
85 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
87 #endif
89 class SQLConnectionTest : public testing::Test {
90 public:
91 SQLConnectionTest() {}
93 virtual void SetUp() {
94 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
95 ASSERT_TRUE(db_.Open(db_path()));
98 virtual void TearDown() {
99 db_.Close();
102 sql::Connection& db() { return db_; }
104 base::FilePath db_path() {
105 return temp_dir_.path().AppendASCII("SQLConnectionTest.db");
108 // Handle errors by blowing away the database.
109 void RazeErrorCallback(int expected_error, int error, sql::Statement* stmt) {
110 EXPECT_EQ(expected_error, error);
111 db_.RazeAndClose();
114 private:
115 base::ScopedTempDir temp_dir_;
116 sql::Connection db_;
119 TEST_F(SQLConnectionTest, Execute) {
120 // Valid statement should return true.
121 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
122 EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
124 // Invalid statement should fail.
125 ASSERT_EQ(SQLITE_ERROR,
126 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
127 EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
130 TEST_F(SQLConnectionTest, ExecuteWithErrorCode) {
131 ASSERT_EQ(SQLITE_OK,
132 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
133 ASSERT_EQ(SQLITE_ERROR,
134 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
135 ASSERT_EQ(SQLITE_ERROR,
136 db().ExecuteAndReturnErrorCode(
137 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
140 TEST_F(SQLConnectionTest, CachedStatement) {
141 sql::StatementID id1("foo", 12);
143 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
144 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
146 // Create a new cached statement.
148 sql::Statement s(db().GetCachedStatement(id1, "SELECT a FROM foo"));
149 ASSERT_TRUE(s.is_valid());
151 ASSERT_TRUE(s.Step());
152 EXPECT_EQ(12, s.ColumnInt(0));
155 // The statement should be cached still.
156 EXPECT_TRUE(db().HasCachedStatement(id1));
159 // Get the same statement using different SQL. This should ignore our
160 // SQL and use the cached one (so it will be valid).
161 sql::Statement s(db().GetCachedStatement(id1, "something invalid("));
162 ASSERT_TRUE(s.is_valid());
164 ASSERT_TRUE(s.Step());
165 EXPECT_EQ(12, s.ColumnInt(0));
168 // Make sure other statements aren't marked as cached.
169 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE));
172 TEST_F(SQLConnectionTest, IsSQLValidTest) {
173 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
174 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
175 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
178 TEST_F(SQLConnectionTest, DoesStuffExist) {
179 // Test DoesTableExist.
180 EXPECT_FALSE(db().DoesTableExist("foo"));
181 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
182 EXPECT_TRUE(db().DoesTableExist("foo"));
184 // Should be case sensitive.
185 EXPECT_FALSE(db().DoesTableExist("FOO"));
187 // Test DoesColumnExist.
188 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
189 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
191 // Testing for a column on a nonexistent table.
192 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
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)"));
227 sql::ScopedErrorIgnorer ignore_errors;
228 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
229 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
230 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
233 TEST_F(SQLConnectionTest, ErrorCallback) {
234 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
235 ASSERT_TRUE(db().Execute(kCreateSql));
236 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
238 int error = SQLITE_OK;
240 sql::ScopedErrorCallback sec(
241 &db(), base::Bind(&sql::CaptureErrorCallback, &error));
242 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
243 EXPECT_EQ(SQLITE_CONSTRAINT, error);
246 // Callback is no longer in force due to reset.
248 error = SQLITE_OK;
249 sql::ScopedErrorIgnorer ignore_errors;
250 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
251 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
252 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
253 EXPECT_EQ(SQLITE_OK, error);
256 // base::Bind() can curry arguments to be passed by const reference
257 // to the callback function. If the callback function calls
258 // re/set_error_callback(), the storage for those arguments can be
259 // deleted while the callback function is still executing.
261 // RefCounter() counts how many objects are live using an external
262 // count. The same counter is passed to the callback, so that it
263 // can check directly even if the RefCounter object is no longer
264 // live.
266 size_t count = 0;
267 sql::ScopedErrorCallback sec(
268 &db(), base::Bind(&ErrorCallbackSetHelper,
269 &db(), &count, RefCounter(&count)));
271 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
274 // Same test, but reset_error_callback() case.
276 size_t count = 0;
277 sql::ScopedErrorCallback sec(
278 &db(), base::Bind(&ErrorCallbackResetHelper,
279 &db(), &count, RefCounter(&count)));
281 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
285 // Test that sql::Connection::Raze() results in a database without the
286 // tables from the original database.
287 TEST_F(SQLConnectionTest, Raze) {
288 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
289 ASSERT_TRUE(db().Execute(kCreateSql));
290 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
292 int pragma_auto_vacuum = 0;
294 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
295 ASSERT_TRUE(s.Step());
296 pragma_auto_vacuum = s.ColumnInt(0);
297 ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
300 // If auto_vacuum is set, there's an extra page to maintain a freelist.
301 const int kExpectedPageCount = 2 + pragma_auto_vacuum;
304 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
305 ASSERT_TRUE(s.Step());
306 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
310 sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
311 ASSERT_TRUE(s.Step());
312 EXPECT_EQ("table", s.ColumnString(0));
313 EXPECT_EQ("foo", s.ColumnString(1));
314 EXPECT_EQ("foo", s.ColumnString(2));
315 // Table "foo" is stored in the last page of the file.
316 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3));
317 EXPECT_EQ(kCreateSql, s.ColumnString(4));
320 ASSERT_TRUE(db().Raze());
323 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
324 ASSERT_TRUE(s.Step());
325 EXPECT_EQ(1, s.ColumnInt(0));
328 ASSERT_EQ(0, SqliteMasterCount(&db()));
331 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
332 ASSERT_TRUE(s.Step());
333 // The new database has the same auto_vacuum as a fresh database.
334 EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
338 // Test that Raze() maintains page_size.
339 TEST_F(SQLConnectionTest, RazePageSize) {
340 // Fetch the default page size and double it for use in this test.
341 // Scoped to release statement before Close().
342 int default_page_size = 0;
344 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
345 ASSERT_TRUE(s.Step());
346 default_page_size = s.ColumnInt(0);
348 ASSERT_GT(default_page_size, 0);
349 const int kPageSize = 2 * default_page_size;
351 // Re-open the database to allow setting the page size.
352 db().Close();
353 db().set_page_size(kPageSize);
354 ASSERT_TRUE(db().Open(db_path()));
356 // page_size should match the indicated value.
357 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
358 ASSERT_TRUE(s.Step());
359 ASSERT_EQ(kPageSize, s.ColumnInt(0));
361 // After raze, page_size should still match the indicated value.
362 ASSERT_TRUE(db().Raze());
363 s.Reset(true);
364 ASSERT_TRUE(s.Step());
365 ASSERT_EQ(kPageSize, s.ColumnInt(0));
368 // Test that Raze() results are seen in other connections.
369 TEST_F(SQLConnectionTest, RazeMultiple) {
370 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
371 ASSERT_TRUE(db().Execute(kCreateSql));
373 sql::Connection other_db;
374 ASSERT_TRUE(other_db.Open(db_path()));
376 // Check that the second connection sees the table.
377 ASSERT_EQ(1, SqliteMasterCount(&other_db));
379 ASSERT_TRUE(db().Raze());
381 // The second connection sees the updated database.
382 ASSERT_EQ(0, SqliteMasterCount(&other_db));
385 TEST_F(SQLConnectionTest, RazeLocked) {
386 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
387 ASSERT_TRUE(db().Execute(kCreateSql));
389 // Open a transaction and write some data in a second connection.
390 // This will acquire a PENDING or EXCLUSIVE transaction, which will
391 // cause the raze to fail.
392 sql::Connection other_db;
393 ASSERT_TRUE(other_db.Open(db_path()));
394 ASSERT_TRUE(other_db.BeginTransaction());
395 const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
396 ASSERT_TRUE(other_db.Execute(kInsertSql));
398 ASSERT_FALSE(db().Raze());
400 // Works after COMMIT.
401 ASSERT_TRUE(other_db.CommitTransaction());
402 ASSERT_TRUE(db().Raze());
404 // Re-create the database.
405 ASSERT_TRUE(db().Execute(kCreateSql));
406 ASSERT_TRUE(db().Execute(kInsertSql));
408 // An unfinished read transaction in the other connection also
409 // blocks raze.
410 const char *kQuery = "SELECT COUNT(*) FROM foo";
411 sql::Statement s(other_db.GetUniqueStatement(kQuery));
412 ASSERT_TRUE(s.Step());
413 ASSERT_FALSE(db().Raze());
415 // Complete the statement unlocks the database.
416 ASSERT_FALSE(s.Step());
417 ASSERT_TRUE(db().Raze());
420 // Verify that Raze() can handle an empty file. SQLite should treat
421 // this as an empty database.
422 TEST_F(SQLConnectionTest, RazeEmptyDB) {
423 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
424 ASSERT_TRUE(db().Execute(kCreateSql));
425 db().Close();
428 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "rb+"));
429 ASSERT_TRUE(file.get() != NULL);
430 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET));
431 ASSERT_TRUE(file_util::TruncateFile(file.get()));
434 ASSERT_TRUE(db().Open(db_path()));
435 ASSERT_TRUE(db().Raze());
436 EXPECT_EQ(0, SqliteMasterCount(&db()));
439 // Verify that Raze() can handle a file of junk.
440 TEST_F(SQLConnectionTest, RazeNOTADB) {
441 db().Close();
442 sql::Connection::Delete(db_path());
443 ASSERT_FALSE(base::PathExists(db_path()));
446 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "wb"));
447 ASSERT_TRUE(file.get() != NULL);
449 const char* kJunk = "This is the hour of our discontent.";
450 fputs(kJunk, file.get());
452 ASSERT_TRUE(base::PathExists(db_path()));
454 // SQLite will successfully open the handle, but will fail with
455 // SQLITE_IOERR_SHORT_READ on pragma statemenets which read the
456 // header.
458 sql::ScopedErrorIgnorer ignore_errors;
459 ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ);
460 EXPECT_TRUE(db().Open(db_path()));
461 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
463 EXPECT_TRUE(db().Raze());
464 db().Close();
466 // Now empty, the open should open an empty database.
467 EXPECT_TRUE(db().Open(db_path()));
468 EXPECT_EQ(0, SqliteMasterCount(&db()));
471 // Verify that Raze() can handle a database overwritten with garbage.
472 TEST_F(SQLConnectionTest, RazeNOTADB2) {
473 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
474 ASSERT_TRUE(db().Execute(kCreateSql));
475 ASSERT_EQ(1, SqliteMasterCount(&db()));
476 db().Close();
479 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "rb+"));
480 ASSERT_TRUE(file.get() != NULL);
481 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET));
483 const char* kJunk = "This is the hour of our discontent.";
484 fputs(kJunk, file.get());
487 // SQLite will successfully open the handle, but will fail with
488 // SQLITE_NOTADB on pragma statemenets which attempt to read the
489 // corrupted header.
491 sql::ScopedErrorIgnorer ignore_errors;
492 ignore_errors.IgnoreError(SQLITE_NOTADB);
493 EXPECT_TRUE(db().Open(db_path()));
494 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
496 EXPECT_TRUE(db().Raze());
497 db().Close();
499 // Now empty, the open should succeed with an empty database.
500 EXPECT_TRUE(db().Open(db_path()));
501 EXPECT_EQ(0, SqliteMasterCount(&db()));
504 // Test that a callback from Open() can raze the database. This is
505 // essential for cases where the Open() can fail entirely, so the
506 // Raze() cannot happen later. Additionally test that when the
507 // callback does this during Open(), the open is retried and succeeds.
509 // Most corruptions seen in the wild seem to happen when two pages in
510 // the database were not written transactionally (the transaction
511 // changed both, but one wasn't successfully written for some reason).
512 // A special case of that is when the header indicates that the
513 // database contains more pages than are in the file. This breaks
514 // things at a very basic level, verify that Raze() can handle it.
515 TEST_F(SQLConnectionTest, RazeCallbackReopen) {
516 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
517 ASSERT_TRUE(db().Execute(kCreateSql));
518 ASSERT_EQ(1, SqliteMasterCount(&db()));
519 int page_size = 0;
521 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
522 ASSERT_TRUE(s.Step());
523 page_size = s.ColumnInt(0);
525 db().Close();
527 // Trim a single page from the end of the file.
529 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "rb+"));
530 ASSERT_TRUE(file.get() != NULL);
531 ASSERT_EQ(0, fseek(file.get(), -page_size, SEEK_END));
532 ASSERT_TRUE(file_util::TruncateFile(file.get()));
535 // Open() will succeed, even though the PRAGMA calls within will
536 // fail with SQLITE_CORRUPT, as will this PRAGMA.
538 sql::ScopedErrorIgnorer ignore_errors;
539 ignore_errors.IgnoreError(SQLITE_CORRUPT);
540 ASSERT_TRUE(db().Open(db_path()));
541 ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
542 db().Close();
543 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
546 db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback,
547 base::Unretained(this),
548 SQLITE_CORRUPT));
550 // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
551 // callback will call RazeAndClose(). Open() will then fail and be
552 // retried. The second Open() on the empty database will succeed
553 // cleanly.
554 ASSERT_TRUE(db().Open(db_path()));
555 ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
556 EXPECT_EQ(0, SqliteMasterCount(&db()));
559 // Basic test of RazeAndClose() operation.
560 TEST_F(SQLConnectionTest, RazeAndClose) {
561 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
562 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
564 // Test that RazeAndClose() closes the database, and that the
565 // database is empty when re-opened.
566 ASSERT_TRUE(db().Execute(kCreateSql));
567 ASSERT_TRUE(db().Execute(kPopulateSql));
568 ASSERT_TRUE(db().RazeAndClose());
569 ASSERT_FALSE(db().is_open());
570 db().Close();
571 ASSERT_TRUE(db().Open(db_path()));
572 ASSERT_EQ(0, SqliteMasterCount(&db()));
574 // Test that RazeAndClose() can break transactions.
575 ASSERT_TRUE(db().Execute(kCreateSql));
576 ASSERT_TRUE(db().Execute(kPopulateSql));
577 ASSERT_TRUE(db().BeginTransaction());
578 ASSERT_TRUE(db().RazeAndClose());
579 ASSERT_FALSE(db().is_open());
580 ASSERT_FALSE(db().CommitTransaction());
581 db().Close();
582 ASSERT_TRUE(db().Open(db_path()));
583 ASSERT_EQ(0, SqliteMasterCount(&db()));
586 // Test that various operations fail without crashing after
587 // RazeAndClose().
588 TEST_F(SQLConnectionTest, RazeAndCloseDiagnostics) {
589 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
590 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
591 const char* kSimpleSql = "SELECT 1";
593 ASSERT_TRUE(db().Execute(kCreateSql));
594 ASSERT_TRUE(db().Execute(kPopulateSql));
596 // Test baseline expectations.
597 db().Preload();
598 ASSERT_TRUE(db().DoesTableExist("foo"));
599 ASSERT_TRUE(db().IsSQLValid(kSimpleSql));
600 ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql));
601 ASSERT_TRUE(db().Execute(kSimpleSql));
602 ASSERT_TRUE(db().is_open());
604 sql::Statement s(db().GetUniqueStatement(kSimpleSql));
605 ASSERT_TRUE(s.Step());
608 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
609 ASSERT_TRUE(s.Step());
611 ASSERT_TRUE(db().BeginTransaction());
612 ASSERT_TRUE(db().CommitTransaction());
613 ASSERT_TRUE(db().BeginTransaction());
614 db().RollbackTransaction();
616 ASSERT_TRUE(db().RazeAndClose());
618 // At this point, they should all fail, but not crash.
619 db().Preload();
620 ASSERT_FALSE(db().DoesTableExist("foo"));
621 ASSERT_FALSE(db().IsSQLValid(kSimpleSql));
622 ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql));
623 ASSERT_FALSE(db().Execute(kSimpleSql));
624 ASSERT_FALSE(db().is_open());
626 sql::Statement s(db().GetUniqueStatement(kSimpleSql));
627 ASSERT_FALSE(s.Step());
630 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
631 ASSERT_FALSE(s.Step());
633 ASSERT_FALSE(db().BeginTransaction());
634 ASSERT_FALSE(db().CommitTransaction());
635 ASSERT_FALSE(db().BeginTransaction());
636 db().RollbackTransaction();
638 // Close normally to reset the poisoned flag.
639 db().Close();
641 // DEATH tests not supported on Android or iOS.
642 #if !defined(OS_ANDROID) && !defined(OS_IOS)
643 // Once the real Close() has been called, various calls enforce API
644 // usage by becoming fatal in debug mode. Since DEATH tests are
645 // expensive, just test one of them.
646 if (DLOG_IS_ON(FATAL)) {
647 ASSERT_DEATH({
648 db().IsSQLValid(kSimpleSql);
649 }, "Illegal use of connection without a db");
651 #endif
654 // TODO(shess): Spin up a background thread to hold other_db, to more
655 // closely match real life. That would also allow testing
656 // RazeWithTimeout().
658 #if defined(OS_ANDROID)
659 TEST_F(SQLConnectionTest, SetTempDirForSQL) {
661 sql::MetaTable meta_table;
662 // Below call needs a temporary directory in sqlite3
663 // On Android, it can pass only when the temporary directory is set.
664 // Otherwise, sqlite3 doesn't find the correct directory to store
665 // temporary files and will report the error 'unable to open
666 // database file'.
667 ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
669 #endif
671 TEST_F(SQLConnectionTest, Delete) {
672 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
673 db().Close();
675 // Should have both a main database file and a journal file because
676 // of journal_mode PERSIST.
677 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
678 ASSERT_TRUE(base::PathExists(db_path()));
679 ASSERT_TRUE(base::PathExists(journal));
681 sql::Connection::Delete(db_path());
682 EXPECT_FALSE(base::PathExists(db_path()));
683 EXPECT_FALSE(base::PathExists(journal));
686 #if defined(OS_POSIX)
687 // Test that set_restrict_to_user() trims database permissions so that
688 // only the owner (and root) can read.
689 TEST_F(SQLConnectionTest, UserPermission) {
690 // If the bots all had a restrictive umask setting such that
691 // databases are always created with only the owner able to read
692 // them, then the code could break without breaking the tests.
693 // Temporarily provide a more permissive umask.
694 db().Close();
695 sql::Connection::Delete(db_path());
696 ASSERT_FALSE(base::PathExists(db_path()));
697 ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
698 ASSERT_TRUE(db().Open(db_path()));
700 // Cause the journal file to be created. If the default
701 // journal_mode is changed back to DELETE, then parts of this test
702 // will need to be updated.
703 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
705 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
706 int mode;
708 // Given a permissive umask, the database is created with permissive
709 // read access for the database and journal.
710 ASSERT_TRUE(base::PathExists(db_path()));
711 ASSERT_TRUE(base::PathExists(journal));
712 mode = file_util::FILE_PERMISSION_MASK;
713 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode));
714 ASSERT_NE((mode & file_util::FILE_PERMISSION_USER_MASK), mode);
715 mode = file_util::FILE_PERMISSION_MASK;
716 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode));
717 ASSERT_NE((mode & file_util::FILE_PERMISSION_USER_MASK), mode);
719 // Re-open with restricted permissions and verify that the modes
720 // changed for both the main database and the journal.
721 db().Close();
722 db().set_restrict_to_user();
723 ASSERT_TRUE(db().Open(db_path()));
724 ASSERT_TRUE(base::PathExists(db_path()));
725 ASSERT_TRUE(base::PathExists(journal));
726 mode = file_util::FILE_PERMISSION_MASK;
727 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode));
728 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode);
729 mode = file_util::FILE_PERMISSION_MASK;
730 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode));
731 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode);
733 // Delete and re-create the database, the restriction should still apply.
734 db().Close();
735 sql::Connection::Delete(db_path());
736 ASSERT_TRUE(db().Open(db_path()));
737 ASSERT_TRUE(base::PathExists(db_path()));
738 ASSERT_FALSE(base::PathExists(journal));
739 mode = file_util::FILE_PERMISSION_MASK;
740 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode));
741 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode);
743 // Verify that journal creation inherits the restriction.
744 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
745 ASSERT_TRUE(base::PathExists(journal));
746 mode = file_util::FILE_PERMISSION_MASK;
747 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode));
748 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode);
750 #endif // defined(OS_POSIX)
752 // Test that errors start happening once Poison() is called.
753 TEST_F(SQLConnectionTest, Poison) {
754 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
756 // Before the Poison() call, things generally work.
757 EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
758 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
760 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
761 ASSERT_TRUE(s.is_valid());
762 ASSERT_TRUE(s.Step());
765 // Get a statement which is valid before and will exist across Poison().
766 sql::Statement valid_statement(
767 db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
768 ASSERT_TRUE(valid_statement.is_valid());
769 ASSERT_TRUE(valid_statement.Step());
770 valid_statement.Reset(true);
772 db().Poison();
774 // After the Poison() call, things fail.
775 EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
776 EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
778 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
779 ASSERT_FALSE(s.is_valid());
780 ASSERT_FALSE(s.Step());
783 // The existing statement has become invalid.
784 ASSERT_FALSE(valid_statement.is_valid());
785 ASSERT_FALSE(valid_statement.Step());
788 // Test attaching and detaching databases from the connection.
789 TEST_F(SQLConnectionTest, Attach) {
790 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
792 // Create a database to attach to.
793 base::FilePath attach_path =
794 db_path().DirName().AppendASCII("SQLConnectionAttach.db");
795 const char kAttachmentPoint[] = "other";
797 sql::Connection other_db;
798 ASSERT_TRUE(other_db.Open(attach_path));
799 EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
800 EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
803 // Cannot see the attached database, yet.
804 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
806 // Attach fails in a transaction.
807 EXPECT_TRUE(db().BeginTransaction());
809 sql::ScopedErrorIgnorer ignore_errors;
810 ignore_errors.IgnoreError(SQLITE_ERROR);
811 EXPECT_FALSE(db().AttachDatabase(attach_path, kAttachmentPoint));
812 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
815 // Attach succeeds when the transaction is closed.
816 db().RollbackTransaction();
817 EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint));
818 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
820 // Queries can touch both databases.
821 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
823 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
824 ASSERT_TRUE(s.Step());
825 EXPECT_EQ(1, s.ColumnInt(0));
828 // Detach also fails in a transaction.
829 EXPECT_TRUE(db().BeginTransaction());
831 sql::ScopedErrorIgnorer ignore_errors;
832 ignore_errors.IgnoreError(SQLITE_ERROR);
833 EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint));
834 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
835 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
838 // Detach succeeds outside of a transaction.
839 db().RollbackTransaction();
840 EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint));
842 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
845 } // namespace