Home | History | Annotate | Download | only in sql
      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.
      4 
      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 "sql/test/test_helpers.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "third_party/sqlite/sqlite3.h"
     17 
     18 namespace {
     19 
     20 // Helper to return the count of items in sqlite_master.  Return -1 in
     21 // case of error.
     22 int SqliteMasterCount(sql::Connection* db) {
     23   const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
     24   sql::Statement s(db->GetUniqueStatement(kMasterCount));
     25   return s.Step() ? s.ColumnInt(0) : -1;
     26 }
     27 
     28 // Track the number of valid references which share the same pointer.
     29 // This is used to allow testing an implicitly use-after-free case by
     30 // explicitly having the ref count live longer than the object.
     31 class RefCounter {
     32  public:
     33   RefCounter(size_t* counter)
     34       : counter_(counter) {
     35     (*counter_)++;
     36   }
     37   RefCounter(const RefCounter& other)
     38       : counter_(other.counter_) {
     39     (*counter_)++;
     40   }
     41   ~RefCounter() {
     42     (*counter_)--;
     43   }
     44 
     45  private:
     46   size_t* counter_;
     47 
     48   DISALLOW_ASSIGN(RefCounter);
     49 };
     50 
     51 // Empty callback for implementation of ErrorCallbackSetHelper().
     52 void IgnoreErrorCallback(int error, sql::Statement* stmt) {
     53 }
     54 
     55 void ErrorCallbackSetHelper(sql::Connection* db,
     56                             size_t* counter,
     57                             const RefCounter& r,
     58                             int error, sql::Statement* stmt) {
     59   // The ref count should not go to zero when changing the callback.
     60   EXPECT_GT(*counter, 0u);
     61   db->set_error_callback(base::Bind(&IgnoreErrorCallback));
     62   EXPECT_GT(*counter, 0u);
     63 }
     64 
     65 void ErrorCallbackResetHelper(sql::Connection* db,
     66                               size_t* counter,
     67                               const RefCounter& r,
     68                               int error, sql::Statement* stmt) {
     69   // The ref count should not go to zero when clearing the callback.
     70   EXPECT_GT(*counter, 0u);
     71   db->reset_error_callback();
     72   EXPECT_GT(*counter, 0u);
     73 }
     74 
     75 #if defined(OS_POSIX)
     76 // Set a umask and restore the old mask on destruction.  Cribbed from
     77 // shared_memory_unittest.cc.  Used by POSIX-only UserPermission test.
     78 class ScopedUmaskSetter {
     79  public:
     80   explicit ScopedUmaskSetter(mode_t target_mask) {
     81     old_umask_ = umask(target_mask);
     82   }
     83   ~ScopedUmaskSetter() { umask(old_umask_); }
     84  private:
     85   mode_t old_umask_;
     86   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
     87 };
     88 #endif
     89 
     90 class SQLConnectionTest : public testing::Test {
     91  public:
     92   virtual void SetUp() {
     93     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     94     db_path_ = temp_dir_.path().AppendASCII("SQLConnectionTest.db");
     95     ASSERT_TRUE(db_.Open(db_path_));
     96   }
     97 
     98   virtual void TearDown() {
     99     db_.Close();
    100   }
    101 
    102   sql::Connection& db() { return db_; }
    103   const base::FilePath& db_path() { return db_path_; }
    104 
    105   // Handle errors by blowing away the database.
    106   void RazeErrorCallback(int expected_error, int error, sql::Statement* stmt) {
    107     EXPECT_EQ(expected_error, error);
    108     db_.RazeAndClose();
    109   }
    110 
    111  private:
    112   sql::Connection db_;
    113   base::FilePath db_path_;
    114   base::ScopedTempDir temp_dir_;
    115 };
    116 
    117 TEST_F(SQLConnectionTest, Execute) {
    118   // Valid statement should return true.
    119   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
    120   EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
    121 
    122   // Invalid statement should fail.
    123   ASSERT_EQ(SQLITE_ERROR,
    124             db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
    125   EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
    126 }
    127 
    128 TEST_F(SQLConnectionTest, ExecuteWithErrorCode) {
    129   ASSERT_EQ(SQLITE_OK,
    130             db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
    131   ASSERT_EQ(SQLITE_ERROR,
    132             db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
    133   ASSERT_EQ(SQLITE_ERROR,
    134             db().ExecuteAndReturnErrorCode(
    135                 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
    136 }
    137 
    138 TEST_F(SQLConnectionTest, CachedStatement) {
    139   sql::StatementID id1("foo", 12);
    140 
    141   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
    142   ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
    143 
    144   // Create a new cached statement.
    145   {
    146     sql::Statement s(db().GetCachedStatement(id1, "SELECT a FROM foo"));
    147     ASSERT_TRUE(s.is_valid());
    148 
    149     ASSERT_TRUE(s.Step());
    150     EXPECT_EQ(12, s.ColumnInt(0));
    151   }
    152 
    153   // The statement should be cached still.
    154   EXPECT_TRUE(db().HasCachedStatement(id1));
    155 
    156   {
    157     // Get the same statement using different SQL. This should ignore our
    158     // SQL and use the cached one (so it will be valid).
    159     sql::Statement s(db().GetCachedStatement(id1, "something invalid("));
    160     ASSERT_TRUE(s.is_valid());
    161 
    162     ASSERT_TRUE(s.Step());
    163     EXPECT_EQ(12, s.ColumnInt(0));
    164   }
    165 
    166   // Make sure other statements aren't marked as cached.
    167   EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE));
    168 }
    169 
    170 TEST_F(SQLConnectionTest, IsSQLValidTest) {
    171   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
    172   ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
    173   ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
    174 }
    175 
    176 TEST_F(SQLConnectionTest, DoesStuffExist) {
    177   // Test DoesTableExist.
    178   EXPECT_FALSE(db().DoesTableExist("foo"));
    179   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
    180   EXPECT_TRUE(db().DoesTableExist("foo"));
    181 
    182   // Should be case sensitive.
    183   EXPECT_FALSE(db().DoesTableExist("FOO"));
    184 
    185   // Test DoesColumnExist.
    186   EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
    187   EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
    188 
    189   // Testing for a column on a nonexistent table.
    190   EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
    191 }
    192 
    193 TEST_F(SQLConnectionTest, GetLastInsertRowId) {
    194   ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
    195 
    196   ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
    197 
    198   // Last insert row ID should be valid.
    199   int64 row = db().GetLastInsertRowId();
    200   EXPECT_LT(0, row);
    201 
    202   // It should be the primary key of the row we just inserted.
    203   sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
    204   s.BindInt64(0, row);
    205   ASSERT_TRUE(s.Step());
    206   EXPECT_EQ(12, s.ColumnInt(0));
    207 }
    208 
    209 TEST_F(SQLConnectionTest, Rollback) {
    210   ASSERT_TRUE(db().BeginTransaction());
    211   ASSERT_TRUE(db().BeginTransaction());
    212   EXPECT_EQ(2, db().transaction_nesting());
    213   db().RollbackTransaction();
    214   EXPECT_FALSE(db().CommitTransaction());
    215   EXPECT_TRUE(db().BeginTransaction());
    216 }
    217 
    218 // Test the scoped error ignorer by attempting to insert a duplicate
    219 // value into an index.
    220 TEST_F(SQLConnectionTest, ScopedIgnoreError) {
    221   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
    222   ASSERT_TRUE(db().Execute(kCreateSql));
    223   ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    224 
    225   sql::ScopedErrorIgnorer ignore_errors;
    226   ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
    227   ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    228   ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    229 }
    230 
    231 TEST_F(SQLConnectionTest, ErrorCallback) {
    232   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
    233   ASSERT_TRUE(db().Execute(kCreateSql));
    234   ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    235 
    236   int error = SQLITE_OK;
    237   {
    238     sql::ScopedErrorCallback sec(
    239         &db(), base::Bind(&sql::CaptureErrorCallback, &error));
    240     EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    241     EXPECT_EQ(SQLITE_CONSTRAINT, error);
    242   }
    243 
    244   // Callback is no longer in force due to reset.
    245   {
    246     error = SQLITE_OK;
    247     sql::ScopedErrorIgnorer ignore_errors;
    248     ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
    249     ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    250     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    251     EXPECT_EQ(SQLITE_OK, error);
    252   }
    253 
    254   // base::Bind() can curry arguments to be passed by const reference
    255   // to the callback function.  If the callback function calls
    256   // re/set_error_callback(), the storage for those arguments can be
    257   // deleted while the callback function is still executing.
    258   //
    259   // RefCounter() counts how many objects are live using an external
    260   // count.  The same counter is passed to the callback, so that it
    261   // can check directly even if the RefCounter object is no longer
    262   // live.
    263   {
    264     size_t count = 0;
    265     sql::ScopedErrorCallback sec(
    266         &db(), base::Bind(&ErrorCallbackSetHelper,
    267                           &db(), &count, RefCounter(&count)));
    268 
    269     EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    270   }
    271 
    272   // Same test, but reset_error_callback() case.
    273   {
    274     size_t count = 0;
    275     sql::ScopedErrorCallback sec(
    276         &db(), base::Bind(&ErrorCallbackResetHelper,
    277                           &db(), &count, RefCounter(&count)));
    278 
    279     EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
    280   }
    281 }
    282 
    283 // Test that sql::Connection::Raze() results in a database without the
    284 // tables from the original database.
    285 TEST_F(SQLConnectionTest, Raze) {
    286   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    287   ASSERT_TRUE(db().Execute(kCreateSql));
    288   ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
    289 
    290   int pragma_auto_vacuum = 0;
    291   {
    292     sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
    293     ASSERT_TRUE(s.Step());
    294     pragma_auto_vacuum = s.ColumnInt(0);
    295     ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
    296   }
    297 
    298   // If auto_vacuum is set, there's an extra page to maintain a freelist.
    299   const int kExpectedPageCount = 2 + pragma_auto_vacuum;
    300 
    301   {
    302     sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
    303     ASSERT_TRUE(s.Step());
    304     EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
    305   }
    306 
    307   {
    308     sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
    309     ASSERT_TRUE(s.Step());
    310     EXPECT_EQ("table", s.ColumnString(0));
    311     EXPECT_EQ("foo", s.ColumnString(1));
    312     EXPECT_EQ("foo", s.ColumnString(2));
    313     // Table "foo" is stored in the last page of the file.
    314     EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3));
    315     EXPECT_EQ(kCreateSql, s.ColumnString(4));
    316   }
    317 
    318   ASSERT_TRUE(db().Raze());
    319 
    320   {
    321     sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
    322     ASSERT_TRUE(s.Step());
    323     EXPECT_EQ(1, s.ColumnInt(0));
    324   }
    325 
    326   ASSERT_EQ(0, SqliteMasterCount(&db()));
    327 
    328   {
    329     sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
    330     ASSERT_TRUE(s.Step());
    331     // The new database has the same auto_vacuum as a fresh database.
    332     EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
    333   }
    334 }
    335 
    336 // Test that Raze() maintains page_size.
    337 TEST_F(SQLConnectionTest, RazePageSize) {
    338   // Fetch the default page size and double it for use in this test.
    339   // Scoped to release statement before Close().
    340   int default_page_size = 0;
    341   {
    342     sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
    343     ASSERT_TRUE(s.Step());
    344     default_page_size = s.ColumnInt(0);
    345   }
    346   ASSERT_GT(default_page_size, 0);
    347   const int kPageSize = 2 * default_page_size;
    348 
    349   // Re-open the database to allow setting the page size.
    350   db().Close();
    351   db().set_page_size(kPageSize);
    352   ASSERT_TRUE(db().Open(db_path()));
    353 
    354   // page_size should match the indicated value.
    355   sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
    356   ASSERT_TRUE(s.Step());
    357   ASSERT_EQ(kPageSize, s.ColumnInt(0));
    358 
    359   // After raze, page_size should still match the indicated value.
    360   ASSERT_TRUE(db().Raze());
    361   s.Reset(true);
    362   ASSERT_TRUE(s.Step());
    363   ASSERT_EQ(kPageSize, s.ColumnInt(0));
    364 }
    365 
    366 // Test that Raze() results are seen in other connections.
    367 TEST_F(SQLConnectionTest, RazeMultiple) {
    368   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    369   ASSERT_TRUE(db().Execute(kCreateSql));
    370 
    371   sql::Connection other_db;
    372   ASSERT_TRUE(other_db.Open(db_path()));
    373 
    374   // Check that the second connection sees the table.
    375   ASSERT_EQ(1, SqliteMasterCount(&other_db));
    376 
    377   ASSERT_TRUE(db().Raze());
    378 
    379   // The second connection sees the updated database.
    380   ASSERT_EQ(0, SqliteMasterCount(&other_db));
    381 }
    382 
    383 TEST_F(SQLConnectionTest, RazeLocked) {
    384   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    385   ASSERT_TRUE(db().Execute(kCreateSql));
    386 
    387   // Open a transaction and write some data in a second connection.
    388   // This will acquire a PENDING or EXCLUSIVE transaction, which will
    389   // cause the raze to fail.
    390   sql::Connection other_db;
    391   ASSERT_TRUE(other_db.Open(db_path()));
    392   ASSERT_TRUE(other_db.BeginTransaction());
    393   const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
    394   ASSERT_TRUE(other_db.Execute(kInsertSql));
    395 
    396   ASSERT_FALSE(db().Raze());
    397 
    398   // Works after COMMIT.
    399   ASSERT_TRUE(other_db.CommitTransaction());
    400   ASSERT_TRUE(db().Raze());
    401 
    402   // Re-create the database.
    403   ASSERT_TRUE(db().Execute(kCreateSql));
    404   ASSERT_TRUE(db().Execute(kInsertSql));
    405 
    406   // An unfinished read transaction in the other connection also
    407   // blocks raze.
    408   const char *kQuery = "SELECT COUNT(*) FROM foo";
    409   sql::Statement s(other_db.GetUniqueStatement(kQuery));
    410   ASSERT_TRUE(s.Step());
    411   ASSERT_FALSE(db().Raze());
    412 
    413   // Complete the statement unlocks the database.
    414   ASSERT_FALSE(s.Step());
    415   ASSERT_TRUE(db().Raze());
    416 }
    417 
    418 // Verify that Raze() can handle an empty file.  SQLite should treat
    419 // this as an empty database.
    420 TEST_F(SQLConnectionTest, RazeEmptyDB) {
    421   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    422   ASSERT_TRUE(db().Execute(kCreateSql));
    423   db().Close();
    424 
    425   {
    426     file_util::ScopedFILE file(base::OpenFile(db_path(), "rb+"));
    427     ASSERT_TRUE(file.get() != NULL);
    428     ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET));
    429     ASSERT_TRUE(base::TruncateFile(file.get()));
    430   }
    431 
    432   ASSERT_TRUE(db().Open(db_path()));
    433   ASSERT_TRUE(db().Raze());
    434   EXPECT_EQ(0, SqliteMasterCount(&db()));
    435 }
    436 
    437 // Verify that Raze() can handle a file of junk.
    438 TEST_F(SQLConnectionTest, RazeNOTADB) {
    439   db().Close();
    440   sql::Connection::Delete(db_path());
    441   ASSERT_FALSE(base::PathExists(db_path()));
    442 
    443   {
    444     file_util::ScopedFILE file(base::OpenFile(db_path(), "wb"));
    445     ASSERT_TRUE(file.get() != NULL);
    446 
    447     const char* kJunk = "This is the hour of our discontent.";
    448     fputs(kJunk, file.get());
    449   }
    450   ASSERT_TRUE(base::PathExists(db_path()));
    451 
    452   // SQLite will successfully open the handle, but will fail with
    453   // SQLITE_IOERR_SHORT_READ on pragma statemenets which read the
    454   // header.
    455   {
    456     sql::ScopedErrorIgnorer ignore_errors;
    457     ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ);
    458     EXPECT_TRUE(db().Open(db_path()));
    459     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    460   }
    461   EXPECT_TRUE(db().Raze());
    462   db().Close();
    463 
    464   // Now empty, the open should open an empty database.
    465   EXPECT_TRUE(db().Open(db_path()));
    466   EXPECT_EQ(0, SqliteMasterCount(&db()));
    467 }
    468 
    469 // Verify that Raze() can handle a database overwritten with garbage.
    470 TEST_F(SQLConnectionTest, RazeNOTADB2) {
    471   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    472   ASSERT_TRUE(db().Execute(kCreateSql));
    473   ASSERT_EQ(1, SqliteMasterCount(&db()));
    474   db().Close();
    475 
    476   {
    477     file_util::ScopedFILE file(base::OpenFile(db_path(), "rb+"));
    478     ASSERT_TRUE(file.get() != NULL);
    479     ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET));
    480 
    481     const char* kJunk = "This is the hour of our discontent.";
    482     fputs(kJunk, file.get());
    483   }
    484 
    485   // SQLite will successfully open the handle, but will fail with
    486   // SQLITE_NOTADB on pragma statemenets which attempt to read the
    487   // corrupted header.
    488   {
    489     sql::ScopedErrorIgnorer ignore_errors;
    490     ignore_errors.IgnoreError(SQLITE_NOTADB);
    491     EXPECT_TRUE(db().Open(db_path()));
    492     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    493   }
    494   EXPECT_TRUE(db().Raze());
    495   db().Close();
    496 
    497   // Now empty, the open should succeed with an empty database.
    498   EXPECT_TRUE(db().Open(db_path()));
    499   EXPECT_EQ(0, SqliteMasterCount(&db()));
    500 }
    501 
    502 // Test that a callback from Open() can raze the database.  This is
    503 // essential for cases where the Open() can fail entirely, so the
    504 // Raze() cannot happen later.  Additionally test that when the
    505 // callback does this during Open(), the open is retried and succeeds.
    506 TEST_F(SQLConnectionTest, RazeCallbackReopen) {
    507   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    508   ASSERT_TRUE(db().Execute(kCreateSql));
    509   ASSERT_EQ(1, SqliteMasterCount(&db()));
    510   db().Close();
    511 
    512   // Corrupt the database so that nothing works, including PRAGMAs.
    513   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
    514 
    515   // Open() will succeed, even though the PRAGMA calls within will
    516   // fail with SQLITE_CORRUPT, as will this PRAGMA.
    517   {
    518     sql::ScopedErrorIgnorer ignore_errors;
    519     ignore_errors.IgnoreError(SQLITE_CORRUPT);
    520     ASSERT_TRUE(db().Open(db_path()));
    521     ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
    522     db().Close();
    523     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    524   }
    525 
    526   db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback,
    527                                      base::Unretained(this),
    528                                      SQLITE_CORRUPT));
    529 
    530   // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
    531   // callback will call RazeAndClose().  Open() will then fail and be
    532   // retried.  The second Open() on the empty database will succeed
    533   // cleanly.
    534   ASSERT_TRUE(db().Open(db_path()));
    535   ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
    536   EXPECT_EQ(0, SqliteMasterCount(&db()));
    537 }
    538 
    539 // Basic test of RazeAndClose() operation.
    540 TEST_F(SQLConnectionTest, RazeAndClose) {
    541   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    542   const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
    543 
    544   // Test that RazeAndClose() closes the database, and that the
    545   // database is empty when re-opened.
    546   ASSERT_TRUE(db().Execute(kCreateSql));
    547   ASSERT_TRUE(db().Execute(kPopulateSql));
    548   ASSERT_TRUE(db().RazeAndClose());
    549   ASSERT_FALSE(db().is_open());
    550   db().Close();
    551   ASSERT_TRUE(db().Open(db_path()));
    552   ASSERT_EQ(0, SqliteMasterCount(&db()));
    553 
    554   // Test that RazeAndClose() can break transactions.
    555   ASSERT_TRUE(db().Execute(kCreateSql));
    556   ASSERT_TRUE(db().Execute(kPopulateSql));
    557   ASSERT_TRUE(db().BeginTransaction());
    558   ASSERT_TRUE(db().RazeAndClose());
    559   ASSERT_FALSE(db().is_open());
    560   ASSERT_FALSE(db().CommitTransaction());
    561   db().Close();
    562   ASSERT_TRUE(db().Open(db_path()));
    563   ASSERT_EQ(0, SqliteMasterCount(&db()));
    564 }
    565 
    566 // Test that various operations fail without crashing after
    567 // RazeAndClose().
    568 TEST_F(SQLConnectionTest, RazeAndCloseDiagnostics) {
    569   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    570   const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
    571   const char* kSimpleSql = "SELECT 1";
    572 
    573   ASSERT_TRUE(db().Execute(kCreateSql));
    574   ASSERT_TRUE(db().Execute(kPopulateSql));
    575 
    576   // Test baseline expectations.
    577   db().Preload();
    578   ASSERT_TRUE(db().DoesTableExist("foo"));
    579   ASSERT_TRUE(db().IsSQLValid(kSimpleSql));
    580   ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql));
    581   ASSERT_TRUE(db().Execute(kSimpleSql));
    582   ASSERT_TRUE(db().is_open());
    583   {
    584     sql::Statement s(db().GetUniqueStatement(kSimpleSql));
    585     ASSERT_TRUE(s.Step());
    586   }
    587   {
    588     sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
    589     ASSERT_TRUE(s.Step());
    590   }
    591   ASSERT_TRUE(db().BeginTransaction());
    592   ASSERT_TRUE(db().CommitTransaction());
    593   ASSERT_TRUE(db().BeginTransaction());
    594   db().RollbackTransaction();
    595 
    596   ASSERT_TRUE(db().RazeAndClose());
    597 
    598   // At this point, they should all fail, but not crash.
    599   db().Preload();
    600   ASSERT_FALSE(db().DoesTableExist("foo"));
    601   ASSERT_FALSE(db().IsSQLValid(kSimpleSql));
    602   ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql));
    603   ASSERT_FALSE(db().Execute(kSimpleSql));
    604   ASSERT_FALSE(db().is_open());
    605   {
    606     sql::Statement s(db().GetUniqueStatement(kSimpleSql));
    607     ASSERT_FALSE(s.Step());
    608   }
    609   {
    610     sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
    611     ASSERT_FALSE(s.Step());
    612   }
    613   ASSERT_FALSE(db().BeginTransaction());
    614   ASSERT_FALSE(db().CommitTransaction());
    615   ASSERT_FALSE(db().BeginTransaction());
    616   db().RollbackTransaction();
    617 
    618   // Close normally to reset the poisoned flag.
    619   db().Close();
    620 
    621   // DEATH tests not supported on Android or iOS.
    622 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    623   // Once the real Close() has been called, various calls enforce API
    624   // usage by becoming fatal in debug mode.  Since DEATH tests are
    625   // expensive, just test one of them.
    626   if (DLOG_IS_ON(FATAL)) {
    627     ASSERT_DEATH({
    628         db().IsSQLValid(kSimpleSql);
    629       }, "Illegal use of connection without a db");
    630   }
    631 #endif
    632 }
    633 
    634 // TODO(shess): Spin up a background thread to hold other_db, to more
    635 // closely match real life.  That would also allow testing
    636 // RazeWithTimeout().
    637 
    638 #if defined(OS_ANDROID)
    639 TEST_F(SQLConnectionTest, SetTempDirForSQL) {
    640 
    641   sql::MetaTable meta_table;
    642   // Below call needs a temporary directory in sqlite3
    643   // On Android, it can pass only when the temporary directory is set.
    644   // Otherwise, sqlite3 doesn't find the correct directory to store
    645   // temporary files and will report the error 'unable to open
    646   // database file'.
    647   ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
    648 }
    649 #endif
    650 
    651 TEST_F(SQLConnectionTest, Delete) {
    652   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
    653   db().Close();
    654 
    655   // Should have both a main database file and a journal file because
    656   // of journal_mode PERSIST.
    657   base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
    658   ASSERT_TRUE(base::PathExists(db_path()));
    659   ASSERT_TRUE(base::PathExists(journal));
    660 
    661   sql::Connection::Delete(db_path());
    662   EXPECT_FALSE(base::PathExists(db_path()));
    663   EXPECT_FALSE(base::PathExists(journal));
    664 }
    665 
    666 #if defined(OS_POSIX)
    667 // Test that set_restrict_to_user() trims database permissions so that
    668 // only the owner (and root) can read.
    669 TEST_F(SQLConnectionTest, UserPermission) {
    670   // If the bots all had a restrictive umask setting such that
    671   // databases are always created with only the owner able to read
    672   // them, then the code could break without breaking the tests.
    673   // Temporarily provide a more permissive umask.
    674   db().Close();
    675   sql::Connection::Delete(db_path());
    676   ASSERT_FALSE(base::PathExists(db_path()));
    677   ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
    678   ASSERT_TRUE(db().Open(db_path()));
    679 
    680   // Cause the journal file to be created.  If the default
    681   // journal_mode is changed back to DELETE, then parts of this test
    682   // will need to be updated.
    683   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
    684 
    685   base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
    686   int mode;
    687 
    688   // Given a permissive umask, the database is created with permissive
    689   // read access for the database and journal.
    690   ASSERT_TRUE(base::PathExists(db_path()));
    691   ASSERT_TRUE(base::PathExists(journal));
    692   mode = base::FILE_PERMISSION_MASK;
    693   EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
    694   ASSERT_NE((mode & base::FILE_PERMISSION_USER_MASK), mode);
    695   mode = base::FILE_PERMISSION_MASK;
    696   EXPECT_TRUE(base::GetPosixFilePermissions(journal, &mode));
    697   ASSERT_NE((mode & base::FILE_PERMISSION_USER_MASK), mode);
    698 
    699   // Re-open with restricted permissions and verify that the modes
    700   // changed for both the main database and the journal.
    701   db().Close();
    702   db().set_restrict_to_user();
    703   ASSERT_TRUE(db().Open(db_path()));
    704   ASSERT_TRUE(base::PathExists(db_path()));
    705   ASSERT_TRUE(base::PathExists(journal));
    706   mode = base::FILE_PERMISSION_MASK;
    707   EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
    708   ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
    709   mode = base::FILE_PERMISSION_MASK;
    710   EXPECT_TRUE(base::GetPosixFilePermissions(journal, &mode));
    711   ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
    712 
    713   // Delete and re-create the database, the restriction should still apply.
    714   db().Close();
    715   sql::Connection::Delete(db_path());
    716   ASSERT_TRUE(db().Open(db_path()));
    717   ASSERT_TRUE(base::PathExists(db_path()));
    718   ASSERT_FALSE(base::PathExists(journal));
    719   mode = base::FILE_PERMISSION_MASK;
    720   EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
    721   ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
    722 
    723   // Verify that journal creation inherits the restriction.
    724   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
    725   ASSERT_TRUE(base::PathExists(journal));
    726   mode = base::FILE_PERMISSION_MASK;
    727   EXPECT_TRUE(base::GetPosixFilePermissions(journal, &mode));
    728   ASSERT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
    729 }
    730 #endif  // defined(OS_POSIX)
    731 
    732 // Test that errors start happening once Poison() is called.
    733 TEST_F(SQLConnectionTest, Poison) {
    734   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
    735 
    736   // Before the Poison() call, things generally work.
    737   EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
    738   EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
    739   {
    740     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
    741     ASSERT_TRUE(s.is_valid());
    742     ASSERT_TRUE(s.Step());
    743   }
    744 
    745   // Get a statement which is valid before and will exist across Poison().
    746   sql::Statement valid_statement(
    747       db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
    748   ASSERT_TRUE(valid_statement.is_valid());
    749   ASSERT_TRUE(valid_statement.Step());
    750   valid_statement.Reset(true);
    751 
    752   db().Poison();
    753 
    754   // After the Poison() call, things fail.
    755   EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
    756   EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
    757   {
    758     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
    759     ASSERT_FALSE(s.is_valid());
    760     ASSERT_FALSE(s.Step());
    761   }
    762 
    763   // The existing statement has become invalid.
    764   ASSERT_FALSE(valid_statement.is_valid());
    765   ASSERT_FALSE(valid_statement.Step());
    766 }
    767 
    768 // Test attaching and detaching databases from the connection.
    769 TEST_F(SQLConnectionTest, Attach) {
    770   EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
    771 
    772   // Create a database to attach to.
    773   base::FilePath attach_path =
    774       db_path().DirName().AppendASCII("SQLConnectionAttach.db");
    775   const char kAttachmentPoint[] = "other";
    776   {
    777     sql::Connection other_db;
    778     ASSERT_TRUE(other_db.Open(attach_path));
    779     EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
    780     EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
    781   }
    782 
    783   // Cannot see the attached database, yet.
    784   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
    785 
    786   // Attach fails in a transaction.
    787   EXPECT_TRUE(db().BeginTransaction());
    788   {
    789     sql::ScopedErrorIgnorer ignore_errors;
    790     ignore_errors.IgnoreError(SQLITE_ERROR);
    791     EXPECT_FALSE(db().AttachDatabase(attach_path, kAttachmentPoint));
    792     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    793   }
    794 
    795   // Attach succeeds when the transaction is closed.
    796   db().RollbackTransaction();
    797   EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint));
    798   EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
    799 
    800   // Queries can touch both databases.
    801   EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
    802   {
    803     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
    804     ASSERT_TRUE(s.Step());
    805     EXPECT_EQ(1, s.ColumnInt(0));
    806   }
    807 
    808   // Detach also fails in a transaction.
    809   EXPECT_TRUE(db().BeginTransaction());
    810   {
    811     sql::ScopedErrorIgnorer ignore_errors;
    812     ignore_errors.IgnoreError(SQLITE_ERROR);
    813     EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint));
    814     EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
    815     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    816   }
    817 
    818   // Detach succeeds outside of a transaction.
    819   db().RollbackTransaction();
    820   EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint));
    821 
    822   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
    823 }
    824 
    825 TEST_F(SQLConnectionTest, Basic_QuickIntegrityCheck) {
    826   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    827   ASSERT_TRUE(db().Execute(kCreateSql));
    828   EXPECT_TRUE(db().QuickIntegrityCheck());
    829   db().Close();
    830 
    831   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
    832 
    833   {
    834     sql::ScopedErrorIgnorer ignore_errors;
    835     ignore_errors.IgnoreError(SQLITE_CORRUPT);
    836     ASSERT_TRUE(db().Open(db_path()));
    837     EXPECT_FALSE(db().QuickIntegrityCheck());
    838     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    839   }
    840 }
    841 
    842 TEST_F(SQLConnectionTest, Basic_FullIntegrityCheck) {
    843   const std::string kOk("ok");
    844   std::vector<std::string> messages;
    845 
    846   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
    847   ASSERT_TRUE(db().Execute(kCreateSql));
    848   EXPECT_TRUE(db().FullIntegrityCheck(&messages));
    849   EXPECT_EQ(1u, messages.size());
    850   EXPECT_EQ(kOk, messages[0]);
    851   db().Close();
    852 
    853   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
    854 
    855   {
    856     sql::ScopedErrorIgnorer ignore_errors;
    857     ignore_errors.IgnoreError(SQLITE_CORRUPT);
    858     ASSERT_TRUE(db().Open(db_path()));
    859     EXPECT_TRUE(db().FullIntegrityCheck(&messages));
    860     EXPECT_LT(1u, messages.size());
    861     EXPECT_NE(kOk, messages[0]);
    862     ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    863   }
    864 
    865   // TODO(shess): CorruptTableOrIndex could be used to produce a
    866   // file that would pass the quick check and fail the full check.
    867 }
    868 
    869 }  // namespace
    870