Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / sql / database_unittest.cc
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 <stddef.h>
6 #include <stdint.h>
7
8 #include "base/bind.h"
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/test/simple_test_tick_clock.h"
19 #include "base/trace_event/process_memory_dump.h"
20 #include "build/build_config.h"
21 #include "sql/database.h"
22 #include "sql/database_memory_dump_provider.h"
23 #include "sql/meta_table.h"
24 #include "sql/sql_features.h"
25 #include "sql/statement.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"
32
33 namespace sql {
34
35 class DatabaseTestPeer {
36  public:
37   static bool AttachDatabase(Database* db,
38                              const base::FilePath& other_db_path,
39                              const char* attachment_point) {
40     return db->AttachDatabase(other_db_path, attachment_point,
41                               InternalApiToken());
42   }
43   static bool DetachDatabase(Database* db, const char* attachment_point) {
44     return db->DetachDatabase(attachment_point, InternalApiToken());
45   }
46 };
47
48 namespace test {
49
50 // Allow a test to add a SQLite function in a scoped context.
51 class ScopedScalarFunction {
52  public:
53   ScopedScalarFunction(
54       sql::Database& db,
55       const char* function_name,
56       int args,
57       base::RepeatingCallback<void(sqlite3_context*, int, sqlite3_value**)> cb)
58       : db_(db.db_), function_name_(function_name), cb_(std::move(cb)) {
59     sqlite3_create_function_v2(db_, function_name, args, SQLITE_UTF8, this,
60                                &Run, nullptr, nullptr, nullptr);
61   }
62   ~ScopedScalarFunction() {
63     sqlite3_create_function_v2(db_, function_name_, 0, SQLITE_UTF8, nullptr,
64                                nullptr, nullptr, nullptr, nullptr);
65   }
66
67  private:
68   static void Run(sqlite3_context* context, int argc, sqlite3_value** argv) {
69     ScopedScalarFunction* t =
70         static_cast<ScopedScalarFunction*>(sqlite3_user_data(context));
71     t->cb_.Run(context, argc, argv);
72   }
73
74   sqlite3* db_;
75   const char* function_name_;
76   base::RepeatingCallback<void(sqlite3_context*, int, sqlite3_value**)> cb_;
77
78   DISALLOW_COPY_AND_ASSIGN(ScopedScalarFunction);
79 };
80
81 // Allow a test to add a SQLite commit hook in a scoped context.
82 class ScopedCommitHook {
83  public:
84   ScopedCommitHook(sql::Database& db, base::RepeatingCallback<int()> cb)
85       : db_(db.db_), cb_(std::move(cb)) {
86     sqlite3_commit_hook(db_, &Run, this);
87   }
88   ~ScopedCommitHook() { sqlite3_commit_hook(db_, nullptr, nullptr); }
89
90  private:
91   static int Run(void* p) {
92     ScopedCommitHook* t = static_cast<ScopedCommitHook*>(p);
93     return t->cb_.Run();
94   }
95
96   sqlite3* db_;
97   base::RepeatingCallback<int(void)> cb_;
98
99   DISALLOW_COPY_AND_ASSIGN(ScopedCommitHook);
100 };
101
102 }  // namespace test
103
104 namespace {
105
106 using sql::test::ExecuteWithResult;
107
108 // Helper to return the count of items in sqlite_master.  Return -1 in
109 // case of error.
110 int SqliteMasterCount(sql::Database* db) {
111   const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
112   sql::Statement s(db->GetUniqueStatement(kMasterCount));
113   return s.Step() ? s.ColumnInt(0) : -1;
114 }
115
116 // Track the number of valid references which share the same pointer.
117 // This is used to allow testing an implicitly use-after-free case by
118 // explicitly having the ref count live longer than the object.
119 class RefCounter {
120  public:
121   RefCounter(size_t* counter) : counter_(counter) { (*counter_)++; }
122   RefCounter(const RefCounter& other) : counter_(other.counter_) {
123     (*counter_)++;
124   }
125   ~RefCounter() { (*counter_)--; }
126
127  private:
128   size_t* counter_;
129
130   DISALLOW_ASSIGN(RefCounter);
131 };
132
133 // Empty callback for implementation of ErrorCallbackSetHelper().
134 void IgnoreErrorCallback(int error, sql::Statement* stmt) {}
135
136 void ErrorCallbackSetHelper(sql::Database* db,
137                             size_t* counter,
138                             const RefCounter& r,
139                             int error,
140                             sql::Statement* stmt) {
141   // The ref count should not go to zero when changing the callback.
142   EXPECT_GT(*counter, 0u);
143   db->set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
144   EXPECT_GT(*counter, 0u);
145 }
146
147 void ErrorCallbackResetHelper(sql::Database* db,
148                               size_t* counter,
149                               const RefCounter& r,
150                               int error,
151                               sql::Statement* stmt) {
152   // The ref count should not go to zero when clearing the callback.
153   EXPECT_GT(*counter, 0u);
154   db->reset_error_callback();
155   EXPECT_GT(*counter, 0u);
156 }
157
158 // Handle errors by blowing away the database.
159 void RazeErrorCallback(sql::Database* db,
160                        int expected_error,
161                        int error,
162                        sql::Statement* stmt) {
163   // Nothing here needs extended errors at this time.
164   EXPECT_EQ(expected_error, expected_error & 0xff);
165   EXPECT_EQ(expected_error, error & 0xff);
166   db->RazeAndClose();
167 }
168
169 #if defined(OS_POSIX)
170 // Set a umask and restore the old mask on destruction.  Cribbed from
171 // shared_memory_unittest.cc.  Used by POSIX-only UserPermission test.
172 class ScopedUmaskSetter {
173  public:
174   explicit ScopedUmaskSetter(mode_t target_mask) {
175     old_umask_ = umask(target_mask);
176   }
177   ~ScopedUmaskSetter() { umask(old_umask_); }
178
179  private:
180   mode_t old_umask_;
181   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
182 };
183 #endif  // defined(OS_POSIX)
184
185 // SQLite function to adjust mock time by |argv[0]| milliseconds.
186 void sqlite_adjust_millis(base::SimpleTestTickClock* mock_clock,
187                           sqlite3_context* context,
188                           int argc,
189                           sqlite3_value** argv) {
190   CHECK_EQ(argc, 1);
191   int64_t milliseconds = sqlite3_value_int64(argv[0]);
192   mock_clock->Advance(base::TimeDelta::FromMilliseconds(milliseconds));
193   sqlite3_result_int64(context, milliseconds);
194 }
195
196 // Adjust mock time by |milliseconds| on commit.
197 int adjust_commit_hook(base::SimpleTestTickClock* mock_clock,
198                        int64_t milliseconds) {
199   mock_clock->Advance(base::TimeDelta::FromMilliseconds(milliseconds));
200   return SQLITE_OK;
201 }
202
203 const char kCommitTime[] = "Sqlite.CommitTime.Test";
204 const char kAutoCommitTime[] = "Sqlite.AutoCommitTime.Test";
205 const char kUpdateTime[] = "Sqlite.UpdateTime.Test";
206 const char kQueryTime[] = "Sqlite.QueryTime.Test";
207
208 }  // namespace
209
210 using SQLDatabaseTest = sql::SQLTestBase;
211
212 TEST_F(SQLDatabaseTest, Execute) {
213   // Valid statement should return true.
214   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
215   EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
216
217   // Invalid statement should fail.
218   ASSERT_EQ(SQLITE_ERROR,
219             db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
220   EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
221 }
222
223 TEST_F(SQLDatabaseTest, ExecuteWithErrorCode) {
224   ASSERT_EQ(SQLITE_OK,
225             db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
226   ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
227   ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(
228                               "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
229 }
230
231 TEST_F(SQLDatabaseTest, CachedStatement) {
232   sql::StatementID id1 = SQL_FROM_HERE;
233   sql::StatementID id2 = SQL_FROM_HERE;
234   static const char kId1Sql[] = "SELECT a FROM foo";
235   static const char kId2Sql[] = "SELECT b FROM foo";
236
237   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
238   ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
239
240   sqlite3_stmt* raw_id1_statement;
241   sqlite3_stmt* raw_id2_statement;
242   {
243     scoped_refptr<sql::Database::StatementRef> ref_from_id1 =
244         db().GetCachedStatement(id1, kId1Sql);
245     raw_id1_statement = ref_from_id1->stmt();
246
247     sql::Statement from_id1(std::move(ref_from_id1));
248     ASSERT_TRUE(from_id1.is_valid());
249     ASSERT_TRUE(from_id1.Step());
250     EXPECT_EQ(12, from_id1.ColumnInt(0));
251
252     scoped_refptr<sql::Database::StatementRef> ref_from_id2 =
253         db().GetCachedStatement(id2, kId2Sql);
254     raw_id2_statement = ref_from_id2->stmt();
255     EXPECT_NE(raw_id1_statement, raw_id2_statement);
256
257     sql::Statement from_id2(std::move(ref_from_id2));
258     ASSERT_TRUE(from_id2.is_valid());
259     ASSERT_TRUE(from_id2.Step());
260     EXPECT_EQ(13, from_id2.ColumnInt(0));
261   }
262
263   {
264     scoped_refptr<sql::Database::StatementRef> ref_from_id1 =
265         db().GetCachedStatement(id1, kId1Sql);
266     EXPECT_EQ(raw_id1_statement, ref_from_id1->stmt())
267         << "statement was not cached";
268
269     sql::Statement from_id1(std::move(ref_from_id1));
270     ASSERT_TRUE(from_id1.is_valid());
271     ASSERT_TRUE(from_id1.Step()) << "cached statement was not reset";
272     EXPECT_EQ(12, from_id1.ColumnInt(0));
273
274     scoped_refptr<sql::Database::StatementRef> ref_from_id2 =
275         db().GetCachedStatement(id2, kId2Sql);
276     EXPECT_EQ(raw_id2_statement, ref_from_id2->stmt())
277         << "statement was not cached";
278
279     sql::Statement from_id2(std::move(ref_from_id2));
280     ASSERT_TRUE(from_id2.is_valid());
281     ASSERT_TRUE(from_id2.Step()) << "cached statement was not reset";
282     EXPECT_EQ(13, from_id2.ColumnInt(0));
283   }
284
285   EXPECT_DCHECK_DEATH(db().GetCachedStatement(id1, kId2Sql))
286       << "Using a different SQL with the same statement ID should DCHECK";
287   EXPECT_DCHECK_DEATH(db().GetCachedStatement(id2, kId1Sql))
288       << "Using a different SQL with the same statement ID should DCHECK";
289 }
290
291 TEST_F(SQLDatabaseTest, IsSQLValidTest) {
292   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
293   ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
294   ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
295 }
296
297 TEST_F(SQLDatabaseTest, DoesTableExist) {
298   EXPECT_FALSE(db().DoesTableExist("foo"));
299   EXPECT_FALSE(db().DoesTableExist("foo_index"));
300
301   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
302   ASSERT_TRUE(db().Execute("CREATE INDEX foo_index ON foo (a)"));
303   EXPECT_TRUE(db().DoesTableExist("foo"));
304   EXPECT_FALSE(db().DoesTableExist("foo_index"));
305 }
306
307 TEST_F(SQLDatabaseTest, DoesIndexExist) {
308   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
309   EXPECT_FALSE(db().DoesIndexExist("foo"));
310   EXPECT_FALSE(db().DoesIndexExist("foo_ubdex"));
311
312   ASSERT_TRUE(db().Execute("CREATE INDEX foo_index ON foo (a)"));
313   EXPECT_TRUE(db().DoesIndexExist("foo_index"));
314   EXPECT_FALSE(db().DoesIndexExist("foo"));
315 }
316
317 TEST_F(SQLDatabaseTest, DoesViewExist) {
318   EXPECT_FALSE(db().DoesViewExist("voo"));
319   ASSERT_TRUE(db().Execute("CREATE VIEW voo (a) AS SELECT 1"));
320   EXPECT_FALSE(db().DoesIndexExist("voo"));
321   EXPECT_FALSE(db().DoesTableExist("voo"));
322   EXPECT_TRUE(db().DoesViewExist("voo"));
323 }
324
325 TEST_F(SQLDatabaseTest, DoesColumnExist) {
326   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
327
328   EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
329   EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
330
331   ASSERT_FALSE(db().DoesTableExist("bar"));
332   EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
333
334   // Names are not case sensitive.
335   EXPECT_TRUE(db().DoesTableExist("FOO"));
336   EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
337 }
338
339 TEST_F(SQLDatabaseTest, GetLastInsertRowId) {
340   ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
341
342   ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
343
344   // Last insert row ID should be valid.
345   int64_t row = db().GetLastInsertRowId();
346   EXPECT_LT(0, row);
347
348   // It should be the primary key of the row we just inserted.
349   sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
350   s.BindInt64(0, row);
351   ASSERT_TRUE(s.Step());
352   EXPECT_EQ(12, s.ColumnInt(0));
353 }
354
355 TEST_F(SQLDatabaseTest, Rollback) {
356   ASSERT_TRUE(db().BeginTransaction());
357   ASSERT_TRUE(db().BeginTransaction());
358   EXPECT_EQ(2, db().transaction_nesting());
359   db().RollbackTransaction();
360   EXPECT_FALSE(db().CommitTransaction());
361   EXPECT_TRUE(db().BeginTransaction());
362 }
363
364 // Test the scoped error expecter by attempting to insert a duplicate
365 // value into an index.
366 TEST_F(SQLDatabaseTest, ScopedErrorExpecter) {
367   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
368   ASSERT_TRUE(db().Execute(kCreateSql));
369   ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
370
371   {
372     sql::test::ScopedErrorExpecter expecter;
373     expecter.ExpectError(SQLITE_CONSTRAINT);
374     ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
375     ASSERT_TRUE(expecter.SawExpectedErrors());
376   }
377 }
378
379 // Test that clients of GetUntrackedStatement() can test corruption-handling
380 // with ScopedErrorExpecter.
381 TEST_F(SQLDatabaseTest, ScopedIgnoreUntracked) {
382   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
383   ASSERT_TRUE(db().Execute(kCreateSql));
384   ASSERT_FALSE(db().DoesTableExist("bar"));
385   ASSERT_TRUE(db().DoesTableExist("foo"));
386   ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
387   db().Close();
388
389   // Corrupt the database so that nothing works, including PRAGMAs.
390   ASSERT_TRUE(CorruptSizeInHeaderOfDB());
391
392   {
393     sql::test::ScopedErrorExpecter expecter;
394     expecter.ExpectError(SQLITE_CORRUPT);
395     ASSERT_TRUE(db().Open(db_path()));
396     ASSERT_FALSE(db().DoesTableExist("bar"));
397     ASSERT_FALSE(db().DoesTableExist("foo"));
398     ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
399     ASSERT_TRUE(expecter.SawExpectedErrors());
400   }
401 }
402
403 TEST_F(SQLDatabaseTest, ErrorCallback) {
404   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
405   ASSERT_TRUE(db().Execute(kCreateSql));
406   ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
407
408   int error = SQLITE_OK;
409   {
410     sql::ScopedErrorCallback sec(
411         &db(), base::BindRepeating(&sql::CaptureErrorCallback, &error));
412     EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
413
414     // Later versions of SQLite throw SQLITE_CONSTRAINT_UNIQUE.  The specific
415     // sub-error isn't really important.
416     EXPECT_EQ(SQLITE_CONSTRAINT, (error & 0xff));
417   }
418
419   // Callback is no longer in force due to reset.
420   {
421     error = SQLITE_OK;
422     sql::test::ScopedErrorExpecter expecter;
423     expecter.ExpectError(SQLITE_CONSTRAINT);
424     ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
425     ASSERT_TRUE(expecter.SawExpectedErrors());
426     EXPECT_EQ(SQLITE_OK, error);
427   }
428
429   // base::BindRepeating() can curry arguments to be passed by const reference
430   // to the callback function.  If the callback function calls
431   // re/set_error_callback(), the storage for those arguments can be
432   // deleted while the callback function is still executing.
433   //
434   // RefCounter() counts how many objects are live using an external
435   // count.  The same counter is passed to the callback, so that it
436   // can check directly even if the RefCounter object is no longer
437   // live.
438   {
439     size_t count = 0;
440     sql::ScopedErrorCallback sec(
441         &db(), base::BindRepeating(&ErrorCallbackSetHelper, &db(), &count,
442                                    RefCounter(&count)));
443
444     EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
445   }
446
447   // Same test, but reset_error_callback() case.
448   {
449     size_t count = 0;
450     sql::ScopedErrorCallback sec(
451         &db(), base::BindRepeating(&ErrorCallbackResetHelper, &db(), &count,
452                                    RefCounter(&count)));
453
454     EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
455   }
456 }
457
458 // Test that sql::Database::Raze() results in a database without the
459 // tables from the original database.
460 TEST_F(SQLDatabaseTest, Raze) {
461   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
462   ASSERT_TRUE(db().Execute(kCreateSql));
463   ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
464
465   int pragma_auto_vacuum = 0;
466   {
467     sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
468     ASSERT_TRUE(s.Step());
469     pragma_auto_vacuum = s.ColumnInt(0);
470     ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
471   }
472
473   // If auto_vacuum is set, there's an extra page to maintain a freelist.
474   const int kExpectedPageCount = 2 + pragma_auto_vacuum;
475
476   {
477     sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
478     ASSERT_TRUE(s.Step());
479     EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
480   }
481
482   {
483     sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
484     ASSERT_TRUE(s.Step());
485     EXPECT_EQ("table", s.ColumnString(0));
486     EXPECT_EQ("foo", s.ColumnString(1));
487     EXPECT_EQ("foo", s.ColumnString(2));
488     // Table "foo" is stored in the last page of the file.
489     EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3));
490     EXPECT_EQ(kCreateSql, s.ColumnString(4));
491   }
492
493   ASSERT_TRUE(db().Raze());
494
495   {
496     sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
497     ASSERT_TRUE(s.Step());
498     EXPECT_EQ(1, s.ColumnInt(0));
499   }
500
501   ASSERT_EQ(0, SqliteMasterCount(&db()));
502
503   {
504     sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
505     ASSERT_TRUE(s.Step());
506     // The new database has the same auto_vacuum as a fresh database.
507     EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
508   }
509 }
510
511 // Helper for SQLDatabaseTest.RazePageSize.  Creates a fresh db based on
512 // db_prefix, with the given initial page size, and verifies it against the
513 // expected size.  Then changes to the final page size and razes, verifying that
514 // the fresh database ends up with the expected final page size.
515 void TestPageSize(const base::FilePath& db_prefix,
516                   int initial_page_size,
517                   const std::string& expected_initial_page_size,
518                   int final_page_size,
519                   const std::string& expected_final_page_size) {
520   static const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
521   static const char kInsertSql1[] = "INSERT INTO x VALUES ('This is a test')";
522   static const char kInsertSql2[] = "INSERT INTO x VALUES ('That was a test')";
523
524   const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
525       base::IntToString(initial_page_size));
526   sql::Database::Delete(db_path);
527   sql::Database db;
528   db.set_page_size(initial_page_size);
529   ASSERT_TRUE(db.Open(db_path));
530   ASSERT_TRUE(db.Execute(kCreateSql));
531   ASSERT_TRUE(db.Execute(kInsertSql1));
532   ASSERT_TRUE(db.Execute(kInsertSql2));
533   ASSERT_EQ(expected_initial_page_size,
534             ExecuteWithResult(&db, "PRAGMA page_size"));
535
536   // Raze will use the page size set in the connection object, which may not
537   // match the file's page size.
538   db.set_page_size(final_page_size);
539   ASSERT_TRUE(db.Raze());
540
541   // SQLite 3.10.2 (at least) has a quirk with the sqlite3_backup() API (used by
542   // Raze()) which causes the destination database to remember the previous
543   // page_size, even if the overwriting database changed the page_size.  Access
544   // the actual database to cause the cached value to be updated.
545   EXPECT_EQ("0", ExecuteWithResult(&db, "SELECT COUNT(*) FROM sqlite_master"));
546
547   EXPECT_EQ(expected_final_page_size,
548             ExecuteWithResult(&db, "PRAGMA page_size"));
549   EXPECT_EQ("1", ExecuteWithResult(&db, "PRAGMA page_count"));
550 }
551
552 // Verify that sql::Recovery maintains the page size, and the virtual table
553 // works with page sizes other than SQLite's default.  Also verify the case
554 // where the default page size has changed.
555 TEST_F(SQLDatabaseTest, RazePageSize) {
556   const std::string default_page_size =
557       ExecuteWithResult(&db(), "PRAGMA page_size");
558
559   // Sync uses 32k pages.
560   EXPECT_NO_FATAL_FAILURE(
561       TestPageSize(db_path(), 32768, "32768", 32768, "32768"));
562
563   // Many clients use 4k pages.  This is the SQLite default after 3.12.0.
564   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 4096, "4096", 4096, "4096"));
565
566   // 1k is the default page size before 3.12.0.
567   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 1024, "1024", 1024, "1024"));
568
569   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 2048, "2048", 4096, "4096"));
570
571   // Databases with no page size specified should result in the default
572   // page size.  2k has never been the default page size.
573   ASSERT_NE("2048", default_page_size);
574   EXPECT_NO_FATAL_FAILURE(TestPageSize(
575       db_path(), 2048, "2048", Database::kDefaultPageSize, default_page_size));
576 }
577
578 // Test that Raze() results are seen in other connections.
579 TEST_F(SQLDatabaseTest, RazeMultiple) {
580   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
581   ASSERT_TRUE(db().Execute(kCreateSql));
582
583   sql::Database other_db;
584   ASSERT_TRUE(other_db.Open(db_path()));
585
586   // Check that the second connection sees the table.
587   ASSERT_EQ(1, SqliteMasterCount(&other_db));
588
589   ASSERT_TRUE(db().Raze());
590
591   // The second connection sees the updated database.
592   ASSERT_EQ(0, SqliteMasterCount(&other_db));
593 }
594
595 TEST_F(SQLDatabaseTest, RazeLocked) {
596   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
597   ASSERT_TRUE(db().Execute(kCreateSql));
598
599   // Open a transaction and write some data in a second connection.
600   // This will acquire a PENDING or EXCLUSIVE transaction, which will
601   // cause the raze to fail.
602   sql::Database other_db;
603   ASSERT_TRUE(other_db.Open(db_path()));
604   ASSERT_TRUE(other_db.BeginTransaction());
605   const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
606   ASSERT_TRUE(other_db.Execute(kInsertSql));
607
608   ASSERT_FALSE(db().Raze());
609
610   // Works after COMMIT.
611   ASSERT_TRUE(other_db.CommitTransaction());
612   ASSERT_TRUE(db().Raze());
613
614   // Re-create the database.
615   ASSERT_TRUE(db().Execute(kCreateSql));
616   ASSERT_TRUE(db().Execute(kInsertSql));
617
618   // An unfinished read transaction in the other connection also
619   // blocks raze.
620   const char* kQuery = "SELECT COUNT(*) FROM foo";
621   sql::Statement s(other_db.GetUniqueStatement(kQuery));
622   ASSERT_TRUE(s.Step());
623   ASSERT_FALSE(db().Raze());
624
625   // Complete the statement unlocks the database.
626   ASSERT_FALSE(s.Step());
627   ASSERT_TRUE(db().Raze());
628 }
629
630 // Verify that Raze() can handle an empty file.  SQLite should treat
631 // this as an empty database.
632 TEST_F(SQLDatabaseTest, RazeEmptyDB) {
633   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
634   ASSERT_TRUE(db().Execute(kCreateSql));
635   db().Close();
636
637   TruncateDatabase();
638
639   ASSERT_TRUE(db().Open(db_path()));
640   ASSERT_TRUE(db().Raze());
641   EXPECT_EQ(0, SqliteMasterCount(&db()));
642 }
643
644 // Verify that Raze() can handle a file of junk.
645 TEST_F(SQLDatabaseTest, RazeNOTADB) {
646   db().Close();
647   sql::Database::Delete(db_path());
648   ASSERT_FALSE(GetPathExists(db_path()));
649
650   WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE_AND_TRUNCATE);
651   ASSERT_TRUE(GetPathExists(db_path()));
652
653   // SQLite will successfully open the handle, but fail when running PRAGMA
654   // statements that access the database.
655   {
656     sql::test::ScopedErrorExpecter expecter;
657     expecter.ExpectError(SQLITE_NOTADB);
658
659     EXPECT_TRUE(db().Open(db_path()));
660     ASSERT_TRUE(expecter.SawExpectedErrors());
661   }
662   EXPECT_TRUE(db().Raze());
663   db().Close();
664
665   // Now empty, the open should open an empty database.
666   EXPECT_TRUE(db().Open(db_path()));
667   EXPECT_EQ(0, SqliteMasterCount(&db()));
668 }
669
670 // Verify that Raze() can handle a database overwritten with garbage.
671 TEST_F(SQLDatabaseTest, RazeNOTADB2) {
672   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
673   ASSERT_TRUE(db().Execute(kCreateSql));
674   ASSERT_EQ(1, SqliteMasterCount(&db()));
675   db().Close();
676
677   WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE);
678
679   // SQLite will successfully open the handle, but will fail with
680   // SQLITE_NOTADB on pragma statemenets which attempt to read the
681   // corrupted header.
682   {
683     sql::test::ScopedErrorExpecter expecter;
684     expecter.ExpectError(SQLITE_NOTADB);
685     EXPECT_TRUE(db().Open(db_path()));
686     ASSERT_TRUE(expecter.SawExpectedErrors());
687   }
688   EXPECT_TRUE(db().Raze());
689   db().Close();
690
691   // Now empty, the open should succeed with an empty database.
692   EXPECT_TRUE(db().Open(db_path()));
693   EXPECT_EQ(0, SqliteMasterCount(&db()));
694 }
695
696 // Test that a callback from Open() can raze the database.  This is
697 // essential for cases where the Open() can fail entirely, so the
698 // Raze() cannot happen later.  Additionally test that when the
699 // callback does this during Open(), the open is retried and succeeds.
700 TEST_F(SQLDatabaseTest, RazeCallbackReopen) {
701   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
702   ASSERT_TRUE(db().Execute(kCreateSql));
703   ASSERT_EQ(1, SqliteMasterCount(&db()));
704   db().Close();
705
706   // Corrupt the database so that nothing works, including PRAGMAs.
707   ASSERT_TRUE(CorruptSizeInHeaderOfDB());
708
709   // Open() will succeed, even though the PRAGMA calls within will
710   // fail with SQLITE_CORRUPT, as will this PRAGMA.
711   {
712     sql::test::ScopedErrorExpecter expecter;
713     expecter.ExpectError(SQLITE_CORRUPT);
714     ASSERT_TRUE(db().Open(db_path()));
715     ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
716     db().Close();
717     ASSERT_TRUE(expecter.SawExpectedErrors());
718   }
719
720   db().set_error_callback(
721       base::BindRepeating(&RazeErrorCallback, &db(), SQLITE_CORRUPT));
722
723   // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
724   // callback will call RazeAndClose().  Open() will then fail and be
725   // retried.  The second Open() on the empty database will succeed
726   // cleanly.
727   ASSERT_TRUE(db().Open(db_path()));
728   ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
729   EXPECT_EQ(0, SqliteMasterCount(&db()));
730 }
731
732 // Basic test of RazeAndClose() operation.
733 TEST_F(SQLDatabaseTest, RazeAndClose) {
734   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
735   const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
736
737   // Test that RazeAndClose() closes the database, and that the
738   // database is empty when re-opened.
739   ASSERT_TRUE(db().Execute(kCreateSql));
740   ASSERT_TRUE(db().Execute(kPopulateSql));
741   ASSERT_TRUE(db().RazeAndClose());
742   ASSERT_FALSE(db().is_open());
743   db().Close();
744   ASSERT_TRUE(db().Open(db_path()));
745   ASSERT_EQ(0, SqliteMasterCount(&db()));
746
747   // Test that RazeAndClose() can break transactions.
748   ASSERT_TRUE(db().Execute(kCreateSql));
749   ASSERT_TRUE(db().Execute(kPopulateSql));
750   ASSERT_TRUE(db().BeginTransaction());
751   ASSERT_TRUE(db().RazeAndClose());
752   ASSERT_FALSE(db().is_open());
753   ASSERT_FALSE(db().CommitTransaction());
754   db().Close();
755   ASSERT_TRUE(db().Open(db_path()));
756   ASSERT_EQ(0, SqliteMasterCount(&db()));
757 }
758
759 // Test that various operations fail without crashing after
760 // RazeAndClose().
761 TEST_F(SQLDatabaseTest, RazeAndCloseDiagnostics) {
762   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
763   const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
764   const char* kSimpleSql = "SELECT 1";
765
766   ASSERT_TRUE(db().Execute(kCreateSql));
767   ASSERT_TRUE(db().Execute(kPopulateSql));
768
769   // Test baseline expectations.
770   db().Preload();
771   ASSERT_TRUE(db().DoesTableExist("foo"));
772   ASSERT_TRUE(db().IsSQLValid(kSimpleSql));
773   ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql));
774   ASSERT_TRUE(db().Execute(kSimpleSql));
775   ASSERT_TRUE(db().is_open());
776   {
777     sql::Statement s(db().GetUniqueStatement(kSimpleSql));
778     ASSERT_TRUE(s.Step());
779   }
780   {
781     sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
782     ASSERT_TRUE(s.Step());
783   }
784   ASSERT_TRUE(db().BeginTransaction());
785   ASSERT_TRUE(db().CommitTransaction());
786   ASSERT_TRUE(db().BeginTransaction());
787   db().RollbackTransaction();
788
789   ASSERT_TRUE(db().RazeAndClose());
790
791   // At this point, they should all fail, but not crash.
792   db().Preload();
793   ASSERT_FALSE(db().DoesTableExist("foo"));
794   ASSERT_FALSE(db().IsSQLValid(kSimpleSql));
795   ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql));
796   ASSERT_FALSE(db().Execute(kSimpleSql));
797   ASSERT_FALSE(db().is_open());
798   {
799     sql::Statement s(db().GetUniqueStatement(kSimpleSql));
800     ASSERT_FALSE(s.Step());
801   }
802   {
803     sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
804     ASSERT_FALSE(s.Step());
805   }
806   ASSERT_FALSE(db().BeginTransaction());
807   ASSERT_FALSE(db().CommitTransaction());
808   ASSERT_FALSE(db().BeginTransaction());
809   db().RollbackTransaction();
810
811   // Close normally to reset the poisoned flag.
812   db().Close();
813
814 // DEATH tests not supported on Android, iOS, or Fuchsia.
815 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
816   // Once the real Close() has been called, various calls enforce API
817   // usage by becoming fatal in debug mode.  Since DEATH tests are
818   // expensive, just test one of them.
819   if (DLOG_IS_ON(FATAL)) {
820     ASSERT_DEATH({ db().IsSQLValid(kSimpleSql); },
821                  "Illegal use of Database without a db");
822   }
823 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
824 }
825
826 // TODO(shess): Spin up a background thread to hold other_db, to more
827 // closely match real life.  That would also allow testing
828 // RazeWithTimeout().
829
830 // On Windows, truncate silently fails against a memory-mapped file.  One goal
831 // of Raze() is to truncate the file to remove blocks which generate I/O errors.
832 // Test that Raze() turns off memory mapping so that the file is truncated.
833 // [This would not cover the case of multiple connections where one of the other
834 // connections is memory-mapped.  That is infrequent in Chromium.]
835 TEST_F(SQLDatabaseTest, RazeTruncate) {
836   // The empty database has 0 or 1 pages.  Raze() should leave it with exactly 1
837   // page.  Not checking directly because auto_vacuum on Android adds a freelist
838   // page.
839   ASSERT_TRUE(db().Raze());
840   int64_t expected_size;
841   ASSERT_TRUE(base::GetFileSize(db_path(), &expected_size));
842   ASSERT_GT(expected_size, 0);
843
844   // Cause the database to take a few pages.
845   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
846   ASSERT_TRUE(db().Execute(kCreateSql));
847   for (size_t i = 0; i < 24; ++i) {
848     ASSERT_TRUE(
849         db().Execute("INSERT INTO foo (value) VALUES (randomblob(1024))"));
850   }
851   int64_t db_size;
852   ASSERT_TRUE(base::GetFileSize(db_path(), &db_size));
853   ASSERT_GT(db_size, expected_size);
854
855   // Make a query covering most of the database file to make sure that the
856   // blocks are actually mapped into memory.  Empirically, the truncate problem
857   // doesn't seem to happen if no blocks are mapped.
858   EXPECT_EQ("24576",
859             ExecuteWithResult(&db(), "SELECT SUM(LENGTH(value)) FROM foo"));
860
861   ASSERT_TRUE(db().Raze());
862   ASSERT_TRUE(base::GetFileSize(db_path(), &db_size));
863   ASSERT_EQ(expected_size, db_size);
864 }
865
866 #if defined(OS_ANDROID)
867 TEST_F(SQLDatabaseTest, SetTempDirForSQL) {
868   sql::MetaTable meta_table;
869   // Below call needs a temporary directory in sqlite3
870   // On Android, it can pass only when the temporary directory is set.
871   // Otherwise, sqlite3 doesn't find the correct directory to store
872   // temporary files and will report the error 'unable to open
873   // database file'.
874   ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
875 }
876 #endif  // defined(OS_ANDROID)
877
878 TEST_F(SQLDatabaseTest, DeleteNonWal) {
879   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
880   db().Close();
881
882   // Should have both a main database file and a journal file because
883   // of journal_mode TRUNCATE.
884   base::FilePath journal_path = sql::Database::JournalPath(db_path());
885   ASSERT_TRUE(GetPathExists(db_path()));
886   ASSERT_TRUE(GetPathExists(journal_path));
887
888   sql::Database::Delete(db_path());
889   EXPECT_FALSE(GetPathExists(db_path()));
890   EXPECT_FALSE(GetPathExists(journal_path));
891 }
892
893 #if defined(OS_POSIX)  // This test operates on POSIX file permissions.
894 TEST_F(SQLDatabaseTest, PosixFilePermissions) {
895   db().Close();
896   sql::Database::Delete(db_path());
897   ASSERT_FALSE(GetPathExists(db_path()));
898
899   // If the bots all had a restrictive umask setting such that databases are
900   // always created with only the owner able to read them, then the code could
901   // break without breaking the tests. Temporarily provide a more permissive
902   // umask.
903   ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
904
905   ASSERT_TRUE(db().Open(db_path()));
906
907   // Cause the journal file to be created. If the default journal_mode is
908   // changed back to DELETE, this test will need to be updated.
909   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
910
911   int mode;
912   ASSERT_TRUE(GetPathExists(db_path()));
913   EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
914   ASSERT_EQ(mode, 0600);
915
916   {
917     base::FilePath journal_path = sql::Database::JournalPath(db_path());
918     DLOG(ERROR) << "journal_path: " << journal_path;
919     ASSERT_TRUE(GetPathExists(journal_path));
920     EXPECT_TRUE(base::GetPosixFilePermissions(journal_path, &mode));
921     ASSERT_EQ(mode, 0600);
922   }
923
924   // Reopen the database and turn on WAL mode.
925   db().Close();
926   sql::Database::Delete(db_path());
927   ASSERT_FALSE(GetPathExists(db_path()));
928   ASSERT_TRUE(db().Open(db_path()));
929   ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
930   ASSERT_EQ("wal", ExecuteWithResult(&db(), "PRAGMA journal_mode"));
931
932   // The WAL file is created lazily on first change.
933   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
934
935   {
936     base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
937     ASSERT_TRUE(GetPathExists(wal_path));
938     EXPECT_TRUE(base::GetPosixFilePermissions(wal_path, &mode));
939     ASSERT_EQ(mode, 0600);
940
941     base::FilePath shm_path = sql::Database::SharedMemoryFilePath(db_path());
942     ASSERT_TRUE(GetPathExists(shm_path));
943     EXPECT_TRUE(base::GetPosixFilePermissions(shm_path, &mode));
944     ASSERT_EQ(mode, 0600);
945   }
946 }
947 #endif  // defined(OS_POSIX)
948
949 // Test that errors start happening once Poison() is called.
950 TEST_F(SQLDatabaseTest, Poison) {
951   EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
952
953   // Before the Poison() call, things generally work.
954   EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
955   EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
956   {
957     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
958     ASSERT_TRUE(s.is_valid());
959     ASSERT_TRUE(s.Step());
960   }
961
962   // Get a statement which is valid before and will exist across Poison().
963   sql::Statement valid_statement(
964       db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
965   ASSERT_TRUE(valid_statement.is_valid());
966   ASSERT_TRUE(valid_statement.Step());
967   valid_statement.Reset(true);
968
969   db().Poison();
970
971   // After the Poison() call, things fail.
972   EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
973   EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
974   {
975     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
976     ASSERT_FALSE(s.is_valid());
977     ASSERT_FALSE(s.Step());
978   }
979
980   // The existing statement has become invalid.
981   ASSERT_FALSE(valid_statement.is_valid());
982   ASSERT_FALSE(valid_statement.Step());
983
984   // Test that poisoning the database during a transaction works (with errors).
985   // RazeErrorCallback() poisons the database, the extra COMMIT causes
986   // CommitTransaction() to throw an error while commiting.
987   db().set_error_callback(
988       base::BindRepeating(&RazeErrorCallback, &db(), SQLITE_ERROR));
989   db().Close();
990   ASSERT_TRUE(db().Open(db_path()));
991   EXPECT_TRUE(db().BeginTransaction());
992   EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
993   EXPECT_TRUE(db().Execute("COMMIT"));
994   EXPECT_FALSE(db().CommitTransaction());
995 }
996
997 TEST_F(SQLDatabaseTest, AttachDatabase) {
998   EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
999
1000   // Create a database to attach to.
1001   base::FilePath attach_path =
1002       db_path().DirName().AppendASCII("SQLDatabaseAttach.db");
1003   static const char kAttachmentPoint[] = "other";
1004   {
1005     sql::Database other_db;
1006     ASSERT_TRUE(other_db.Open(attach_path));
1007     EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
1008     EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
1009   }
1010
1011   // Cannot see the attached database, yet.
1012   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
1013
1014   EXPECT_TRUE(
1015       DatabaseTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
1016   EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
1017
1018   // Queries can touch both databases after the ATTACH.
1019   EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
1020   {
1021     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
1022     ASSERT_TRUE(s.Step());
1023     EXPECT_EQ(1, s.ColumnInt(0));
1024   }
1025
1026   EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
1027   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
1028 }
1029
1030 TEST_F(SQLDatabaseTest, AttachDatabaseWithOpenTransaction) {
1031   EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
1032
1033   // Create a database to attach to.
1034   base::FilePath attach_path =
1035       db_path().DirName().AppendASCII("SQLDatabaseAttach.db");
1036   static const char kAttachmentPoint[] = "other";
1037   {
1038     sql::Database other_db;
1039     ASSERT_TRUE(other_db.Open(attach_path));
1040     EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
1041     EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
1042   }
1043
1044   // Cannot see the attached database, yet.
1045   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
1046
1047   // Attach succeeds in a transaction.
1048   EXPECT_TRUE(db().BeginTransaction());
1049   EXPECT_TRUE(
1050       DatabaseTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
1051   EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
1052
1053   // Queries can touch both databases after the ATTACH.
1054   EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
1055   {
1056     sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
1057     ASSERT_TRUE(s.Step());
1058     EXPECT_EQ(1, s.ColumnInt(0));
1059   }
1060
1061   // Detaching the same database fails, database is locked in the transaction.
1062   {
1063     sql::test::ScopedErrorExpecter expecter;
1064     expecter.ExpectError(SQLITE_ERROR);
1065     EXPECT_FALSE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
1066     EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
1067     ASSERT_TRUE(expecter.SawExpectedErrors());
1068   }
1069
1070   // Detach succeeds when the transaction is closed.
1071   db().RollbackTransaction();
1072   EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
1073   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
1074 }
1075
1076 TEST_F(SQLDatabaseTest, Basic_QuickIntegrityCheck) {
1077   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1078   ASSERT_TRUE(db().Execute(kCreateSql));
1079   EXPECT_TRUE(db().QuickIntegrityCheck());
1080   db().Close();
1081
1082   ASSERT_TRUE(CorruptSizeInHeaderOfDB());
1083
1084   {
1085     sql::test::ScopedErrorExpecter expecter;
1086     expecter.ExpectError(SQLITE_CORRUPT);
1087     ASSERT_TRUE(db().Open(db_path()));
1088     EXPECT_FALSE(db().QuickIntegrityCheck());
1089     ASSERT_TRUE(expecter.SawExpectedErrors());
1090   }
1091 }
1092
1093 TEST_F(SQLDatabaseTest, Basic_FullIntegrityCheck) {
1094   const std::string kOk("ok");
1095   std::vector<std::string> messages;
1096
1097   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1098   ASSERT_TRUE(db().Execute(kCreateSql));
1099   EXPECT_TRUE(db().FullIntegrityCheck(&messages));
1100   EXPECT_EQ(1u, messages.size());
1101   EXPECT_EQ(kOk, messages[0]);
1102   db().Close();
1103
1104   ASSERT_TRUE(CorruptSizeInHeaderOfDB());
1105
1106   {
1107     sql::test::ScopedErrorExpecter expecter;
1108     expecter.ExpectError(SQLITE_CORRUPT);
1109     ASSERT_TRUE(db().Open(db_path()));
1110     EXPECT_TRUE(db().FullIntegrityCheck(&messages));
1111     EXPECT_LT(1u, messages.size());
1112     EXPECT_NE(kOk, messages[0]);
1113     ASSERT_TRUE(expecter.SawExpectedErrors());
1114   }
1115
1116   // TODO(shess): CorruptTableOrIndex could be used to produce a
1117   // file that would pass the quick check and fail the full check.
1118 }
1119
1120 // Test Sqlite.Stats histogram for execute-oriented calls.
1121 TEST_F(SQLDatabaseTest, EventsExecute) {
1122   // Re-open with histogram tag.
1123   db().Close();
1124   db().set_histogram_tag("Test");
1125   ASSERT_TRUE(db().Open(db_path()));
1126
1127   // Open() uses Execute() extensively, don't track those calls.
1128   base::HistogramTester tester;
1129
1130   static const char kHistogramName[] = "Sqlite.Stats.Test";
1131   static const char kGlobalHistogramName[] = "Sqlite.Stats";
1132
1133   ASSERT_TRUE(db().BeginTransaction());
1134   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1135   EXPECT_TRUE(db().Execute(kCreateSql));
1136   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, 'text')"));
1137   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, 'text')"));
1138   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (12, 'text')"));
1139   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (13, 'text')"));
1140   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (14, 'text')"));
1141   EXPECT_TRUE(
1142       db().Execute("INSERT INTO foo VALUES (15, 'text');"
1143                    "INSERT INTO foo VALUES (16, 'text');"
1144                    "INSERT INTO foo VALUES (17, 'text');"
1145                    "INSERT INTO foo VALUES (18, 'text');"
1146                    "INSERT INTO foo VALUES (19, 'text')"));
1147   ASSERT_TRUE(db().CommitTransaction());
1148   ASSERT_TRUE(db().BeginTransaction());
1149   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (20, 'text')"));
1150   db().RollbackTransaction();
1151   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (20, 'text')"));
1152   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (21, 'text')"));
1153
1154   // The create, 5 inserts, multi-statement insert, rolled-back insert, 2
1155   // inserts outside transaction.
1156   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_EXECUTE, 10);
1157   tester.ExpectBucketCount(kGlobalHistogramName, sql::Database::EVENT_EXECUTE,
1158                            10);
1159
1160   // All of the executes, with the multi-statement inserts broken out, plus one
1161   // for each begin, commit, and rollback.
1162   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_STATEMENT_RUN,
1163                            18);
1164   tester.ExpectBucketCount(kGlobalHistogramName,
1165                            sql::Database::EVENT_STATEMENT_RUN, 18);
1166
1167   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_STATEMENT_ROWS,
1168                            0);
1169   tester.ExpectBucketCount(kGlobalHistogramName,
1170                            sql::Database::EVENT_STATEMENT_ROWS, 0);
1171   tester.ExpectBucketCount(kHistogramName,
1172                            sql::Database::EVENT_STATEMENT_SUCCESS, 18);
1173   tester.ExpectBucketCount(kGlobalHistogramName,
1174                            sql::Database::EVENT_STATEMENT_SUCCESS, 18);
1175
1176   // The 2 inserts outside the transaction.
1177   tester.ExpectBucketCount(kHistogramName,
1178                            sql::Database::EVENT_CHANGES_AUTOCOMMIT, 2);
1179   tester.ExpectBucketCount(kGlobalHistogramName,
1180                            sql::Database::EVENT_CHANGES_AUTOCOMMIT, 2);
1181
1182   // 11 inserts inside transactions.
1183   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_CHANGES, 11);
1184   tester.ExpectBucketCount(kGlobalHistogramName, sql::Database::EVENT_CHANGES,
1185                            11);
1186
1187   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_BEGIN, 2);
1188   tester.ExpectBucketCount(kGlobalHistogramName, sql::Database::EVENT_BEGIN, 2);
1189   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_COMMIT, 1);
1190   tester.ExpectBucketCount(kGlobalHistogramName, sql::Database::EVENT_COMMIT,
1191                            1);
1192   tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_ROLLBACK, 1);
1193   tester.ExpectBucketCount(kGlobalHistogramName, sql::Database::EVENT_ROLLBACK,
1194                            1);
1195 }
1196
1197 // Test Sqlite.Stats histogram for prepared statements.
1198 TEST_F(SQLDatabaseTest, EventsStatement) {
1199   // Re-open with histogram tag.
1200   db().Close();
1201   db().set_histogram_tag("Test");
1202   ASSERT_TRUE(db().Open(db_path()));
1203
1204   static const char kHistogramName[] = "Sqlite.Stats.Test";
1205   static const char kGlobalHistogramName[] = "Sqlite.Stats";
1206
1207   static const char kCreateSql[] =
1208       "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1209   EXPECT_TRUE(db().Execute(kCreateSql));
1210   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, 'text')"));
1211   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, 'text')"));
1212   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (12, 'text')"));
1213
1214   {
1215     base::HistogramTester tester;
1216
1217     {
1218       sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo"));
1219       while (s.Step()) {
1220       }
1221     }
1222
1223     tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_STATEMENT_RUN,
1224                              1);
1225     tester.ExpectBucketCount(kGlobalHistogramName,
1226                              sql::Database::EVENT_STATEMENT_RUN, 1);
1227     tester.ExpectBucketCount(kHistogramName,
1228                              sql::Database::EVENT_STATEMENT_ROWS, 3);
1229     tester.ExpectBucketCount(kGlobalHistogramName,
1230                              sql::Database::EVENT_STATEMENT_ROWS, 3);
1231     tester.ExpectBucketCount(kHistogramName,
1232                              sql::Database::EVENT_STATEMENT_SUCCESS, 1);
1233     tester.ExpectBucketCount(kGlobalHistogramName,
1234                              sql::Database::EVENT_STATEMENT_SUCCESS, 1);
1235   }
1236
1237   {
1238     base::HistogramTester tester;
1239
1240     {
1241       sql::Statement s(
1242           db().GetUniqueStatement("SELECT value FROM foo WHERE id > 10"));
1243       while (s.Step()) {
1244       }
1245     }
1246
1247     tester.ExpectBucketCount(kHistogramName, sql::Database::EVENT_STATEMENT_RUN,
1248                              1);
1249     tester.ExpectBucketCount(kGlobalHistogramName,
1250                              sql::Database::EVENT_STATEMENT_RUN, 1);
1251     tester.ExpectBucketCount(kHistogramName,
1252                              sql::Database::EVENT_STATEMENT_ROWS, 2);
1253     tester.ExpectBucketCount(kGlobalHistogramName,
1254                              sql::Database::EVENT_STATEMENT_ROWS, 2);
1255     tester.ExpectBucketCount(kHistogramName,
1256                              sql::Database::EVENT_STATEMENT_SUCCESS, 1);
1257     tester.ExpectBucketCount(kGlobalHistogramName,
1258                              sql::Database::EVENT_STATEMENT_SUCCESS, 1);
1259   }
1260 }
1261
1262 // Read-only query allocates time to QueryTime, but not others.
1263 TEST_F(SQLDatabaseTest, TimeQuery) {
1264   // Re-open with histogram tag.  Use an in-memory database to minimize variance
1265   // due to filesystem.
1266   db().Close();
1267   db().set_histogram_tag("Test");
1268   ASSERT_TRUE(db().OpenInMemory());
1269
1270   auto mock_clock = std::make_unique<base::SimpleTestTickClock>();
1271   // Retaining the pointer is safe because the connection keeps it alive.
1272   base::SimpleTestTickClock* mock_clock_ptr = mock_clock.get();
1273   db().set_clock_for_testing(std::move(mock_clock));
1274
1275   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1276   EXPECT_TRUE(db().Execute(kCreateSql));
1277
1278   // Function to inject pauses into statements.
1279   sql::test::ScopedScalarFunction scoper(
1280       db(), "milliadjust", 1,
1281       base::BindRepeating(&sqlite_adjust_millis, mock_clock_ptr));
1282
1283   base::HistogramTester tester;
1284
1285   EXPECT_TRUE(db().Execute("SELECT milliadjust(10)"));
1286
1287   std::unique_ptr<base::HistogramSamples> samples(
1288       tester.GetHistogramSamplesSinceCreation(kQueryTime));
1289   ASSERT_TRUE(samples);
1290   EXPECT_EQ(10, samples->sum());
1291
1292   samples = tester.GetHistogramSamplesSinceCreation(kUpdateTime);
1293   EXPECT_EQ(0, samples->sum());
1294
1295   samples = tester.GetHistogramSamplesSinceCreation(kCommitTime);
1296   EXPECT_EQ(0, samples->sum());
1297
1298   samples = tester.GetHistogramSamplesSinceCreation(kAutoCommitTime);
1299   EXPECT_EQ(0, samples->sum());
1300 }
1301
1302 // Autocommit update allocates time to QueryTime, UpdateTime, and
1303 // AutoCommitTime.
1304 TEST_F(SQLDatabaseTest, TimeUpdateAutocommit) {
1305   // Re-open with histogram tag.  Use an in-memory database to minimize variance
1306   // due to filesystem.
1307   db().Close();
1308   db().set_histogram_tag("Test");
1309   ASSERT_TRUE(db().OpenInMemory());
1310
1311   auto mock_clock = std::make_unique<base::SimpleTestTickClock>();
1312   // Retaining the pointer is safe because the connection keeps it alive.
1313   base::SimpleTestTickClock* mock_clock_ptr = mock_clock.get();
1314   db().set_clock_for_testing(std::move(mock_clock));
1315
1316   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1317   EXPECT_TRUE(db().Execute(kCreateSql));
1318
1319   // Function to inject pauses into statements.
1320   sql::test::ScopedScalarFunction scoper(
1321       db(), "milliadjust", 1,
1322       base::BindRepeating(&sqlite_adjust_millis, mock_clock_ptr));
1323
1324   base::HistogramTester tester;
1325
1326   EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, milliadjust(10))"));
1327
1328   std::unique_ptr<base::HistogramSamples> samples(
1329       tester.GetHistogramSamplesSinceCreation(kQueryTime));
1330   ASSERT_TRUE(samples);
1331   EXPECT_EQ(10, samples->sum());
1332
1333   samples = tester.GetHistogramSamplesSinceCreation(kUpdateTime);
1334   ASSERT_TRUE(samples);
1335   EXPECT_EQ(10, samples->sum());
1336
1337   samples = tester.GetHistogramSamplesSinceCreation(kCommitTime);
1338   EXPECT_EQ(0, samples->sum());
1339
1340   samples = tester.GetHistogramSamplesSinceCreation(kAutoCommitTime);
1341   ASSERT_TRUE(samples);
1342   EXPECT_EQ(10, samples->sum());
1343 }
1344
1345 // Update with explicit transaction allocates time to QueryTime, UpdateTime, and
1346 // CommitTime.
1347 TEST_F(SQLDatabaseTest, TimeUpdateTransaction) {
1348   // Re-open with histogram tag.  Use an in-memory database to minimize variance
1349   // due to filesystem.
1350   db().Close();
1351   db().set_histogram_tag("Test");
1352   ASSERT_TRUE(db().OpenInMemory());
1353
1354   auto mock_clock = std::make_unique<base::SimpleTestTickClock>();
1355   // Retaining the pointer is safe because the connection keeps it alive.
1356   base::SimpleTestTickClock* mock_clock_ptr = mock_clock.get();
1357   db().set_clock_for_testing(std::move(mock_clock));
1358
1359   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1360   EXPECT_TRUE(db().Execute(kCreateSql));
1361
1362   // Function to inject pauses into statements.
1363   sql::test::ScopedScalarFunction scoper(
1364       db(), "milliadjust", 1,
1365       base::BindRepeating(&sqlite_adjust_millis, mock_clock_ptr));
1366
1367   base::HistogramTester tester;
1368
1369   {
1370     // Make the commit slow.
1371     sql::test::ScopedCommitHook scoped_hook(
1372         db(), base::BindRepeating(adjust_commit_hook, mock_clock_ptr, 1000));
1373     ASSERT_TRUE(db().BeginTransaction());
1374     EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, milliadjust(10))"));
1375     EXPECT_TRUE(
1376         db().Execute("UPDATE foo SET value = milliadjust(100) WHERE id = 11"));
1377     EXPECT_TRUE(db().CommitTransaction());
1378   }
1379
1380   std::unique_ptr<base::HistogramSamples> samples(
1381       tester.GetHistogramSamplesSinceCreation(kQueryTime));
1382   ASSERT_TRUE(samples);
1383   // 10 for insert, 100 for update, 1000 for commit
1384   EXPECT_EQ(1110, samples->sum());
1385
1386   samples = tester.GetHistogramSamplesSinceCreation(kUpdateTime);
1387   ASSERT_TRUE(samples);
1388   EXPECT_EQ(1110, samples->sum());
1389
1390   samples = tester.GetHistogramSamplesSinceCreation(kCommitTime);
1391   ASSERT_TRUE(samples);
1392   EXPECT_EQ(1000, samples->sum());
1393
1394   samples = tester.GetHistogramSamplesSinceCreation(kAutoCommitTime);
1395   EXPECT_EQ(0, samples->sum());
1396 }
1397
1398 TEST_F(SQLDatabaseTest, OnMemoryDump) {
1399   base::trace_event::MemoryDumpArgs args = {
1400       base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
1401   base::trace_event::ProcessMemoryDump pmd(args);
1402   ASSERT_TRUE(db().memory_dump_provider_->OnMemoryDump(args, &pmd));
1403   EXPECT_GE(pmd.allocator_dumps().size(), 1u);
1404 }
1405
1406 // Test that the functions to collect diagnostic data run to completion, without
1407 // worrying too much about what they generate (since that will change).
1408 TEST_F(SQLDatabaseTest, CollectDiagnosticInfo) {
1409   const std::string corruption_info = db().CollectCorruptionInfo();
1410   EXPECT_NE(std::string::npos, corruption_info.find("SQLITE_CORRUPT"));
1411   EXPECT_NE(std::string::npos, corruption_info.find("integrity_check"));
1412
1413   // A statement to see in the results.
1414   const char* kSimpleSql = "SELECT 'mountain'";
1415   Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
1416
1417   // Error includes the statement.
1418   const std::string readonly_info = db().CollectErrorInfo(SQLITE_READONLY, &s);
1419   EXPECT_NE(std::string::npos, readonly_info.find(kSimpleSql));
1420
1421   // Some other error doesn't include the statment.
1422   // TODO(shess): This is weak.
1423   const std::string full_info = db().CollectErrorInfo(SQLITE_FULL, nullptr);
1424   EXPECT_EQ(std::string::npos, full_info.find(kSimpleSql));
1425
1426   // A table to see in the SQLITE_ERROR results.
1427   EXPECT_TRUE(db().Execute("CREATE TABLE volcano (x)"));
1428
1429   // Version info to see in the SQLITE_ERROR results.
1430   sql::MetaTable meta_table;
1431   ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
1432
1433   const std::string error_info = db().CollectErrorInfo(SQLITE_ERROR, &s);
1434   EXPECT_NE(std::string::npos, error_info.find(kSimpleSql));
1435   EXPECT_NE(std::string::npos, error_info.find("volcano"));
1436   EXPECT_NE(std::string::npos, error_info.find("version: 4"));
1437 }
1438
1439 TEST_F(SQLDatabaseTest, RegisterIntentToUpload) {
1440   base::FilePath breadcrumb_path =
1441       db_path().DirName().AppendASCII("sqlite-diag");
1442
1443   // No stale diagnostic store.
1444   ASSERT_TRUE(!base::PathExists(breadcrumb_path));
1445
1446   // The histogram tag is required to enable diagnostic features.
1447   EXPECT_FALSE(db().RegisterIntentToUpload());
1448   EXPECT_TRUE(!base::PathExists(breadcrumb_path));
1449
1450   db().Close();
1451   db().set_histogram_tag("Test");
1452   ASSERT_TRUE(db().Open(db_path()));
1453
1454   // Should signal upload only once.
1455   EXPECT_TRUE(db().RegisterIntentToUpload());
1456   EXPECT_TRUE(base::PathExists(breadcrumb_path));
1457   EXPECT_FALSE(db().RegisterIntentToUpload());
1458
1459   // Changing the histogram tag should allow new upload to succeed.
1460   db().Close();
1461   db().set_histogram_tag("NewTest");
1462   ASSERT_TRUE(db().Open(db_path()));
1463   EXPECT_TRUE(db().RegisterIntentToUpload());
1464   EXPECT_FALSE(db().RegisterIntentToUpload());
1465
1466   // Old tag is still prevented.
1467   db().Close();
1468   db().set_histogram_tag("Test");
1469   ASSERT_TRUE(db().Open(db_path()));
1470   EXPECT_FALSE(db().RegisterIntentToUpload());
1471 }
1472
1473 // Test that a fresh database has mmap enabled by default, if mmap'ed I/O is
1474 // enabled by SQLite.
1475 TEST_F(SQLDatabaseTest, MmapInitiallyEnabled) {
1476   {
1477     sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
1478     ASSERT_TRUE(s.Step())
1479         << "All supported SQLite versions should have mmap support";
1480
1481     // If mmap I/O is not on, attempt to turn it on.  If that succeeds, then
1482     // Open() should have turned it on.  If mmap support is disabled, 0 is
1483     // returned.  If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
1484     // instance MojoVFS), -1 is returned.
1485     if (s.ColumnInt(0) <= 0) {
1486       ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576"));
1487       s.Reset(true);
1488       ASSERT_TRUE(s.Step());
1489       EXPECT_LE(s.ColumnInt(0), 0);
1490     }
1491   }
1492
1493   // Test that explicit disable prevents mmap'ed I/O.
1494   db().Close();
1495   sql::Database::Delete(db_path());
1496   db().set_mmap_disabled();
1497   ASSERT_TRUE(db().Open(db_path()));
1498   EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size"));
1499 }
1500
1501 // Test whether a fresh database gets mmap enabled when using alternate status
1502 // storage.
1503 TEST_F(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
1504   // Re-open fresh database with alt-status flag set.
1505   db().Close();
1506   sql::Database::Delete(db_path());
1507   db().set_mmap_alt_status();
1508   ASSERT_TRUE(db().Open(db_path()));
1509
1510   {
1511     sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
1512     ASSERT_TRUE(s.Step())
1513         << "All supported SQLite versions should have mmap support";
1514
1515     // If mmap I/O is not on, attempt to turn it on.  If that succeeds, then
1516     // Open() should have turned it on.  If mmap support is disabled, 0 is
1517     // returned.  If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
1518     // instance MojoVFS), -1 is returned.
1519     if (s.ColumnInt(0) <= 0) {
1520       ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576"));
1521       s.Reset(true);
1522       ASSERT_TRUE(s.Step());
1523       EXPECT_LE(s.ColumnInt(0), 0);
1524     }
1525   }
1526
1527   // Test that explicit disable overrides set_mmap_alt_status().
1528   db().Close();
1529   sql::Database::Delete(db_path());
1530   db().set_mmap_disabled();
1531   ASSERT_TRUE(db().Open(db_path()));
1532   EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size"));
1533 }
1534
1535 TEST_F(SQLDatabaseTest, GetAppropriateMmapSize) {
1536   const size_t kMmapAlot = 25 * 1024 * 1024;
1537   int64_t mmap_status = MetaTable::kMmapFailure;
1538
1539   // If there is no meta table (as for a fresh database), assume that everything
1540   // should be mapped, and the status of the meta table is not affected.
1541   ASSERT_TRUE(!db().DoesTableExist("meta"));
1542   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1543   ASSERT_TRUE(!db().DoesTableExist("meta"));
1544
1545   // When the meta table is first created, it sets up to map everything.
1546   MetaTable().Init(&db(), 1, 1);
1547   ASSERT_TRUE(db().DoesTableExist("meta"));
1548   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1549   ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1550   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1551
1552   // Preload with partial progress of one page.  Should map everything.
1553   ASSERT_TRUE(db().Execute("REPLACE INTO meta VALUES ('mmap_status', 1)"));
1554   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1555   ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1556   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1557
1558   // Failure status maps nothing.
1559   ASSERT_TRUE(db().Execute("REPLACE INTO meta VALUES ('mmap_status', -2)"));
1560   ASSERT_EQ(0UL, db().GetAppropriateMmapSize());
1561
1562   // Re-initializing the meta table does not re-create the key if the table
1563   // already exists.
1564   ASSERT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'mmap_status'"));
1565   MetaTable().Init(&db(), 1, 1);
1566   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1567   ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1568   ASSERT_EQ(0, mmap_status);
1569
1570   // With no key, map everything and create the key.
1571   // TODO(shess): This really should be "maps everything after validating it",
1572   // but that is more complicated to structure.
1573   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1574   ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
1575   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1576 }
1577
1578 TEST_F(SQLDatabaseTest, GetAppropriateMmapSizeAltStatus) {
1579   const size_t kMmapAlot = 25 * 1024 * 1024;
1580
1581   // At this point, Database still expects a future [meta] table.
1582   ASSERT_FALSE(db().DoesTableExist("meta"));
1583   ASSERT_FALSE(db().DoesViewExist("MmapStatus"));
1584   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1585   ASSERT_FALSE(db().DoesTableExist("meta"));
1586   ASSERT_FALSE(db().DoesViewExist("MmapStatus"));
1587
1588   // Using alt status, everything should be mapped, with state in the view.
1589   db().set_mmap_alt_status();
1590   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1591   ASSERT_FALSE(db().DoesTableExist("meta"));
1592   ASSERT_TRUE(db().DoesViewExist("MmapStatus"));
1593   EXPECT_EQ(base::IntToString(MetaTable::kMmapSuccess),
1594             ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
1595
1596   // Also maps everything when kMmapSuccess is already in the view.
1597   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1598
1599   // Preload with partial progress of one page.  Should map everything.
1600   ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus"));
1601   ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus (value) AS SELECT 1"));
1602   ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
1603   EXPECT_EQ(base::IntToString(MetaTable::kMmapSuccess),
1604             ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
1605
1606   // Failure status leads to nothing being mapped.
1607   ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus"));
1608   ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus (value) AS SELECT -2"));
1609   ASSERT_EQ(0UL, db().GetAppropriateMmapSize());
1610   EXPECT_EQ(base::IntToString(MetaTable::kMmapFailure),
1611             ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
1612 }
1613
1614 // To prevent invalid SQL from accidentally shipping to production, prepared
1615 // statements which fail to compile with SQLITE_ERROR call DLOG(DCHECK).  This
1616 // case cannot be suppressed with an error callback.
1617 TEST_F(SQLDatabaseTest, CompileError) {
1618 // DEATH tests not supported on Android, iOS, or Fuchsia.
1619 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
1620   if (DLOG_IS_ON(FATAL)) {
1621     db().set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
1622     ASSERT_DEATH({ db().GetUniqueStatement("SELECT x"); },
1623                  "SQL compile error no such column: x");
1624   }
1625 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
1626 }
1627
1628 // Verify that Raze() can handle an empty file.  SQLite should treat
1629 // this as an empty database.
1630 TEST_F(SQLDatabaseTest, SqlTempMemoryFeatureFlagDefault) {
1631   EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA temp_store"))
1632       << "temp_store should not be set by default";
1633 }
1634
1635 TEST_F(SQLDatabaseTest, SqlTempMemoryFeatureFlagEnabled) {
1636   base::test::ScopedFeatureList feature_list;
1637   feature_list.InitAndEnableFeature(features::kSqlTempStoreMemory);
1638
1639   db().Close();
1640
1641   ASSERT_TRUE(db().Open(db_path()));
1642   EXPECT_EQ("2", ExecuteWithResult(&db(), "PRAGMA temp_store"))
1643       << "temp_store should be set by the feature flag SqlTempStoreMemory";
1644 }
1645
1646 }  // namespace sql