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.
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_file.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/test/gtest_util.h"
16 #include "base/test/metrics/histogram_tester.h"
17 #include "base/test/scoped_feature_list.h"
18 #include "base/trace_event/process_memory_dump.h"
19 #include "build/build_config.h"
20 #include "sql/database.h"
21 #include "sql/database_memory_dump_provider.h"
22 #include "sql/meta_table.h"
23 #include "sql/sql_features.h"
24 #include "sql/statement.h"
25 #include "sql/test/database_test_peer.h"
26 #include "sql/test/error_callback_support.h"
27 #include "sql/test/scoped_error_expecter.h"
28 #include "sql/test/sql_test_base.h"
29 #include "sql/test/test_helpers.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/sqlite/sqlite3.h"
37 using sql::test::ExecuteWithResult;
39 // Helper to return the count of items in sqlite_master. Return -1 in
41 int SqliteMasterCount(sql::Database* db) {
42 const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
43 sql::Statement s(db->GetUniqueStatement(kMasterCount));
44 return s.Step() ? s.ColumnInt(0) : -1;
47 // Track the number of valid references which share the same pointer.
48 // This is used to allow testing an implicitly use-after-free case by
49 // explicitly having the ref count live longer than the object.
52 RefCounter(size_t* counter) : counter_(counter) { (*counter_)++; }
53 RefCounter(const RefCounter& other) : counter_(other.counter_) {
56 ~RefCounter() { (*counter_)--; }
61 DISALLOW_ASSIGN(RefCounter);
64 // Empty callback for implementation of ErrorCallbackSetHelper().
65 void IgnoreErrorCallback(int error, sql::Statement* stmt) {}
67 void ErrorCallbackSetHelper(sql::Database* db,
71 sql::Statement* stmt) {
72 // The ref count should not go to zero when changing the callback.
73 EXPECT_GT(*counter, 0u);
74 db->set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
75 EXPECT_GT(*counter, 0u);
78 void ErrorCallbackResetHelper(sql::Database* db,
82 sql::Statement* stmt) {
83 // The ref count should not go to zero when clearing the callback.
84 EXPECT_GT(*counter, 0u);
85 db->reset_error_callback();
86 EXPECT_GT(*counter, 0u);
89 // Handle errors by blowing away the database.
90 void RazeErrorCallback(sql::Database* db,
93 sql::Statement* stmt) {
94 // Nothing here needs extended errors at this time.
95 EXPECT_EQ(expected_error, expected_error & 0xff);
96 EXPECT_EQ(expected_error, error & 0xff);
100 #if defined(OS_POSIX)
101 // Set a umask and restore the old mask on destruction. Cribbed from
102 // shared_memory_unittest.cc. Used by POSIX-only UserPermission test.
103 class ScopedUmaskSetter {
105 explicit ScopedUmaskSetter(mode_t target_mask) {
106 old_umask_ = umask(target_mask);
108 ~ScopedUmaskSetter() { umask(old_umask_); }
112 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
114 #endif // defined(OS_POSIX)
118 using SQLDatabaseTest = sql::SQLTestBase;
120 TEST_F(SQLDatabaseTest, Execute) {
121 // Valid statement should return true.
122 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
123 EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
125 // Invalid statement should fail.
126 ASSERT_EQ(SQLITE_ERROR,
127 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
128 EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
131 TEST_F(SQLDatabaseTest, ExecuteWithErrorCode) {
133 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
134 ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
135 ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(
136 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
139 TEST_F(SQLDatabaseTest, CachedStatement) {
140 sql::StatementID id1 = SQL_FROM_HERE;
141 sql::StatementID id2 = SQL_FROM_HERE;
142 static const char kId1Sql[] = "SELECT a FROM foo";
143 static const char kId2Sql[] = "SELECT b FROM foo";
145 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
146 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
148 sqlite3_stmt* raw_id1_statement;
149 sqlite3_stmt* raw_id2_statement;
151 scoped_refptr<sql::Database::StatementRef> ref_from_id1 =
152 db().GetCachedStatement(id1, kId1Sql);
153 raw_id1_statement = ref_from_id1->stmt();
155 sql::Statement from_id1(std::move(ref_from_id1));
156 ASSERT_TRUE(from_id1.is_valid());
157 ASSERT_TRUE(from_id1.Step());
158 EXPECT_EQ(12, from_id1.ColumnInt(0));
160 scoped_refptr<sql::Database::StatementRef> ref_from_id2 =
161 db().GetCachedStatement(id2, kId2Sql);
162 raw_id2_statement = ref_from_id2->stmt();
163 EXPECT_NE(raw_id1_statement, raw_id2_statement);
165 sql::Statement from_id2(std::move(ref_from_id2));
166 ASSERT_TRUE(from_id2.is_valid());
167 ASSERT_TRUE(from_id2.Step());
168 EXPECT_EQ(13, from_id2.ColumnInt(0));
172 scoped_refptr<sql::Database::StatementRef> ref_from_id1 =
173 db().GetCachedStatement(id1, kId1Sql);
174 EXPECT_EQ(raw_id1_statement, ref_from_id1->stmt())
175 << "statement was not cached";
177 sql::Statement from_id1(std::move(ref_from_id1));
178 ASSERT_TRUE(from_id1.is_valid());
179 ASSERT_TRUE(from_id1.Step()) << "cached statement was not reset";
180 EXPECT_EQ(12, from_id1.ColumnInt(0));
182 scoped_refptr<sql::Database::StatementRef> ref_from_id2 =
183 db().GetCachedStatement(id2, kId2Sql);
184 EXPECT_EQ(raw_id2_statement, ref_from_id2->stmt())
185 << "statement was not cached";
187 sql::Statement from_id2(std::move(ref_from_id2));
188 ASSERT_TRUE(from_id2.is_valid());
189 ASSERT_TRUE(from_id2.Step()) << "cached statement was not reset";
190 EXPECT_EQ(13, from_id2.ColumnInt(0));
193 EXPECT_DCHECK_DEATH(db().GetCachedStatement(id1, kId2Sql))
194 << "Using a different SQL with the same statement ID should DCHECK";
195 EXPECT_DCHECK_DEATH(db().GetCachedStatement(id2, kId1Sql))
196 << "Using a different SQL with the same statement ID should DCHECK";
199 TEST_F(SQLDatabaseTest, IsSQLValidTest) {
200 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
201 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
202 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
205 TEST_F(SQLDatabaseTest, DoesTableExist) {
206 EXPECT_FALSE(db().DoesTableExist("foo"));
207 EXPECT_FALSE(db().DoesTableExist("foo_index"));
209 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
210 ASSERT_TRUE(db().Execute("CREATE INDEX foo_index ON foo (a)"));
211 EXPECT_TRUE(db().DoesTableExist("foo"));
212 EXPECT_FALSE(db().DoesTableExist("foo_index"));
214 // DoesTableExist() is case-sensitive.
215 EXPECT_FALSE(db().DoesTableExist("Foo"));
216 EXPECT_FALSE(db().DoesTableExist("FOO"));
219 TEST_F(SQLDatabaseTest, DoesIndexExist) {
220 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
221 EXPECT_FALSE(db().DoesIndexExist("foo"));
222 EXPECT_FALSE(db().DoesIndexExist("foo_ubdex"));
224 ASSERT_TRUE(db().Execute("CREATE INDEX foo_index ON foo (a)"));
225 EXPECT_TRUE(db().DoesIndexExist("foo_index"));
226 EXPECT_FALSE(db().DoesIndexExist("foo"));
228 // DoesIndexExist() is case-sensitive.
229 EXPECT_FALSE(db().DoesIndexExist("Foo_index"));
230 EXPECT_FALSE(db().DoesIndexExist("Foo_Index"));
231 EXPECT_FALSE(db().DoesIndexExist("FOO_INDEX"));
234 TEST_F(SQLDatabaseTest, DoesViewExist) {
235 EXPECT_FALSE(db().DoesViewExist("voo"));
236 ASSERT_TRUE(db().Execute("CREATE VIEW voo (a) AS SELECT 1"));
237 EXPECT_FALSE(db().DoesIndexExist("voo"));
238 EXPECT_FALSE(db().DoesTableExist("voo"));
239 EXPECT_TRUE(db().DoesViewExist("voo"));
241 // DoesTableExist() is case-sensitive.
242 EXPECT_FALSE(db().DoesViewExist("Voo"));
243 EXPECT_FALSE(db().DoesViewExist("VOO"));
246 TEST_F(SQLDatabaseTest, DoesColumnExist) {
247 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
249 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
250 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
252 ASSERT_FALSE(db().DoesTableExist("bar"));
253 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
255 // SQLite resolves table/column names without case sensitivity.
256 EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
257 EXPECT_TRUE(db().DoesColumnExist("FOO", "a"));
258 EXPECT_TRUE(db().DoesColumnExist("foo", "A"));
261 TEST_F(SQLDatabaseTest, GetLastInsertRowId) {
262 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
264 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
266 // Last insert row ID should be valid.
267 int64_t row = db().GetLastInsertRowId();
270 // It should be the primary key of the row we just inserted.
271 sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
273 ASSERT_TRUE(s.Step());
274 EXPECT_EQ(12, s.ColumnInt(0));
277 TEST_F(SQLDatabaseTest, Rollback) {
278 ASSERT_TRUE(db().BeginTransaction());
279 ASSERT_TRUE(db().BeginTransaction());
280 EXPECT_EQ(2, db().transaction_nesting());
281 db().RollbackTransaction();
282 EXPECT_FALSE(db().CommitTransaction());
283 EXPECT_TRUE(db().BeginTransaction());
286 // Test the scoped error expecter by attempting to insert a duplicate
287 // value into an index.
288 TEST_F(SQLDatabaseTest, ScopedErrorExpecter) {
289 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
290 ASSERT_TRUE(db().Execute(kCreateSql));
291 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
294 sql::test::ScopedErrorExpecter expecter;
295 expecter.ExpectError(SQLITE_CONSTRAINT);
296 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
297 ASSERT_TRUE(expecter.SawExpectedErrors());
301 // Test that clients of GetUntrackedStatement() can test corruption-handling
302 // with ScopedErrorExpecter.
303 TEST_F(SQLDatabaseTest, ScopedIgnoreUntracked) {
304 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
305 ASSERT_TRUE(db().Execute(kCreateSql));
306 ASSERT_FALSE(db().DoesTableExist("bar"));
307 ASSERT_TRUE(db().DoesTableExist("foo"));
308 ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
311 // Corrupt the database so that nothing works, including PRAGMAs.
312 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
315 sql::test::ScopedErrorExpecter expecter;
316 expecter.ExpectError(SQLITE_CORRUPT);
317 ASSERT_TRUE(db().Open(db_path()));
318 ASSERT_FALSE(db().DoesTableExist("bar"));
319 ASSERT_FALSE(db().DoesTableExist("foo"));
320 ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
321 ASSERT_TRUE(expecter.SawExpectedErrors());
325 TEST_F(SQLDatabaseTest, ErrorCallback) {
326 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
327 ASSERT_TRUE(db().Execute(kCreateSql));
328 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
330 int error = SQLITE_OK;
332 sql::ScopedErrorCallback sec(
333 &db(), base::BindRepeating(&sql::CaptureErrorCallback, &error));
334 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
336 // Later versions of SQLite throw SQLITE_CONSTRAINT_UNIQUE. The specific
337 // sub-error isn't really important.
338 EXPECT_EQ(SQLITE_CONSTRAINT, (error & 0xff));
341 // Callback is no longer in force due to reset.
344 sql::test::ScopedErrorExpecter expecter;
345 expecter.ExpectError(SQLITE_CONSTRAINT);
346 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
347 ASSERT_TRUE(expecter.SawExpectedErrors());
348 EXPECT_EQ(SQLITE_OK, error);
351 // base::BindRepeating() can curry arguments to be passed by const reference
352 // to the callback function. If the callback function calls
353 // re/set_error_callback(), the storage for those arguments can be
354 // deleted while the callback function is still executing.
356 // RefCounter() counts how many objects are live using an external
357 // count. The same counter is passed to the callback, so that it
358 // can check directly even if the RefCounter object is no longer
362 sql::ScopedErrorCallback sec(
363 &db(), base::BindRepeating(&ErrorCallbackSetHelper, &db(), &count,
364 RefCounter(&count)));
366 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
369 // Same test, but reset_error_callback() case.
372 sql::ScopedErrorCallback sec(
373 &db(), base::BindRepeating(&ErrorCallbackResetHelper, &db(), &count,
374 RefCounter(&count)));
376 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
380 // Test that sql::Database::Raze() results in a database without the
381 // tables from the original database.
382 TEST_F(SQLDatabaseTest, Raze) {
383 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
384 ASSERT_TRUE(db().Execute(kCreateSql));
385 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
387 int pragma_auto_vacuum = 0;
389 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
390 ASSERT_TRUE(s.Step());
391 pragma_auto_vacuum = s.ColumnInt(0);
392 ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
395 // If auto_vacuum is set, there's an extra page to maintain a freelist.
396 const int kExpectedPageCount = 2 + pragma_auto_vacuum;
399 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
400 ASSERT_TRUE(s.Step());
401 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
405 sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
406 ASSERT_TRUE(s.Step());
407 EXPECT_EQ("table", s.ColumnString(0));
408 EXPECT_EQ("foo", s.ColumnString(1));
409 EXPECT_EQ("foo", s.ColumnString(2));
410 // Table "foo" is stored in the last page of the file.
411 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3));
412 EXPECT_EQ(kCreateSql, s.ColumnString(4));
415 ASSERT_TRUE(db().Raze());
418 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
419 ASSERT_TRUE(s.Step());
420 EXPECT_EQ(1, s.ColumnInt(0));
423 ASSERT_EQ(0, SqliteMasterCount(&db()));
426 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
427 ASSERT_TRUE(s.Step());
428 // The new database has the same auto_vacuum as a fresh database.
429 EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
433 // Helper for SQLDatabaseTest.RazePageSize. Creates a fresh db based on
434 // db_prefix, with the given initial page size, and verifies it against the
435 // expected size. Then changes to the final page size and razes, verifying that
436 // the fresh database ends up with the expected final page size.
437 void TestPageSize(const base::FilePath& db_prefix,
438 int initial_page_size,
439 const std::string& expected_initial_page_size,
441 const std::string& expected_final_page_size) {
442 static const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
443 static const char kInsertSql1[] = "INSERT INTO x VALUES ('This is a test')";
444 static const char kInsertSql2[] = "INSERT INTO x VALUES ('That was a test')";
446 const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
447 base::NumberToString(initial_page_size));
448 sql::Database::Delete(db_path);
450 db.set_page_size(initial_page_size);
451 ASSERT_TRUE(db.Open(db_path));
452 ASSERT_TRUE(db.Execute(kCreateSql));
453 ASSERT_TRUE(db.Execute(kInsertSql1));
454 ASSERT_TRUE(db.Execute(kInsertSql2));
455 ASSERT_EQ(expected_initial_page_size,
456 ExecuteWithResult(&db, "PRAGMA page_size"));
458 // Raze will use the page size set in the connection object, which may not
459 // match the file's page size.
460 db.set_page_size(final_page_size);
461 ASSERT_TRUE(db.Raze());
463 // SQLite 3.10.2 (at least) has a quirk with the sqlite3_backup() API (used by
464 // Raze()) which causes the destination database to remember the previous
465 // page_size, even if the overwriting database changed the page_size. Access
466 // the actual database to cause the cached value to be updated.
467 EXPECT_EQ("0", ExecuteWithResult(&db, "SELECT COUNT(*) FROM sqlite_master"));
469 EXPECT_EQ(expected_final_page_size,
470 ExecuteWithResult(&db, "PRAGMA page_size"));
471 EXPECT_EQ("1", ExecuteWithResult(&db, "PRAGMA page_count"));
474 // Verify that sql::Recovery maintains the page size, and the virtual table
475 // works with page sizes other than SQLite's default. Also verify the case
476 // where the default page size has changed.
477 TEST_F(SQLDatabaseTest, RazePageSize) {
478 const std::string default_page_size =
479 ExecuteWithResult(&db(), "PRAGMA page_size");
481 // Sync uses 32k pages.
482 EXPECT_NO_FATAL_FAILURE(
483 TestPageSize(db_path(), 32768, "32768", 32768, "32768"));
485 // Many clients use 4k pages. This is the SQLite default after 3.12.0.
486 EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 4096, "4096", 4096, "4096"));
488 // 1k is the default page size before 3.12.0.
489 EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 1024, "1024", 1024, "1024"));
491 EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 2048, "2048", 4096, "4096"));
493 // Databases with no page size specified should result in the default
494 // page size. 2k has never been the default page size.
495 ASSERT_NE("2048", default_page_size);
496 EXPECT_NO_FATAL_FAILURE(TestPageSize(
497 db_path(), 2048, "2048", Database::kDefaultPageSize, default_page_size));
500 // Test that Raze() results are seen in other connections.
501 TEST_F(SQLDatabaseTest, RazeMultiple) {
502 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
503 ASSERT_TRUE(db().Execute(kCreateSql));
505 sql::Database other_db;
506 ASSERT_TRUE(other_db.Open(db_path()));
508 // Check that the second connection sees the table.
509 ASSERT_EQ(1, SqliteMasterCount(&other_db));
511 ASSERT_TRUE(db().Raze());
513 // The second connection sees the updated database.
514 ASSERT_EQ(0, SqliteMasterCount(&other_db));
517 TEST_F(SQLDatabaseTest, RazeLocked) {
518 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
519 ASSERT_TRUE(db().Execute(kCreateSql));
521 // Open a transaction and write some data in a second connection.
522 // This will acquire a PENDING or EXCLUSIVE transaction, which will
523 // cause the raze to fail.
524 sql::Database other_db;
525 ASSERT_TRUE(other_db.Open(db_path()));
526 ASSERT_TRUE(other_db.BeginTransaction());
527 const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
528 ASSERT_TRUE(other_db.Execute(kInsertSql));
530 ASSERT_FALSE(db().Raze());
532 // Works after COMMIT.
533 ASSERT_TRUE(other_db.CommitTransaction());
534 ASSERT_TRUE(db().Raze());
536 // Re-create the database.
537 ASSERT_TRUE(db().Execute(kCreateSql));
538 ASSERT_TRUE(db().Execute(kInsertSql));
540 // An unfinished read transaction in the other connection also
542 // This doesn't happen in WAL mode because reads are no longer blocked by
543 // write operations when using a WAL.
544 if (!base::FeatureList::IsEnabled(sql::features::kEnableWALModeByDefault)) {
545 const char* kQuery = "SELECT COUNT(*) FROM foo";
546 sql::Statement s(other_db.GetUniqueStatement(kQuery));
547 ASSERT_TRUE(s.Step());
548 ASSERT_FALSE(db().Raze());
550 // Completing the statement unlocks the database.
551 ASSERT_FALSE(s.Step());
552 ASSERT_TRUE(db().Raze());
556 // Verify that Raze() can handle an empty file. SQLite should treat
557 // this as an empty database.
558 TEST_F(SQLDatabaseTest, RazeEmptyDB) {
559 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
560 ASSERT_TRUE(db().Execute(kCreateSql));
565 ASSERT_TRUE(db().Open(db_path()));
566 ASSERT_TRUE(db().Raze());
567 EXPECT_EQ(0, SqliteMasterCount(&db()));
570 // Verify that Raze() can handle a file of junk.
571 TEST_F(SQLDatabaseTest, RazeNOTADB) {
573 sql::Database::Delete(db_path());
574 ASSERT_FALSE(GetPathExists(db_path()));
576 WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE_AND_TRUNCATE);
577 ASSERT_TRUE(GetPathExists(db_path()));
579 // SQLite will successfully open the handle, but fail when running PRAGMA
580 // statements that access the database.
582 sql::test::ScopedErrorExpecter expecter;
583 expecter.ExpectError(SQLITE_NOTADB);
585 EXPECT_TRUE(db().Open(db_path()));
586 ASSERT_TRUE(expecter.SawExpectedErrors());
588 EXPECT_TRUE(db().Raze());
591 // Now empty, the open should open an empty database.
592 EXPECT_TRUE(db().Open(db_path()));
593 EXPECT_EQ(0, SqliteMasterCount(&db()));
596 // Verify that Raze() can handle a database overwritten with garbage.
597 TEST_F(SQLDatabaseTest, RazeNOTADB2) {
598 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
599 ASSERT_TRUE(db().Execute(kCreateSql));
600 ASSERT_EQ(1, SqliteMasterCount(&db()));
603 WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE);
605 // SQLite will successfully open the handle, but will fail with
606 // SQLITE_NOTADB on pragma statemenets which attempt to read the
609 sql::test::ScopedErrorExpecter expecter;
610 expecter.ExpectError(SQLITE_NOTADB);
611 EXPECT_TRUE(db().Open(db_path()));
612 ASSERT_TRUE(expecter.SawExpectedErrors());
614 EXPECT_TRUE(db().Raze());
617 // Now empty, the open should succeed with an empty database.
618 EXPECT_TRUE(db().Open(db_path()));
619 EXPECT_EQ(0, SqliteMasterCount(&db()));
622 // Test that a callback from Open() can raze the database. This is
623 // essential for cases where the Open() can fail entirely, so the
624 // Raze() cannot happen later. Additionally test that when the
625 // callback does this during Open(), the open is retried and succeeds.
626 TEST_F(SQLDatabaseTest, RazeCallbackReopen) {
627 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
628 ASSERT_TRUE(db().Execute(kCreateSql));
629 ASSERT_EQ(1, SqliteMasterCount(&db()));
632 // Corrupt the database so that nothing works, including PRAGMAs.
633 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
635 // Open() will succeed, even though the PRAGMA calls within will
636 // fail with SQLITE_CORRUPT, as will this PRAGMA.
638 sql::test::ScopedErrorExpecter expecter;
639 expecter.ExpectError(SQLITE_CORRUPT);
640 ASSERT_TRUE(db().Open(db_path()));
641 ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
643 ASSERT_TRUE(expecter.SawExpectedErrors());
646 db().set_error_callback(
647 base::BindRepeating(&RazeErrorCallback, &db(), SQLITE_CORRUPT));
649 // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
650 // callback will call RazeAndClose(). Open() will then fail and be
651 // retried. The second Open() on the empty database will succeed
653 ASSERT_TRUE(db().Open(db_path()));
654 ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
655 EXPECT_EQ(0, SqliteMasterCount(&db()));
658 // Basic test of RazeAndClose() operation.
659 TEST_F(SQLDatabaseTest, RazeAndClose) {
660 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
661 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
663 // Test that RazeAndClose() closes the database, and that the
664 // database is empty when re-opened.
665 ASSERT_TRUE(db().Execute(kCreateSql));
666 ASSERT_TRUE(db().Execute(kPopulateSql));
667 ASSERT_TRUE(db().RazeAndClose());
668 ASSERT_FALSE(db().is_open());
670 ASSERT_TRUE(db().Open(db_path()));
671 ASSERT_EQ(0, SqliteMasterCount(&db()));
673 // Test that RazeAndClose() can break transactions.
674 ASSERT_TRUE(db().Execute(kCreateSql));
675 ASSERT_TRUE(db().Execute(kPopulateSql));
676 ASSERT_TRUE(db().BeginTransaction());
677 ASSERT_TRUE(db().RazeAndClose());
678 ASSERT_FALSE(db().is_open());
679 ASSERT_FALSE(db().CommitTransaction());
681 ASSERT_TRUE(db().Open(db_path()));
682 ASSERT_EQ(0, SqliteMasterCount(&db()));
685 // Test that various operations fail without crashing after
687 TEST_F(SQLDatabaseTest, RazeAndCloseDiagnostics) {
688 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
689 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
690 const char* kSimpleSql = "SELECT 1";
692 ASSERT_TRUE(db().Execute(kCreateSql));
693 ASSERT_TRUE(db().Execute(kPopulateSql));
695 // Test baseline expectations.
697 ASSERT_TRUE(db().DoesTableExist("foo"));
698 ASSERT_TRUE(db().IsSQLValid(kSimpleSql));
699 ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql));
700 ASSERT_TRUE(db().Execute(kSimpleSql));
701 ASSERT_TRUE(db().is_open());
703 sql::Statement s(db().GetUniqueStatement(kSimpleSql));
704 ASSERT_TRUE(s.Step());
707 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
708 ASSERT_TRUE(s.Step());
710 ASSERT_TRUE(db().BeginTransaction());
711 ASSERT_TRUE(db().CommitTransaction());
712 ASSERT_TRUE(db().BeginTransaction());
713 db().RollbackTransaction();
715 ASSERT_TRUE(db().RazeAndClose());
717 // At this point, they should all fail, but not crash.
719 ASSERT_FALSE(db().DoesTableExist("foo"));
720 ASSERT_FALSE(db().IsSQLValid(kSimpleSql));
721 ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql));
722 ASSERT_FALSE(db().Execute(kSimpleSql));
723 ASSERT_FALSE(db().is_open());
725 sql::Statement s(db().GetUniqueStatement(kSimpleSql));
726 ASSERT_FALSE(s.Step());
729 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
730 ASSERT_FALSE(s.Step());
732 ASSERT_FALSE(db().BeginTransaction());
733 ASSERT_FALSE(db().CommitTransaction());
734 ASSERT_FALSE(db().BeginTransaction());
735 db().RollbackTransaction();
737 // Close normally to reset the poisoned flag.
740 // DEATH tests not supported on Android, iOS, or Fuchsia.
741 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
742 // Once the real Close() has been called, various calls enforce API
743 // usage by becoming fatal in debug mode. Since DEATH tests are
744 // expensive, just test one of them.
745 if (DLOG_IS_ON(FATAL)) {
746 ASSERT_DEATH({ db().IsSQLValid(kSimpleSql); },
747 "Illegal use of Database without a db");
749 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
752 // TODO(shess): Spin up a background thread to hold other_db, to more
753 // closely match real life. That would also allow testing
754 // RazeWithTimeout().
756 // On Windows, truncate silently fails against a memory-mapped file. One goal
757 // of Raze() is to truncate the file to remove blocks which generate I/O errors.
758 // Test that Raze() turns off memory mapping so that the file is truncated.
759 // [This would not cover the case of multiple connections where one of the other
760 // connections is memory-mapped. That is infrequent in Chromium.]
761 TEST_F(SQLDatabaseTest, RazeTruncate) {
762 // The empty database has 0 or 1 pages. Raze() should leave it with exactly 1
763 // page. Not checking directly because auto_vacuum on Android adds a freelist
765 ASSERT_TRUE(db().Raze());
766 int64_t expected_size;
767 ASSERT_TRUE(base::GetFileSize(db_path(), &expected_size));
768 ASSERT_GT(expected_size, 0);
770 // Cause the database to take a few pages.
771 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
772 ASSERT_TRUE(db().Execute(kCreateSql));
773 for (size_t i = 0; i < 24; ++i) {
775 db().Execute("INSERT INTO foo (value) VALUES (randomblob(1024))"));
778 // In WAL mode, writes don't reach the database file until a checkpoint
780 ASSERT_TRUE(db().CheckpointDatabase());
783 ASSERT_TRUE(base::GetFileSize(db_path(), &db_size));
784 ASSERT_GT(db_size, expected_size);
786 // Make a query covering most of the database file to make sure that the
787 // blocks are actually mapped into memory. Empirically, the truncate problem
788 // doesn't seem to happen if no blocks are mapped.
790 ExecuteWithResult(&db(), "SELECT SUM(LENGTH(value)) FROM foo"));
792 ASSERT_TRUE(db().Raze());
793 ASSERT_TRUE(base::GetFileSize(db_path(), &db_size));
794 ASSERT_EQ(expected_size, db_size);
797 #if defined(OS_ANDROID)
798 TEST_F(SQLDatabaseTest, SetTempDirForSQL) {
799 sql::MetaTable meta_table;
800 // Below call needs a temporary directory in sqlite3
801 // On Android, it can pass only when the temporary directory is set.
802 // Otherwise, sqlite3 doesn't find the correct directory to store
803 // temporary files and will report the error 'unable to open
805 ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
807 #endif // defined(OS_ANDROID)
809 // Contained param indicates whether WAL mode is switched on or not.
810 class JournalModeTest : public SQLDatabaseTest,
811 public testing::WithParamInterface<bool> {
813 void SetUp() override {
814 #if defined(OS_FUCHSIA) // Exclusive mode needs to be enabled to enter WAL mode
816 if (IsWALEnabled()) {
817 db().set_exclusive_locking();
819 #endif // defined(OS_FUCHSIA)
820 db().want_wal_mode(IsWALEnabled());
821 SQLDatabaseTest::SetUp();
824 bool IsWALEnabled() { return GetParam(); }
827 TEST_P(JournalModeTest, Delete) {
828 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
831 base::FilePath journal_path = sql::Database::JournalPath(db_path());
832 base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
834 // Should have both a main database file and a journal file if
835 // journal_mode is TRUNCATE. There is no WAL file as it is deleted on Close.
836 ASSERT_TRUE(GetPathExists(db_path()));
837 if (!IsWALEnabled()) { // TRUNCATE mode
838 ASSERT_TRUE(GetPathExists(journal_path));
841 sql::Database::Delete(db_path());
842 EXPECT_FALSE(GetPathExists(db_path()));
843 EXPECT_FALSE(GetPathExists(journal_path));
844 EXPECT_FALSE(GetPathExists(wal_path));
847 // WAL mode is currently not supported on Fuchsia
848 #if !defined(OS_FUCHSIA)
849 INSTANTIATE_TEST_SUITE_P(SQLDatabaseTest, JournalModeTest, testing::Bool());
851 INSTANTIATE_TEST_SUITE_P(SQLDatabaseTest,
853 testing::Values(false));
856 #if defined(OS_POSIX) // This test operates on POSIX file permissions.
857 TEST_P(JournalModeTest, PosixFilePermissions) {
859 sql::Database::Delete(db_path());
860 ASSERT_FALSE(GetPathExists(db_path()));
862 // If the bots all had a restrictive umask setting such that databases are
863 // always created with only the owner able to read them, then the code could
864 // break without breaking the tests. Temporarily provide a more permissive
866 ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
868 ASSERT_TRUE(db().Open(db_path()));
870 // Cause the journal file to be created. If the default journal_mode is
871 // changed back to DELETE, this test will need to be updated.
872 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
875 ASSERT_TRUE(GetPathExists(db_path()));
876 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
877 ASSERT_EQ(mode, 0600);
879 if (IsWALEnabled()) { // WAL mode
880 // The WAL file is created lazily on first change.
881 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
883 base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
884 ASSERT_TRUE(GetPathExists(wal_path));
885 EXPECT_TRUE(base::GetPosixFilePermissions(wal_path, &mode));
886 ASSERT_EQ(mode, 0600);
888 base::FilePath shm_path = sql::Database::SharedMemoryFilePath(db_path());
889 ASSERT_TRUE(GetPathExists(shm_path));
890 EXPECT_TRUE(base::GetPosixFilePermissions(shm_path, &mode));
891 ASSERT_EQ(mode, 0600);
892 } else { // Truncate mode
893 base::FilePath journal_path = sql::Database::JournalPath(db_path());
894 DLOG(ERROR) << "journal_path: " << journal_path;
895 ASSERT_TRUE(GetPathExists(journal_path));
896 EXPECT_TRUE(base::GetPosixFilePermissions(journal_path, &mode));
897 ASSERT_EQ(mode, 0600);
900 #endif // defined(OS_POSIX)
902 // Test that errors start happening once Poison() is called.
903 TEST_F(SQLDatabaseTest, Poison) {
904 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
906 // Before the Poison() call, things generally work.
907 EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
908 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
910 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
911 ASSERT_TRUE(s.is_valid());
912 ASSERT_TRUE(s.Step());
915 // Get a statement which is valid before and will exist across Poison().
916 sql::Statement valid_statement(
917 db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
918 ASSERT_TRUE(valid_statement.is_valid());
919 ASSERT_TRUE(valid_statement.Step());
920 valid_statement.Reset(true);
924 // After the Poison() call, things fail.
925 EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
926 EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
928 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
929 ASSERT_FALSE(s.is_valid());
930 ASSERT_FALSE(s.Step());
933 // The existing statement has become invalid.
934 ASSERT_FALSE(valid_statement.is_valid());
935 ASSERT_FALSE(valid_statement.Step());
937 // Test that poisoning the database during a transaction works (with errors).
938 // RazeErrorCallback() poisons the database, the extra COMMIT causes
939 // CommitTransaction() to throw an error while commiting.
940 db().set_error_callback(
941 base::BindRepeating(&RazeErrorCallback, &db(), SQLITE_ERROR));
943 ASSERT_TRUE(db().Open(db_path()));
944 EXPECT_TRUE(db().BeginTransaction());
945 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
946 EXPECT_TRUE(db().Execute("COMMIT"));
947 EXPECT_FALSE(db().CommitTransaction());
950 TEST_F(SQLDatabaseTest, AttachDatabase) {
951 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
953 // Create a database to attach to.
954 base::FilePath attach_path =
955 db_path().DirName().AppendASCII("SQLDatabaseAttach.db");
956 static const char kAttachmentPoint[] = "other";
958 sql::Database other_db;
959 ASSERT_TRUE(other_db.Open(attach_path));
960 EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
961 EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
964 // Cannot see the attached database, yet.
965 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
968 DatabaseTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
969 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
971 // Queries can touch both databases after the ATTACH.
972 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
974 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
975 ASSERT_TRUE(s.Step());
976 EXPECT_EQ(1, s.ColumnInt(0));
979 EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
980 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
983 TEST_F(SQLDatabaseTest, AttachDatabaseWithOpenTransaction) {
984 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
986 // Create a database to attach to.
987 base::FilePath attach_path =
988 db_path().DirName().AppendASCII("SQLDatabaseAttach.db");
989 static const char kAttachmentPoint[] = "other";
991 sql::Database other_db;
992 ASSERT_TRUE(other_db.Open(attach_path));
993 EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
994 EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
997 // Cannot see the attached database, yet.
998 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
1000 // Attach succeeds in a transaction.
1001 EXPECT_TRUE(db().BeginTransaction());
1003 DatabaseTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
1004 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
1006 // Queries can touch both databases after the ATTACH.
1007 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
1009 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
1010 ASSERT_TRUE(s.Step());
1011 EXPECT_EQ(1, s.ColumnInt(0));
1014 // Detaching the same database fails, database is locked in the transaction.
1016 sql::test::ScopedErrorExpecter expecter;
1017 expecter.ExpectError(SQLITE_ERROR);
1018 EXPECT_FALSE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
1019 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
1020 ASSERT_TRUE(expecter.SawExpectedErrors());
1023 // Detach succeeds when the transaction is closed.
1024 db().RollbackTransaction();
1025 EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
1026 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
1029 TEST_F(SQLDatabaseTest, Basic_QuickIntegrityCheck) {
1030 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1031 ASSERT_TRUE(db().Execute(kCreateSql));
1032 EXPECT_TRUE(db().QuickIntegrityCheck());
1035 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
1038 sql::test::ScopedErrorExpecter expecter;
1039 expecter.ExpectError(SQLITE_CORRUPT);
1040 ASSERT_TRUE(db().Open(db_path()));
1041 EXPECT_FALSE(db().QuickIntegrityCheck());
1042 ASSERT_TRUE(expecter.SawExpectedErrors());
1046 TEST_F(SQLDatabaseTest, Basic_FullIntegrityCheck) {
1047 const std::string kOk("ok");
1048 std::vector<std::string> messages;
1050 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1051 ASSERT_TRUE(db().Execute(kCreateSql));
1052 EXPECT_TRUE(db().FullIntegrityCheck(&messages));
1053 EXPECT_EQ(1u, messages.size());
1054 EXPECT_EQ(kOk, messages[0]);
1057 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
1060 sql::test::ScopedErrorExpecter expecter;
1061 expecter.ExpectError(SQLITE_CORRUPT);
1062 ASSERT_TRUE(db().Open(db_path()));
1063 EXPECT_TRUE(db().FullIntegrityCheck(&messages));
1064 EXPECT_LT(1u, messages.size());
1065 EXPECT_NE(kOk, messages[0]);
1066 ASSERT_TRUE(expecter.SawExpectedErrors());
1069 // TODO(shess): CorruptTableOrIndex could be used to produce a
1070 // file that would pass the quick check and fail the full check.
1073 TEST_F(SQLDatabaseTest, OnMemoryDump) {
1074 base::trace_event::MemoryDumpArgs args = {
1075 base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
1076 base::trace_event::ProcessMemoryDump pmd(args);
1077 ASSERT_TRUE(db().memory_dump_provider_->OnMemoryDump(args, &pmd));
1078 EXPECT_GE(pmd.allocator_dumps().size(), 1u);
1081 // Test that the functions to collect diagnostic data run to completion, without
1082 // worrying too much about what they generate (since that will change).
1083 TEST_F(SQLDatabaseTest, CollectDiagnosticInfo) {
1084 const std::string corruption_info = db().CollectCorruptionInfo();
1085 EXPECT_NE(std::string::npos, corruption_info.find("SQLITE_CORRUPT"));
1086 EXPECT_NE(std::string::npos, corruption_info.find("integrity_check"));
1088 // A statement to see in the results.
1089 const char* kSimpleSql = "SELECT 'mountain'";
1090 Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
1092 // Error includes the statement.
1093 const std::string readonly_info = db().CollectErrorInfo(SQLITE_READONLY, &s);
1094 EXPECT_NE(std::string::npos, readonly_info.find(kSimpleSql));
1096 // Some other error doesn't include the statment.
1097 // TODO(shess): This is weak.
1098 const std::string full_info = db().CollectErrorInfo(SQLITE_FULL, nullptr);
1099 EXPECT_EQ(std::string::npos, full_info.find(kSimpleSql));
1101 // A table to see in the SQLITE_ERROR results.
1102 EXPECT_TRUE(db().Execute("CREATE TABLE volcano (x)"));
1104 // Version info to see in the SQLITE_ERROR results.
1105 sql::MetaTable meta_table;
1106 ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
1108 const std::string error_info = db().CollectErrorInfo(SQLITE_ERROR, &s);
1109 EXPECT_NE(std::string::npos, error_info.find(kSimpleSql));
1110 EXPECT_NE(std::string::npos, error_info.find("volcano"));
1111 EXPECT_NE(std::string::npos, error_info.find("version: 4"));
1114 // Test that a fresh database has mmap enabled by default, if mmap'ed I/O is
1115 // enabled by SQLite.
1116 TEST_F(SQLDatabaseTest, MmapInitiallyEnabled) {
1118 sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
1119 ASSERT_TRUE(s.Step())
1120 << "All supported SQLite versions should have mmap support";
1122 // If mmap I/O is not on, attempt to turn it on. If that succeeds, then
1123 // Open() should have turned it on. If mmap support is disabled, 0 is
1124 // returned. If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
1125 // instance MojoVFS), -1 is returned.
1126 if (s.ColumnInt(0) <= 0) {
1127 ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576"));
1129 ASSERT_TRUE(s.Step());
1130 EXPECT_LE(s.ColumnInt(0), 0);
1134 // Test that explicit disable prevents mmap'ed I/O.
1136 sql::Database::Delete(db_path());
1137 db().set_mmap_disabled();
1138 ASSERT_TRUE(db().Open(db_path()));
1139 EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size"));
1142 // Test whether a fresh database gets mmap enabled when using alternate status
1144 TEST_F(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
1145 // Re-open fresh database with alt-status flag set.
1147 sql::Database::Delete(db_path());
1148 db().set_mmap_alt_status();
1149 ASSERT_TRUE(db().Open(db_path()));
1152 sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
1153 ASSERT_TRUE(s.Step())
1154 << "All supported SQLite versions should have mmap support";
1156 // If mmap I/O is not on, attempt to turn it on. If that succeeds, then
1157 // Open() should have turned it on. If mmap support is disabled, 0 is
1158 // returned. If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
1159 // instance MojoVFS), -1 is returned.
1160 if (s.ColumnInt(0) <= 0) {
1161 ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576"));
1163 ASSERT_TRUE(s.Step());
1164 EXPECT_LE(s.ColumnInt(0), 0);
1168 // Test that explicit disable overrides set_mmap_alt_status().
1170 sql::Database::Delete(db_path());
1171 db().set_mmap_disabled();
1172 ASSERT_TRUE(db().Open(db_path()));
1173 EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size"));
1176 TEST_F(SQLDatabaseTest, GetAppropriateMmapSize) {
1177 const size_t kMmapAlot = 25 * 1024 * 1024;
1178 int64_t mmap_status = MetaTable::kMmapFailure;
1180 // If there is no meta table (as for a fresh database), assume that everything
1181 // should be mapped, and the status of the meta table is not affected.
1182 ASSERT_TRUE(!db().DoesTableExist("meta"));
1183 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1184 ASSERT_TRUE(!db().DoesTableExist("meta"));
1186 // When the meta table is first created, it sets up to map everything.
1187 MetaTable().Init(&db(), 1, 1);
1188 ASSERT_TRUE(db().DoesTableExist("meta"));
1189 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1190 ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1191 ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1193 // Preload with partial progress of one page. Should map everything.
1194 ASSERT_TRUE(db().Execute("REPLACE INTO meta VALUES ('mmap_status', 1)"));
1195 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1196 ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1197 ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1199 // Failure status maps nothing.
1200 ASSERT_TRUE(db().Execute("REPLACE INTO meta VALUES ('mmap_status', -2)"));
1201 ASSERT_EQ(0UL, db().GetAppropriateMmapSize());
1203 // Re-initializing the meta table does not re-create the key if the table
1205 ASSERT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'mmap_status'"));
1206 MetaTable().Init(&db(), 1, 1);
1207 ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1208 ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1209 ASSERT_EQ(0, mmap_status);
1211 // With no key, map everything and create the key.
1212 // TODO(shess): This really should be "maps everything after validating it",
1213 // but that is more complicated to structure.
1214 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1215 ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1216 ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1219 TEST_F(SQLDatabaseTest, GetAppropriateMmapSizeAltStatus) {
1220 const size_t kMmapAlot = 25 * 1024 * 1024;
1222 // At this point, Database still expects a future [meta] table.
1223 ASSERT_FALSE(db().DoesTableExist("meta"));
1224 ASSERT_FALSE(db().DoesViewExist("MmapStatus"));
1225 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1226 ASSERT_FALSE(db().DoesTableExist("meta"));
1227 ASSERT_FALSE(db().DoesViewExist("MmapStatus"));
1229 // Using alt status, everything should be mapped, with state in the view.
1230 db().set_mmap_alt_status();
1231 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1232 ASSERT_FALSE(db().DoesTableExist("meta"));
1233 ASSERT_TRUE(db().DoesViewExist("MmapStatus"));
1234 EXPECT_EQ(base::NumberToString(MetaTable::kMmapSuccess),
1235 ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
1237 // Also maps everything when kMmapSuccess is already in the view.
1238 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1240 // Preload with partial progress of one page. Should map everything.
1241 ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus"));
1242 ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus (value) AS SELECT 1"));
1243 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1244 EXPECT_EQ(base::NumberToString(MetaTable::kMmapSuccess),
1245 ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
1247 // Failure status leads to nothing being mapped.
1248 ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus"));
1249 ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus (value) AS SELECT -2"));
1250 ASSERT_EQ(0UL, db().GetAppropriateMmapSize());
1251 EXPECT_EQ(base::NumberToString(MetaTable::kMmapFailure),
1252 ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
1255 TEST_F(SQLDatabaseTest, EnableWALMode) {
1256 db().want_wal_mode(true);
1257 #if defined(OS_FUCHSIA) // Exclusive mode needs to be enabled to enter WAL mode
1259 db().set_exclusive_locking();
1260 #endif // defined(OS_FUCHSIA)
1261 ASSERT_TRUE(Reopen());
1263 EXPECT_EQ(ExecuteWithResult(&db(), "PRAGMA journal_mode"), "wal");
1266 TEST_F(SQLDatabaseTest, DisableWALMode) {
1267 db().want_wal_mode(true);
1268 #if defined(OS_FUCHSIA) // Exclusive mode needs to be enabled to enter WAL mode
1270 db().set_exclusive_locking();
1271 #endif // defined(OS_FUCHSIA)
1272 ASSERT_TRUE(Reopen());
1273 ASSERT_EQ(ExecuteWithResult(&db(), "PRAGMA journal_mode"), "wal");
1275 // Add some data to ensure that disabling WAL mode correctly handles a
1276 // populated WAL file.
1278 db().Execute("CREATE TABLE foo (id INTEGER UNIQUE, value INTEGER)"));
1279 ASSERT_TRUE(db().Execute("INSERT INTO foo VALUES (1, 1)"));
1280 ASSERT_TRUE(db().Execute("INSERT INTO foo VALUES (2, 2)"));
1282 db().want_wal_mode(false);
1283 ASSERT_TRUE(Reopen());
1284 EXPECT_EQ(ExecuteWithResult(&db(), "PRAGMA journal_mode"), "truncate");
1285 // Check that data is preserved
1286 EXPECT_EQ(ExecuteWithResult(&db(), "SELECT SUM(value) FROM foo WHERE id < 3"),
1290 TEST_F(SQLDatabaseTest, CheckpointDatabase) {
1291 if (!db().UseWALMode()) {
1293 sql::Database::Delete(db_path());
1294 db().want_wal_mode(true);
1295 #if defined(OS_FUCHSIA) // Exclusive mode needs to be enabled to enter WAL mode
1297 db().set_exclusive_locking();
1298 #endif // defined(OS_FUCHSIA)
1299 ASSERT_TRUE(db().Open(db_path()));
1300 ASSERT_EQ(ExecuteWithResult(&db(), "PRAGMA journal_mode"), "wal");
1303 base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
1305 int64_t wal_size = 0;
1306 // WAL file initially empty.
1307 EXPECT_TRUE(GetPathExists(wal_path));
1308 base::GetFileSize(wal_path, &wal_size);
1309 EXPECT_EQ(wal_size, 0);
1312 db().Execute("CREATE TABLE foo (id INTEGER UNIQUE, value INTEGER)"));
1313 ASSERT_TRUE(db().Execute("INSERT INTO foo VALUES (1, 1)"));
1314 ASSERT_TRUE(db().Execute("INSERT INTO foo VALUES (2, 2)"));
1316 // Writes reach WAL file but not db file.
1317 base::GetFileSize(wal_path, &wal_size);
1318 EXPECT_GT(wal_size, 0);
1320 int64_t db_size = 0;
1321 base::GetFileSize(db_path(), &db_size);
1322 EXPECT_EQ(db_size, db().page_size());
1324 // Checkpoint database to immediately propagate writes to DB file.
1325 EXPECT_TRUE(db().CheckpointDatabase());
1327 base::GetFileSize(db_path(), &db_size);
1328 EXPECT_GT(db_size, db().page_size());
1329 EXPECT_EQ(ExecuteWithResult(&db(), "SELECT value FROM foo where id=1"), "1");
1330 EXPECT_EQ(ExecuteWithResult(&db(), "SELECT value FROM foo where id=2"), "2");
1333 // To prevent invalid SQL from accidentally shipping to production, prepared
1334 // statements which fail to compile with SQLITE_ERROR call DLOG(DCHECK). This
1335 // case cannot be suppressed with an error callback.
1336 TEST_F(SQLDatabaseTest, CompileError) {
1337 // DEATH tests not supported on Android, iOS, or Fuchsia.
1338 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
1339 if (DLOG_IS_ON(FATAL)) {
1340 db().set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
1341 ASSERT_DEATH({ db().GetUniqueStatement("SELECT x"); },
1342 "SQL compile error no such column: x");
1344 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)