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