[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / sql / database_unittest.cc
1 // Copyright 2012 The Chromium Authors
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 "sql/database.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <cstdint>
10
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/files/file_util.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/logging.h"
16 #include "base/memory/raw_ptr.h"
17 #include "base/sequence_checker.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/test/bind.h"
20 #include "base/test/gtest_util.h"
21 #include "base/test/metrics/histogram_tester.h"
22 #include "base/thread_annotations.h"
23 #include "base/trace_event/process_memory_dump.h"
24 #include "build/build_config.h"
25 #include "sql/database_memory_dump_provider.h"
26 #include "sql/meta_table.h"
27 #include "sql/sql_features.h"
28 #include "sql/statement.h"
29 #include "sql/test/database_test_peer.h"
30 #include "sql/test/scoped_error_expecter.h"
31 #include "sql/test/test_helpers.h"
32 #include "sql/transaction.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/sqlite/sqlite3.h"
36
37 namespace sql {
38
39 namespace {
40
41 using sql::test::ExecuteWithResult;
42
43 // Helper to return the count of items in sqlite_schema.  Return -1 in
44 // case of error.
45 int SqliteSchemaCount(Database* db) {
46   const char* kSchemaCount = "SELECT COUNT(*) FROM sqlite_schema";
47   Statement s(db->GetUniqueStatement(kSchemaCount));
48   return s.Step() ? s.ColumnInt(0) : -1;
49 }
50
51 // Handle errors by blowing away the database.
52 void RazeErrorCallback(Database* db,
53                        int expected_error,
54                        int error,
55                        Statement* stmt) {
56   // Nothing here needs extended errors at this time.
57   EXPECT_EQ(expected_error, expected_error & 0xff);
58   EXPECT_EQ(expected_error, error & 0xff);
59   db->RazeAndClose();
60 }
61
62 #if BUILDFLAG(IS_POSIX)
63 // Set a umask and restore the old mask on destruction.  Cribbed from
64 // shared_memory_unittest.cc.  Used by POSIX-only UserPermission test.
65 class ScopedUmaskSetter {
66  public:
67   explicit ScopedUmaskSetter(mode_t target_mask) {
68     old_umask_ = umask(target_mask);
69   }
70   ~ScopedUmaskSetter() { umask(old_umask_); }
71
72   ScopedUmaskSetter(const ScopedUmaskSetter&) = delete;
73   ScopedUmaskSetter& operator=(const ScopedUmaskSetter&) = delete;
74
75  private:
76   mode_t old_umask_;
77 };
78 #endif  // BUILDFLAG(IS_POSIX)
79
80 }  // namespace
81
82 // We use the parameter to run all tests with WAL mode on and off.
83 class SQLDatabaseTest : public testing::Test,
84                         public testing::WithParamInterface<bool> {
85  public:
86   enum class OverwriteType {
87     kTruncate,
88     kOverwrite,
89   };
90
91   ~SQLDatabaseTest() override = default;
92
93   void SetUp() override {
94     db_ = std::make_unique<Database>(GetDBOptions());
95     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
96     db_path_ = temp_dir_.GetPath().AppendASCII("database_test.sqlite");
97     ASSERT_TRUE(db_->Open(db_path_));
98   }
99
100   DatabaseOptions GetDBOptions() {
101     DatabaseOptions options;
102     options.wal_mode = IsWALEnabled();
103     // TODO(crbug.com/1120969): Remove after switching to exclusive mode on by
104     // default.
105     options.exclusive_locking = false;
106 #if BUILDFLAG(IS_FUCHSIA)  // Exclusive mode needs to be enabled to enter WAL
107                            // mode on Fuchsia
108     if (IsWALEnabled()) {
109       options.exclusive_locking = true;
110     }
111 #endif  // BUILDFLAG(IS_FUCHSIA)
112     return options;
113   }
114
115   bool IsWALEnabled() { return GetParam(); }
116
117   bool TruncateDatabase() {
118     base::File file(db_path_,
119                     base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
120     return file.SetLength(0);
121   }
122
123   bool OverwriteDatabaseHeader(OverwriteType type) {
124     base::File file(db_path_,
125                     base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
126     if (type == OverwriteType::kTruncate) {
127       if (!file.SetLength(0))
128         return false;
129     }
130
131     static constexpr char kText[] = "Now is the winter of our discontent.";
132     constexpr int kTextBytes = sizeof(kText) - 1;
133     return file.Write(0, kText, kTextBytes) == kTextBytes;
134   }
135
136  protected:
137   base::ScopedTempDir temp_dir_;
138   base::FilePath db_path_;
139   std::unique_ptr<Database> db_;
140 };
141
142 TEST_P(SQLDatabaseTest, Execute_ValidStatement) {
143   ASSERT_TRUE(db_->Execute("CREATE TABLE data(contents TEXT)"));
144   EXPECT_EQ(SQLITE_OK, db_->GetErrorCode());
145 }
146
147 TEST_P(SQLDatabaseTest, Execute_InvalidStatement) {
148   {
149     sql::test::ScopedErrorExpecter error_expecter;
150     error_expecter.ExpectError(SQLITE_ERROR);
151     EXPECT_FALSE(db_->Execute("CREATE TABLE data("));
152     EXPECT_TRUE(error_expecter.SawExpectedErrors());
153   }
154   EXPECT_EQ(SQLITE_ERROR, db_->GetErrorCode());
155 }
156
157 TEST_P(SQLDatabaseTest, ExecuteScriptForTesting_OneLineValid) {
158   ASSERT_TRUE(db_->ExecuteScriptForTesting("CREATE TABLE data(contents TEXT)"));
159   EXPECT_EQ(SQLITE_OK, db_->GetErrorCode());
160 }
161
162 TEST_P(SQLDatabaseTest, ExecuteScriptForTesting_OneLineInvalid) {
163   ASSERT_FALSE(db_->ExecuteScriptForTesting("CREATE TABLE data("));
164   EXPECT_EQ(SQLITE_ERROR, db_->GetErrorCode());
165 }
166
167 TEST_P(SQLDatabaseTest, ExecuteScriptForTesting_ExtraContents) {
168   EXPECT_TRUE(db_->ExecuteScriptForTesting("CREATE TABLE data1(id)"))
169       << "Minimal statement";
170   EXPECT_TRUE(db_->ExecuteScriptForTesting("CREATE TABLE data2(id);"))
171       << "Extra semicolon";
172   EXPECT_TRUE(db_->ExecuteScriptForTesting("CREATE TABLE data3(id) -- Comment"))
173       << "Trailing comment";
174
175   EXPECT_TRUE(db_->ExecuteScriptForTesting(
176       "CREATE TABLE data4(id);CREATE TABLE data5(id)"))
177       << "Extra statement without whitespace";
178   EXPECT_TRUE(db_->ExecuteScriptForTesting(
179       "CREATE TABLE data6(id); CREATE TABLE data7(id)"))
180       << "Extra statement separated by whitespace";
181
182   EXPECT_TRUE(db_->ExecuteScriptForTesting("CREATE TABLE data8(id);-- Comment"))
183       << "Comment without whitespace";
184   EXPECT_TRUE(
185       db_->ExecuteScriptForTesting("CREATE TABLE data9(id); -- Comment"))
186       << "Comment sepatated by whitespace";
187 }
188
189 TEST_P(SQLDatabaseTest, ExecuteScriptForTesting_MultipleValidLines) {
190   EXPECT_TRUE(db_->ExecuteScriptForTesting(R"(
191       CREATE TABLE data1(contents TEXT);
192       CREATE TABLE data2(contents TEXT);
193       CREATE TABLE data3(contents TEXT);
194   )"));
195   EXPECT_EQ(SQLITE_OK, db_->GetErrorCode());
196
197   // DoesColumnExist() is implemented directly on top of a SQLite call. The
198   // other schema functions use sql::Statement infrastructure to query the
199   // schema table.
200   EXPECT_TRUE(db_->DoesColumnExist("data1", "contents"));
201   EXPECT_TRUE(db_->DoesColumnExist("data2", "contents"));
202   EXPECT_TRUE(db_->DoesColumnExist("data3", "contents"));
203 }
204
205 TEST_P(SQLDatabaseTest, ExecuteScriptForTesting_StopsOnCompileError) {
206   EXPECT_FALSE(db_->ExecuteScriptForTesting(R"(
207       CREATE TABLE data1(contents TEXT);
208       CREATE TABLE data1();
209       CREATE TABLE data3(contents TEXT);
210   )"));
211   EXPECT_EQ(SQLITE_ERROR, db_->GetErrorCode());
212
213   EXPECT_TRUE(db_->DoesColumnExist("data1", "contents"));
214   EXPECT_FALSE(db_->DoesColumnExist("data3", "contents"));
215 }
216
217 TEST_P(SQLDatabaseTest, ExecuteScriptForTesting_StopsOnStepError) {
218   EXPECT_FALSE(db_->ExecuteScriptForTesting(R"(
219       CREATE TABLE data1(contents TEXT UNIQUE);
220       INSERT INTO data1(contents) VALUES('value1');
221       INSERT INTO data1(contents) VALUES('value1');
222       CREATE TABLE data3(contents TEXT);
223   )"));
224   EXPECT_EQ(SQLITE_CONSTRAINT_UNIQUE, db_->GetErrorCode());
225
226   EXPECT_TRUE(db_->DoesColumnExist("data1", "contents"));
227   EXPECT_FALSE(db_->DoesColumnExist("data3", "contents"));
228 }
229
230 TEST_P(SQLDatabaseTest, CachedStatement) {
231   StatementID id1 = SQL_FROM_HERE;
232   StatementID id2 = SQL_FROM_HERE;
233   static const char kId1Sql[] = "SELECT a FROM foo";
234   static const char kId2Sql[] = "SELECT b FROM foo";
235
236   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
237   ASSERT_TRUE(db_->Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
238
239   sqlite3_stmt* raw_id1_statement;
240   sqlite3_stmt* raw_id2_statement;
241   {
242     scoped_refptr<Database::StatementRef> ref_from_id1 =
243         db_->GetCachedStatement(id1, kId1Sql);
244     raw_id1_statement = ref_from_id1->stmt();
245
246     Statement from_id1(std::move(ref_from_id1));
247     ASSERT_TRUE(from_id1.is_valid());
248     ASSERT_TRUE(from_id1.Step());
249     EXPECT_EQ(12, from_id1.ColumnInt(0));
250
251     scoped_refptr<Database::StatementRef> ref_from_id2 =
252         db_->GetCachedStatement(id2, kId2Sql);
253     raw_id2_statement = ref_from_id2->stmt();
254     EXPECT_NE(raw_id1_statement, raw_id2_statement);
255
256     Statement from_id2(std::move(ref_from_id2));
257     ASSERT_TRUE(from_id2.is_valid());
258     ASSERT_TRUE(from_id2.Step());
259     EXPECT_EQ(13, from_id2.ColumnInt(0));
260   }
261
262   {
263     scoped_refptr<Database::StatementRef> ref_from_id1 =
264         db_->GetCachedStatement(id1, kId1Sql);
265     EXPECT_EQ(raw_id1_statement, ref_from_id1->stmt())
266         << "statement was not cached";
267
268     Statement from_id1(std::move(ref_from_id1));
269     ASSERT_TRUE(from_id1.is_valid());
270     ASSERT_TRUE(from_id1.Step()) << "cached statement was not reset";
271     EXPECT_EQ(12, from_id1.ColumnInt(0));
272
273     scoped_refptr<Database::StatementRef> ref_from_id2 =
274         db_->GetCachedStatement(id2, kId2Sql);
275     EXPECT_EQ(raw_id2_statement, ref_from_id2->stmt())
276         << "statement was not cached";
277
278     Statement from_id2(std::move(ref_from_id2));
279     ASSERT_TRUE(from_id2.is_valid());
280     ASSERT_TRUE(from_id2.Step()) << "cached statement was not reset";
281     EXPECT_EQ(13, from_id2.ColumnInt(0));
282   }
283
284   EXPECT_DCHECK_DEATH(db_->GetCachedStatement(id1, kId2Sql))
285       << "Using a different SQL with the same statement ID should DCHECK";
286   EXPECT_DCHECK_DEATH(db_->GetCachedStatement(id2, kId1Sql))
287       << "Using a different SQL with the same statement ID should DCHECK";
288 }
289
290 TEST_P(SQLDatabaseTest, IsSQLValidTest) {
291   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
292   ASSERT_TRUE(db_->IsSQLValid("SELECT a FROM foo"));
293   ASSERT_FALSE(db_->IsSQLValid("SELECT no_exist FROM foo"));
294 }
295
296 TEST_P(SQLDatabaseTest, DoesTableExist) {
297   EXPECT_FALSE(db_->DoesTableExist("foo"));
298   EXPECT_FALSE(db_->DoesTableExist("foo_index"));
299
300   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
301   ASSERT_TRUE(db_->Execute("CREATE INDEX foo_index ON foo (a)"));
302   EXPECT_TRUE(db_->DoesTableExist("foo"));
303   EXPECT_FALSE(db_->DoesTableExist("foo_index"));
304
305   // DoesTableExist() is case-sensitive.
306   EXPECT_FALSE(db_->DoesTableExist("Foo"));
307   EXPECT_FALSE(db_->DoesTableExist("FOO"));
308 }
309
310 TEST_P(SQLDatabaseTest, DoesIndexExist) {
311   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
312   EXPECT_FALSE(db_->DoesIndexExist("foo"));
313   EXPECT_FALSE(db_->DoesIndexExist("foo_ubdex"));
314
315   ASSERT_TRUE(db_->Execute("CREATE INDEX foo_index ON foo (a)"));
316   EXPECT_TRUE(db_->DoesIndexExist("foo_index"));
317   EXPECT_FALSE(db_->DoesIndexExist("foo"));
318
319   // DoesIndexExist() is case-sensitive.
320   EXPECT_FALSE(db_->DoesIndexExist("Foo_index"));
321   EXPECT_FALSE(db_->DoesIndexExist("Foo_Index"));
322   EXPECT_FALSE(db_->DoesIndexExist("FOO_INDEX"));
323 }
324
325 TEST_P(SQLDatabaseTest, DoesViewExist) {
326   EXPECT_FALSE(db_->DoesViewExist("voo"));
327   ASSERT_TRUE(db_->Execute("CREATE VIEW voo (a) AS SELECT 1"));
328   EXPECT_FALSE(db_->DoesIndexExist("voo"));
329   EXPECT_FALSE(db_->DoesTableExist("voo"));
330   EXPECT_TRUE(db_->DoesViewExist("voo"));
331
332   // DoesTableExist() is case-sensitive.
333   EXPECT_FALSE(db_->DoesViewExist("Voo"));
334   EXPECT_FALSE(db_->DoesViewExist("VOO"));
335 }
336
337 TEST_P(SQLDatabaseTest, DoesColumnExist) {
338   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
339
340   EXPECT_FALSE(db_->DoesColumnExist("foo", "bar"));
341   EXPECT_TRUE(db_->DoesColumnExist("foo", "a"));
342
343   ASSERT_FALSE(db_->DoesTableExist("bar"));
344   EXPECT_FALSE(db_->DoesColumnExist("bar", "b"));
345
346   // SQLite resolves table/column names without case sensitivity.
347   EXPECT_TRUE(db_->DoesColumnExist("FOO", "A"));
348   EXPECT_TRUE(db_->DoesColumnExist("FOO", "a"));
349   EXPECT_TRUE(db_->DoesColumnExist("foo", "A"));
350 }
351
352 TEST_P(SQLDatabaseTest, GetLastInsertRowId) {
353   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
354
355   ASSERT_TRUE(db_->Execute("INSERT INTO foo (value) VALUES (12)"));
356
357   // Last insert row ID should be valid.
358   int64_t row = db_->GetLastInsertRowId();
359   EXPECT_LT(0, row);
360
361   // It should be the primary key of the row we just inserted.
362   Statement s(db_->GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
363   s.BindInt64(0, row);
364   ASSERT_TRUE(s.Step());
365   EXPECT_EQ(12, s.ColumnInt(0));
366 }
367
368 // Test the scoped error expecter by attempting to insert a duplicate
369 // value into an index.
370 TEST_P(SQLDatabaseTest, ScopedErrorExpecter) {
371   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
372   ASSERT_TRUE(db_->Execute(kCreateSql));
373   ASSERT_TRUE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
374
375   {
376     sql::test::ScopedErrorExpecter expecter;
377     expecter.ExpectError(SQLITE_CONSTRAINT);
378     ASSERT_FALSE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
379     ASSERT_TRUE(expecter.SawExpectedErrors());
380   }
381 }
382
383 TEST_P(SQLDatabaseTest, SchemaIntrospectionUsesErrorExpecter) {
384   const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
385   ASSERT_TRUE(db_->Execute(kCreateSql));
386   ASSERT_FALSE(db_->DoesTableExist("bar"));
387   ASSERT_TRUE(db_->DoesTableExist("foo"));
388   ASSERT_TRUE(db_->DoesColumnExist("foo", "id"));
389   db_->Close();
390
391   // Corrupt the database so that nothing works, including PRAGMAs.
392   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
393
394   {
395     sql::test::ScopedErrorExpecter expecter;
396     expecter.ExpectError(SQLITE_CORRUPT);
397     ASSERT_TRUE(db_->Open(db_path_));
398     ASSERT_FALSE(db_->DoesTableExist("bar"));
399     ASSERT_FALSE(db_->DoesTableExist("foo"));
400     ASSERT_FALSE(db_->DoesColumnExist("foo", "id"));
401     ASSERT_TRUE(expecter.SawExpectedErrors());
402   }
403 }
404
405 TEST_P(SQLDatabaseTest, SetErrorCallback) {
406   static constexpr char kCreateSql[] =
407       "CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)";
408   ASSERT_TRUE(db_->Execute(kCreateSql));
409   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(12)"));
410
411   bool error_callback_called = false;
412   int error = SQLITE_OK;
413   db_->set_error_callback(base::BindLambdaForTesting(
414       [&](int sqlite_error, sql::Statement* statement) {
415         error_callback_called = true;
416         error = sqlite_error;
417       }));
418   EXPECT_FALSE(db_->Execute("INSERT INTO rows(id) VALUES(12)"))
419       << "Inserting a duplicate primary key should have failed";
420   EXPECT_TRUE(error_callback_called)
421       << "Execute() should report errors to the database error callback";
422   EXPECT_EQ(SQLITE_CONSTRAINT_PRIMARYKEY, error)
423       << "Execute() should report errors to the database error callback";
424 }
425
426 TEST_P(SQLDatabaseTest, SetErrorCallbackDchecksOnExistingCallback) {
427   db_->set_error_callback(base::DoNothing());
428   EXPECT_DCHECK_DEATH(db_->set_error_callback(base::DoNothing()))
429       << "set_error_callback() should DCHECK if error callback already exists";
430 }
431
432 TEST_P(SQLDatabaseTest, ResetErrorCallback) {
433   static constexpr char kCreateSql[] =
434       "CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)";
435   ASSERT_TRUE(db_->Execute(kCreateSql));
436   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(12)"));
437
438   bool error_callback_called = false;
439   int error = SQLITE_OK;
440   db_->set_error_callback(
441       base::BindLambdaForTesting([&](int sqlite_error, Statement* statement) {
442         error_callback_called = true;
443         error = sqlite_error;
444       }));
445   db_->reset_error_callback();
446
447   {
448     sql::test::ScopedErrorExpecter expecter;
449     expecter.ExpectError(SQLITE_CONSTRAINT);
450     EXPECT_FALSE(db_->Execute("INSERT INTO rows(id) VALUES(12)"))
451         << "Inserting a duplicate primary key should have failed";
452     EXPECT_TRUE(expecter.SawExpectedErrors())
453         << "Inserting a duplicate primary key should have failed";
454   }
455   EXPECT_FALSE(error_callback_called)
456       << "Execute() should not report errors after reset_error_callback()";
457   EXPECT_EQ(SQLITE_OK, error)
458       << "Execute() should not report errors after reset_error_callback()";
459 }
460
461 // Sets a flag to true/false to track being alive.
462 class LifeTracker {
463  public:
464   explicit LifeTracker(bool* flag_ptr) : flag_ptr_(flag_ptr) {
465     DCHECK(flag_ptr != nullptr);
466     DCHECK(!*flag_ptr)
467         << "LifeTracker's flag should be set to false prior to construction";
468     *flag_ptr_ = true;
469   }
470
471   LifeTracker(LifeTracker&& rhs) {
472     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
473     DCHECK_CALLED_ON_VALID_SEQUENCE(rhs.sequence_checker_);
474     flag_ptr_ = rhs.flag_ptr_;
475     rhs.flag_ptr_ = nullptr;
476   }
477
478   // base::RepeatingCallback only requires move-construction support.
479   LifeTracker& operator=(const LifeTracker& rhs) = delete;
480
481   ~LifeTracker() {
482     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
483     if (flag_ptr_)
484       *flag_ptr_ = false;
485   }
486
487  private:
488   SEQUENCE_CHECKER(sequence_checker_);
489   raw_ptr<bool> flag_ptr_ GUARDED_BY_CONTEXT(sequence_checker_);
490 };
491
492 // base::BindRepeating() can curry arguments to be passed by const reference to
493 // the callback function. If the error callback function calls
494 // reset_error_callback() and the Database doesn't hang onto the callback while
495 // running it, the storage for those arguments may be deleted while the callback
496 // function is executing. This test ensures that the database is hanging onto
497 // the callback while running it.
498 TEST_P(SQLDatabaseTest, ErrorCallbackStorageProtectedWhileRun) {
499   bool is_alive = false;
500   db_->set_error_callback(base::BindRepeating(
501       [](Database* db, bool* life_tracker_is_alive,
502          const LifeTracker& life_tracker, int sqlite_error,
503          Statement* statement) {
504         EXPECT_TRUE(*life_tracker_is_alive)
505             << "The error callback storage should be alive when it is Run()";
506         db->reset_error_callback();
507         EXPECT_TRUE(*life_tracker_is_alive)
508             << "The error storage should remain alive during Run() after "
509             << "reset_error_callback()";
510       },
511       base::Unretained(db_.get()), base::Unretained(&is_alive),
512       LifeTracker(&is_alive)));
513
514   EXPECT_TRUE(is_alive)
515       << "The error callback storage should be alive after creation";
516   EXPECT_FALSE(db_->Execute("INSERT INTO rows(id) VALUES(12)"));
517   EXPECT_FALSE(is_alive)
518       << "The error callback storage should be released after Run() completes";
519 }
520
521 TEST_P(SQLDatabaseTest, Execute_CompilationError) {
522   bool error_callback_called = false;
523   db_->set_error_callback(base::BindLambdaForTesting([&](int error,
524                                                          sql::Statement*
525                                                              statement) {
526     EXPECT_EQ(SQLITE_ERROR, error);
527     EXPECT_EQ(nullptr, statement);
528     EXPECT_FALSE(error_callback_called)
529         << "SQL compilation errors should call the error callback exactly once";
530     error_callback_called = true;
531   }));
532
533   {
534     sql::test::ScopedErrorExpecter expecter;
535     expecter.ExpectError(SQLITE_ERROR);
536     EXPECT_FALSE(db_->Execute("SELECT missing_column FROM missing_table"));
537     EXPECT_TRUE(expecter.SawExpectedErrors());
538   }
539
540   EXPECT_TRUE(error_callback_called)
541       << "SQL compilation errors should call the error callback";
542 }
543
544 TEST_P(SQLDatabaseTest, GetUniqueStatement_CompilationError) {
545   bool error_callback_called = false;
546   db_->set_error_callback(base::BindLambdaForTesting([&](int error,
547                                                          sql::Statement*
548                                                              statement) {
549     EXPECT_EQ(SQLITE_ERROR, error);
550     EXPECT_EQ(nullptr, statement);
551     EXPECT_FALSE(error_callback_called)
552         << "SQL compilation errors should call the error callback exactly once";
553     error_callback_called = true;
554   }));
555
556   {
557     sql::test::ScopedErrorExpecter expecter;
558     expecter.ExpectError(SQLITE_ERROR);
559     sql::Statement statement(
560         db_->GetUniqueStatement("SELECT missing_column FROM missing_table"));
561     EXPECT_FALSE(statement.is_valid());
562     EXPECT_TRUE(expecter.SawExpectedErrors());
563   }
564
565   EXPECT_TRUE(error_callback_called)
566       << "SQL compilation errors should call the error callback";
567 }
568
569 TEST_P(SQLDatabaseTest, GetCachedStatement_CompilationError) {
570   bool error_callback_called = false;
571   db_->set_error_callback(base::BindLambdaForTesting([&](int error,
572                                                          sql::Statement*
573                                                              statement) {
574     EXPECT_EQ(SQLITE_ERROR, error);
575     EXPECT_EQ(nullptr, statement);
576     EXPECT_FALSE(error_callback_called)
577         << "SQL compilation errors should call the error callback exactly once";
578     error_callback_called = true;
579   }));
580
581   {
582     sql::test::ScopedErrorExpecter expecter;
583     expecter.ExpectError(SQLITE_ERROR);
584     sql::Statement statement(db_->GetCachedStatement(
585         SQL_FROM_HERE, "SELECT missing_column FROM missing_table"));
586     EXPECT_FALSE(statement.is_valid());
587     EXPECT_TRUE(expecter.SawExpectedErrors());
588   }
589
590   EXPECT_TRUE(error_callback_called)
591       << "SQL compilation errors should call the error callback";
592 }
593
594 TEST_P(SQLDatabaseTest, GetUniqueStatement_ExtraContents) {
595   sql::Statement minimal(db_->GetUniqueStatement("SELECT 1"));
596   sql::Statement extra_semicolon(db_->GetUniqueStatement("SELECT 1;"));
597
598   // It would be nice to flag trailing comments too, as they cost binary size.
599   // However, there's no easy way of doing that.
600   sql::Statement trailing_comment(
601       db_->GetUniqueStatement("SELECT 1 -- Comment"));
602
603   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("SELECT 1;SELECT 2"))
604       << "Extra statement without whitespace";
605   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("SELECT 1; SELECT 2"))
606       << "Extra statement separated by whitespace";
607   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("SELECT 1;-- Comment"))
608       << "Comment without whitespace";
609   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("SELECT 1; -- Comment"))
610       << "Comment separated by whitespace";
611 }
612
613 TEST_P(SQLDatabaseTest, GetCachedStatement_ExtraContents) {
614   sql::Statement minimal(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
615   sql::Statement extra_semicolon(
616       db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1;"));
617
618   // It would be nice to flag trailing comments too, as they cost binary size.
619   // However, there's no easy way of doing that.
620   sql::Statement trailing_comment(
621       db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1 -- Comment"));
622
623   EXPECT_DCHECK_DEATH(
624       db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1;SELECT 2"))
625       << "Extra statement without whitespace";
626   EXPECT_DCHECK_DEATH(
627       db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1; SELECT 2"))
628       << "Extra statement separated by whitespace";
629   EXPECT_DCHECK_DEATH(
630       db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1;-- Comment"))
631       << "Comment without whitespace";
632   EXPECT_DCHECK_DEATH(
633       db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1; -- Comment"))
634       << "Comment separated by whitespace";
635 }
636
637 TEST_P(SQLDatabaseTest, IsSQLValid_ExtraContents) {
638   EXPECT_TRUE(db_->IsSQLValid("SELECT 1"));
639   EXPECT_TRUE(db_->IsSQLValid("SELECT 1;"))
640       << "Trailing semicolons are currently tolerated";
641
642   // It would be nice to flag trailing comments too, as they cost binary size.
643   // However, there's no easy way of doing that.
644   EXPECT_TRUE(db_->IsSQLValid("SELECT 1 -- Comment"))
645       << "Trailing comments are currently tolerated";
646
647   EXPECT_DCHECK_DEATH(db_->IsSQLValid("SELECT 1;SELECT 2"))
648       << "Extra statement without whitespace";
649   EXPECT_DCHECK_DEATH(db_->IsSQLValid("SELECT 1; SELECT 2"))
650       << "Extra statement separated by whitespace";
651   EXPECT_DCHECK_DEATH(db_->IsSQLValid("SELECT 1;-- Comment"))
652       << "Comment without whitespace";
653   EXPECT_DCHECK_DEATH(db_->IsSQLValid("SELECT 1; -- Comment"))
654       << "Comment separated by whitespace";
655 }
656
657 TEST_P(SQLDatabaseTest, GetUniqueStatement_NoContents) {
658   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("")) << "Empty string";
659   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement(" ")) << "Space";
660   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("\n")) << "Newline";
661   EXPECT_DCHECK_DEATH(db_->GetUniqueStatement("-- Comment")) << "Comment";
662 }
663
664 TEST_P(SQLDatabaseTest, GetCachedStatement_NoContents) {
665   EXPECT_DCHECK_DEATH(db_->GetCachedStatement(SQL_FROM_HERE, ""))
666       << "Empty string";
667   EXPECT_DCHECK_DEATH(db_->GetCachedStatement(SQL_FROM_HERE, " ")) << "Space";
668   EXPECT_DCHECK_DEATH(db_->GetCachedStatement(SQL_FROM_HERE, "\n"))
669       << "Newline";
670   EXPECT_DCHECK_DEATH(db_->GetCachedStatement(SQL_FROM_HERE, "-- Comment"))
671       << "Comment";
672 }
673
674 TEST_P(SQLDatabaseTest, GetReadonlyStatement) {
675   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
676   ASSERT_TRUE(db_->Execute(kCreateSql));
677   ASSERT_TRUE(db_->Execute("INSERT INTO foo (value) VALUES (12)"));
678
679   // PRAGMA statements do not change the database file.
680   {
681     Statement s(db_->GetReadonlyStatement("PRAGMA analysis_limit"));
682     ASSERT_TRUE(s.Step());
683   }
684   {
685     Statement s(db_->GetReadonlyStatement("PRAGMA analysis_limit=100"));
686     ASSERT_TRUE(s.is_valid());
687   }
688
689   // Create and insert statements should fail, while the same queries as unique
690   // statement succeeds.
691   {
692     Statement s(db_->GetReadonlyStatement(
693         "CREATE TABLE IF NOT EXISTS foo (id INTEGER PRIMARY KEY, value)"));
694     ASSERT_FALSE(s.is_valid());
695     Statement s1(db_->GetUniqueStatement(
696         "CREATE TABLE IF NOT EXISTS foo (id INTEGER PRIMARY KEY, value)"));
697     ASSERT_TRUE(s1.is_valid());
698   }
699   {
700     Statement s(
701         db_->GetReadonlyStatement("INSERT INTO foo (value) VALUES (12)"));
702     ASSERT_FALSE(s.is_valid());
703     Statement s1(
704         db_->GetUniqueStatement("INSERT INTO foo (value) VALUES (12)"));
705     ASSERT_TRUE(s1.is_valid());
706   }
707   {
708     Statement s(
709         db_->GetReadonlyStatement("CREATE VIRTUAL TABLE bar USING module"));
710     ASSERT_FALSE(s.is_valid());
711     Statement s1(
712         db_->GetUniqueStatement("CREATE VIRTUAL TABLE bar USING module"));
713     ASSERT_TRUE(s1.is_valid());
714   }
715
716   // Select statement is successful.
717   {
718     Statement s(db_->GetReadonlyStatement("SELECT * FROM foo"));
719     ASSERT_TRUE(s.Step());
720     EXPECT_EQ(s.ColumnInt(1), 12);
721   }
722 }
723
724 TEST_P(SQLDatabaseTest, IsSQLValid_NoContents) {
725   EXPECT_DCHECK_DEATH(db_->IsSQLValid("")) << "Empty string";
726   EXPECT_DCHECK_DEATH(db_->IsSQLValid(" ")) << "Space";
727   EXPECT_DCHECK_DEATH(db_->IsSQLValid("\n")) << "Newline";
728   EXPECT_DCHECK_DEATH(db_->IsSQLValid("-- Comment")) << "Comment";
729 }
730
731 // Test that Database::Raze() results in a database without the
732 // tables from the original database.
733 TEST_P(SQLDatabaseTest, Raze) {
734   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
735   ASSERT_TRUE(db_->Execute(kCreateSql));
736   ASSERT_TRUE(db_->Execute("INSERT INTO foo (value) VALUES (12)"));
737
738   int pragma_auto_vacuum = 0;
739   {
740     Statement s(db_->GetUniqueStatement("PRAGMA auto_vacuum"));
741     ASSERT_TRUE(s.Step());
742     pragma_auto_vacuum = s.ColumnInt(0);
743     ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
744   }
745
746   // If auto_vacuum is set, there's an extra page to maintain a freelist.
747   const int kExpectedPageCount = 2 + pragma_auto_vacuum;
748
749   {
750     Statement s(db_->GetUniqueStatement("PRAGMA page_count"));
751     ASSERT_TRUE(s.Step());
752     EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
753   }
754
755   {
756     Statement s(db_->GetUniqueStatement("SELECT * FROM sqlite_schema"));
757     ASSERT_TRUE(s.Step());
758     EXPECT_EQ("table", s.ColumnString(0));
759     EXPECT_EQ("foo", s.ColumnString(1));
760     EXPECT_EQ("foo", s.ColumnString(2));
761     // Table "foo" is stored in the last page of the file.
762     EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3));
763     EXPECT_EQ(kCreateSql, s.ColumnString(4));
764   }
765
766   ASSERT_TRUE(db_->Raze());
767
768   {
769     Statement s(db_->GetUniqueStatement("PRAGMA page_count"));
770     ASSERT_TRUE(s.Step());
771     EXPECT_EQ(1, s.ColumnInt(0));
772   }
773
774   ASSERT_EQ(0, SqliteSchemaCount(db_.get()));
775
776   {
777     Statement s(db_->GetUniqueStatement("PRAGMA auto_vacuum"));
778     ASSERT_TRUE(s.Step());
779     // The new database has the same auto_vacuum as a fresh database.
780     EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
781   }
782 }
783
784 TEST_P(SQLDatabaseTest, RazeDuringSelect) {
785   ASSERT_TRUE(
786       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
787   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(1)"));
788   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(2)"));
789
790   {
791     // SELECT implicitly creates a transaction while it's executing. This
792     // implicit transaction will not be caught by Raze()'s checks.
793     Statement select(db_->GetUniqueStatement("SELECT id FROM rows"));
794     ASSERT_TRUE(select.Step());
795     EXPECT_FALSE(db_->Raze()) << "Raze() should fail while SELECT is executing";
796   }
797
798   {
799     Statement count(db_->GetUniqueStatement("SELECT COUNT(*) FROM rows"));
800     ASSERT_TRUE(count.Step());
801     EXPECT_EQ(2, count.ColumnInt(0)) << "Raze() deleted some data";
802   }
803 }
804
805 // Helper for SQLDatabaseTest.RazePageSize.  Creates a fresh db based on
806 // db_prefix, with the given initial page size, and verifies it against the
807 // expected size.  Then changes to the final page size and razes, verifying that
808 // the fresh database ends up with the expected final page size.
809 void TestPageSize(const base::FilePath& db_prefix,
810                   int initial_page_size,
811                   const std::string& expected_initial_page_size,
812                   int final_page_size,
813                   const std::string& expected_final_page_size) {
814   static const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
815   static const char kInsertSql1[] = "INSERT INTO x VALUES ('This is a test')";
816   static const char kInsertSql2[] = "INSERT INTO x VALUES ('That was a test')";
817
818   const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
819       base::NumberToString(initial_page_size));
820   Database::Delete(db_path);
821   Database db({.page_size = initial_page_size});
822   ASSERT_TRUE(db.Open(db_path));
823   ASSERT_TRUE(db.Execute(kCreateSql));
824   ASSERT_TRUE(db.Execute(kInsertSql1));
825   ASSERT_TRUE(db.Execute(kInsertSql2));
826   ASSERT_EQ(expected_initial_page_size,
827             ExecuteWithResult(&db, "PRAGMA page_size"));
828   db.Close();
829
830   // Re-open the database while setting a new |options.page_size| in the object.
831   Database razed_db({.page_size = final_page_size});
832   ASSERT_TRUE(razed_db.Open(db_path));
833   // Raze will use the page size set in the connection object, which may not
834   // match the file's page size.
835   ASSERT_TRUE(razed_db.Raze());
836
837   // SQLite 3.10.2 (at least) has a quirk with the sqlite3_backup() API (used by
838   // Raze()) which causes the destination database to remember the previous
839   // page_size, even if the overwriting database changed the page_size.  Access
840   // the actual database to cause the cached value to be updated.
841   EXPECT_EQ("0",
842             ExecuteWithResult(&razed_db, "SELECT COUNT(*) FROM sqlite_schema"));
843
844   EXPECT_EQ(expected_final_page_size,
845             ExecuteWithResult(&razed_db, "PRAGMA page_size"));
846   EXPECT_EQ("1", ExecuteWithResult(&razed_db, "PRAGMA page_count"));
847 }
848
849 // Verify that Recovery maintains the page size, and the virtual table
850 // works with page sizes other than SQLite's default.  Also verify the case
851 // where the default page size has changed.
852 TEST_P(SQLDatabaseTest, RazePageSize) {
853   const std::string default_page_size =
854       ExecuteWithResult(db_.get(), "PRAGMA page_size");
855
856   // Sync uses 32k pages.
857   EXPECT_NO_FATAL_FAILURE(
858       TestPageSize(db_path_, 32768, "32768", 32768, "32768"));
859
860   // Many clients use 4k pages.  This is the SQLite default after 3.12.0.
861   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 4096, "4096", 4096, "4096"));
862
863   // 1k is the default page size before 3.12.0.
864   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 1024, "1024", 1024, "1024"));
865
866   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 2048, "2048", 4096, "4096"));
867
868   // Databases with no page size specified should result in the default
869   // page size.  2k has never been the default page size.
870   ASSERT_NE("2048", default_page_size);
871   EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 2048, "2048",
872                                        DatabaseOptions::kDefaultPageSize,
873                                        default_page_size));
874 }
875
876 // Test that Raze() results are seen in other connections.
877 TEST_P(SQLDatabaseTest, RazeMultiple) {
878   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
879   ASSERT_TRUE(db_->Execute(kCreateSql));
880
881   Database other_db(GetDBOptions());
882   ASSERT_TRUE(other_db.Open(db_path_));
883
884   // Check that the second connection sees the table.
885   ASSERT_EQ(1, SqliteSchemaCount(&other_db));
886
887   ASSERT_TRUE(db_->Raze());
888
889   // The second connection sees the updated database.
890   ASSERT_EQ(0, SqliteSchemaCount(&other_db));
891 }
892
893 TEST_P(SQLDatabaseTest, Raze_OtherConnectionHasWriteLock) {
894   ASSERT_TRUE(db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY)"));
895
896   Database other_db(GetDBOptions());
897   ASSERT_TRUE(other_db.Open(db_path_));
898
899   Transaction other_db_transaction(&other_db);
900   ASSERT_TRUE(other_db_transaction.Begin());
901   ASSERT_TRUE(other_db.Execute("INSERT INTO rows(id) VALUES(1)"));
902
903   EXPECT_FALSE(db_->Raze())
904       << "Raze() should fail while another connection has a write lock";
905
906   ASSERT_TRUE(other_db_transaction.Commit());
907   EXPECT_TRUE(db_->Raze())
908       << "Raze() should succeed after the other connection releases the lock";
909 }
910
911 TEST_P(SQLDatabaseTest, Raze_OtherConnectionHasReadLock) {
912   ASSERT_TRUE(db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY)"));
913   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(1)"));
914
915   if (IsWALEnabled()) {
916     // In WAL mode, read transactions in other connections do not block a write
917     // transaction.
918     return;
919   }
920
921   Database other_db(GetDBOptions());
922   ASSERT_TRUE(other_db.Open(db_path_));
923
924   Statement select(other_db.GetUniqueStatement("SELECT id FROM rows"));
925   ASSERT_TRUE(select.Step());
926   EXPECT_FALSE(db_->Raze())
927       << "Raze() should fail while another connection has a read lock";
928
929   ASSERT_FALSE(select.Step())
930       << "The SELECT statement should not produce more than one row";
931   EXPECT_TRUE(db_->Raze())
932       << "Raze() should succeed after the other connection releases the lock";
933 }
934
935 TEST_P(SQLDatabaseTest, Raze_EmptyDatabaseFile) {
936   ASSERT_TRUE(
937       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
938   db_->Close();
939
940   ASSERT_TRUE(TruncateDatabase());
941   ASSERT_TRUE(db_->Open(db_path_))
942       << "Failed to reopen database after truncating";
943
944   EXPECT_TRUE(db_->Raze()) << "Raze() failed on an empty file";
945   EXPECT_TRUE(
946       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
947       << "Raze() did not produce a healthy empty database";
948 }
949
950 // Verify that Raze() can handle a file of junk.
951 // Need exclusive mode off here as there are some subtleties (by design) around
952 // how the cache is used with it on which causes the test to fail.
953 TEST_P(SQLDatabaseTest, RazeNOTADB) {
954   db_->Close();
955   Database::Delete(db_path_);
956   ASSERT_FALSE(base::PathExists(db_path_));
957
958   ASSERT_TRUE(OverwriteDatabaseHeader(OverwriteType::kTruncate));
959   ASSERT_TRUE(base::PathExists(db_path_));
960
961   // SQLite will successfully open the handle, but fail when running PRAGMA
962   // statements that access the database.
963   {
964     sql::test::ScopedErrorExpecter expecter;
965     expecter.ExpectError(SQLITE_NOTADB);
966
967     EXPECT_TRUE(db_->Open(db_path_));
968     ASSERT_TRUE(expecter.SawExpectedErrors());
969   }
970   EXPECT_TRUE(db_->Raze());
971   db_->Close();
972
973   // Now empty, the open should open an empty database.
974   EXPECT_TRUE(db_->Open(db_path_));
975   EXPECT_EQ(0, SqliteSchemaCount(db_.get()));
976 }
977
978 // Verify that Raze() can handle a database overwritten with garbage.
979 TEST_P(SQLDatabaseTest, RazeNOTADB2) {
980   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
981   ASSERT_TRUE(db_->Execute(kCreateSql));
982   ASSERT_EQ(1, SqliteSchemaCount(db_.get()));
983   db_->Close();
984
985   ASSERT_TRUE(OverwriteDatabaseHeader(OverwriteType::kOverwrite));
986
987   // SQLite will successfully open the handle, but will fail with
988   // SQLITE_NOTADB on pragma statemenets which attempt to read the
989   // corrupted header.
990   {
991     sql::test::ScopedErrorExpecter expecter;
992     expecter.ExpectError(SQLITE_NOTADB);
993     EXPECT_TRUE(db_->Open(db_path_));
994     ASSERT_TRUE(expecter.SawExpectedErrors());
995   }
996   EXPECT_TRUE(db_->Raze());
997   db_->Close();
998
999   // Now empty, the open should succeed with an empty database.
1000   EXPECT_TRUE(db_->Open(db_path_));
1001   EXPECT_EQ(0, SqliteSchemaCount(db_.get()));
1002 }
1003
1004 // Test that a callback from Open() can raze the database.  This is
1005 // essential for cases where the Open() can fail entirely, so the
1006 // Raze() cannot happen later.  Additionally test that when the
1007 // callback does this during Open(), the open is retried and succeeds.
1008 TEST_P(SQLDatabaseTest, RazeCallbackReopen) {
1009   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1010   ASSERT_TRUE(db_->Execute(kCreateSql));
1011   ASSERT_EQ(1, SqliteSchemaCount(db_.get()));
1012   db_->Close();
1013
1014   // Corrupt the database so that nothing works, including PRAGMAs.
1015   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
1016
1017   // Open() will succeed, even though the PRAGMA calls within will
1018   // fail with SQLITE_CORRUPT, as will this PRAGMA.
1019   {
1020     sql::test::ScopedErrorExpecter expecter;
1021     expecter.ExpectError(SQLITE_CORRUPT);
1022     ASSERT_TRUE(db_->Open(db_path_));
1023     ASSERT_FALSE(db_->Execute("PRAGMA auto_vacuum"));
1024     db_->Close();
1025     ASSERT_TRUE(expecter.SawExpectedErrors());
1026   }
1027
1028   db_->set_error_callback(
1029       base::BindRepeating(&RazeErrorCallback, db_.get(), SQLITE_CORRUPT));
1030
1031   // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
1032   // callback will call RazeAndClose().  Open() will then fail and be
1033   // retried.  The second Open() on the empty database will succeed
1034   // cleanly.
1035   ASSERT_TRUE(db_->Open(db_path_));
1036   ASSERT_TRUE(db_->Execute("PRAGMA auto_vacuum"));
1037   EXPECT_EQ(0, SqliteSchemaCount(db_.get()));
1038 }
1039
1040 TEST_P(SQLDatabaseTest, RazeAndClose_DeletesData) {
1041   ASSERT_TRUE(
1042       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1043   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(12)"));
1044   ASSERT_TRUE(db_->RazeAndClose());
1045
1046   // RazeAndClose() actually Poison()s. We need to call Close() in order to
1047   // re-Open(). crbug.com/1311771 tracks renaming RazeAndClose().
1048   db_->Close();
1049   ASSERT_TRUE(db_->Open(db_path_))
1050       << "RazeAndClose() did not produce a healthy database";
1051   EXPECT_TRUE(
1052       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
1053       << "RazeAndClose() did not produce a healthy empty database";
1054 }
1055
1056 TEST_P(SQLDatabaseTest, RazeAndClose_IsOpen) {
1057   ASSERT_TRUE(
1058       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1059   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(12)"));
1060   ASSERT_TRUE(db_->RazeAndClose());
1061
1062   EXPECT_FALSE(db_->is_open())
1063       << "RazeAndClose() did not mark the database as closed";
1064 }
1065
1066 TEST_P(SQLDatabaseTest, RazeAndClose_Reopen_NoChanges) {
1067   ASSERT_TRUE(db_->RazeAndClose());
1068   EXPECT_FALSE(
1069       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
1070       << "Execute() should return false after RazeAndClose()";
1071
1072   // RazeAndClose() actually Poison()s. We need to call Close() in order to
1073   // re-Open(). crbug.com/1311771 tracks renaming RazeAndClose().
1074   db_->Close();
1075   ASSERT_TRUE(db_->Open(db_path_))
1076       << "RazeAndClose() did not produce a healthy database";
1077   EXPECT_TRUE(
1078       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
1079       << "Execute() returned false but went through after RazeAndClose()";
1080 }
1081
1082 TEST_P(SQLDatabaseTest, RazeAndClose_OpenTransaction) {
1083   ASSERT_TRUE(
1084       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1085   ASSERT_TRUE(db_->Execute("INSERT INTO rows(id) VALUES(12)"));
1086
1087   Transaction transaction(db_.get());
1088   ASSERT_TRUE(transaction.Begin());
1089   ASSERT_TRUE(db_->RazeAndClose());
1090
1091   EXPECT_FALSE(db_->is_open())
1092       << "RazeAndClose() did not mark the database as closed";
1093   EXPECT_FALSE(transaction.Commit())
1094       << "RazeAndClose() did not cancel the transaction";
1095
1096   // RazeAndClose() actually Poison()s. We need to call Close() in order to
1097   // re-Open(). crbug.com/1311771 tracks renaming RazeAndClose().
1098   db_->Close();
1099
1100   ASSERT_TRUE(db_->Open(db_path_));
1101   EXPECT_TRUE(
1102       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
1103       << "RazeAndClose() did not produce a healthy empty database";
1104 }
1105
1106 TEST_P(SQLDatabaseTest, RazeAndClose_Preload_NoCrash) {
1107   db_->Preload();
1108   db_->RazeAndClose();
1109   db_->Preload();
1110 }
1111
1112 TEST_P(SQLDatabaseTest, RazeAndClose_DoesTableExist) {
1113   ASSERT_TRUE(
1114       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1115   ASSERT_TRUE(db_->DoesTableExist("rows")) << "Incorrect test setup";
1116
1117   ASSERT_TRUE(db_->RazeAndClose());
1118   EXPECT_FALSE(db_->DoesTableExist("rows"))
1119       << "DoesTableExist() should return false after RazeAndClose()";
1120 }
1121
1122 TEST_P(SQLDatabaseTest, RazeAndClose_IsSQLValid) {
1123   ASSERT_TRUE(db_->IsSQLValid("SELECT 1")) << "Incorrect test setup";
1124
1125   ASSERT_TRUE(db_->RazeAndClose());
1126   EXPECT_FALSE(db_->IsSQLValid("SELECT 1"))
1127       << "IsSQLValid() should return false after RazeAndClose()";
1128 }
1129
1130 TEST_P(SQLDatabaseTest, RazeAndClose_Execute) {
1131   ASSERT_TRUE(db_->Execute("SELECT 1")) << "Incorrect test setup";
1132
1133   ASSERT_TRUE(db_->RazeAndClose());
1134   EXPECT_FALSE(db_->Execute("SELECT 1"))
1135       << "Execute() should return false after RazeAndClose()";
1136 }
1137
1138 TEST_P(SQLDatabaseTest, RazeAndClose_GetUniqueStatement) {
1139   {
1140     Statement select(db_->GetUniqueStatement("SELECT 1"));
1141     ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1142   }
1143
1144   ASSERT_TRUE(db_->RazeAndClose());
1145   {
1146     Statement select(db_->GetUniqueStatement("SELECT 1"));
1147     EXPECT_FALSE(select.Step())
1148         << "GetUniqueStatement() should return an invalid Statement after "
1149         << "RazeAndClose()";
1150   }
1151 }
1152
1153 TEST_P(SQLDatabaseTest, RazeAndClose_GetCachedStatement) {
1154   {
1155     Statement select(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
1156     ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1157   }
1158
1159   ASSERT_TRUE(db_->RazeAndClose());
1160   {
1161     Statement select(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
1162     EXPECT_FALSE(select.Step())
1163         << "GetCachedStatement() should return an invalid Statement after "
1164         << "RazeAndClose()";
1165   }
1166 }
1167
1168 TEST_P(SQLDatabaseTest, RazeAndClose_InvalidatesUniqueStatement) {
1169   Statement select(db_->GetUniqueStatement("SELECT 1"));
1170   ASSERT_TRUE(select.is_valid()) << "Incorrect test setup";
1171   ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1172   select.Reset(/*clear_bound_vars=*/true);
1173
1174   ASSERT_TRUE(db_->RazeAndClose());
1175   EXPECT_FALSE(select.is_valid())
1176       << "RazeAndClose() should invalidate live Statements";
1177   EXPECT_FALSE(select.Step())
1178       << "RazeAndClose() should invalidate live Statements";
1179 }
1180
1181 TEST_P(SQLDatabaseTest, RazeAndClose_InvalidatesCachedStatement) {
1182   Statement select(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
1183   ASSERT_TRUE(select.is_valid()) << "Incorrect test setup";
1184   ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1185   select.Reset(/*clear_bound_vars=*/true);
1186
1187   ASSERT_TRUE(db_->RazeAndClose());
1188   EXPECT_FALSE(select.is_valid())
1189       << "RazeAndClose() should invalidate live Statements";
1190   EXPECT_FALSE(select.Step())
1191       << "RazeAndClose() should invalidate live Statements";
1192 }
1193
1194 TEST_P(SQLDatabaseTest, RazeAndClose_TransactionBegin) {
1195   {
1196     Transaction transaction(db_.get());
1197     ASSERT_TRUE(transaction.Begin()) << "Incorrect test setup";
1198     ASSERT_TRUE(transaction.Commit()) << "Incorrect test setup";
1199   }
1200
1201   ASSERT_TRUE(db_->RazeAndClose());
1202   {
1203     Transaction transaction(db_.get());
1204     EXPECT_FALSE(transaction.Begin())
1205         << "Transaction::Begin() should return false after RazeAndClose()";
1206     EXPECT_FALSE(transaction.IsActiveForTesting())
1207         << "RazeAndClose() should block transactions from starting";
1208   }
1209 }
1210
1211 TEST_P(SQLDatabaseTest, Close_IsSQLValid) {
1212   ASSERT_TRUE(db_->IsSQLValid("SELECT 1")) << "Incorrect test setup";
1213
1214   db_->Close();
1215
1216   EXPECT_DCHECK_DEATH_WITH({ std::ignore = db_->IsSQLValid("SELECT 1"); },
1217                            "Illegal use of Database without a db");
1218 }
1219
1220 // On Windows, truncate silently fails against a memory-mapped file.  One goal
1221 // of Raze() is to truncate the file to remove blocks which generate I/O errors.
1222 // Test that Raze() turns off memory mapping so that the file is truncated.
1223 // [This would not cover the case of multiple connections where one of the other
1224 // connections is memory-mapped.  That is infrequent in Chromium.]
1225 TEST_P(SQLDatabaseTest, RazeTruncate) {
1226   // The empty database has 0 or 1 pages.  Raze() should leave it with exactly 1
1227   // page.  Not checking directly because auto_vacuum on Android adds a freelist
1228   // page.
1229   ASSERT_TRUE(db_->Raze());
1230   int64_t expected_size;
1231   ASSERT_TRUE(base::GetFileSize(db_path_, &expected_size));
1232   ASSERT_GT(expected_size, 0);
1233
1234   // Cause the database to take a few pages.
1235   const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1236   ASSERT_TRUE(db_->Execute(kCreateSql));
1237   for (size_t i = 0; i < 24; ++i) {
1238     ASSERT_TRUE(
1239         db_->Execute("INSERT INTO foo (value) VALUES (randomblob(1024))"));
1240   }
1241
1242   // In WAL mode, writes don't reach the database file until a checkpoint
1243   // happens.
1244   ASSERT_TRUE(db_->CheckpointDatabase());
1245
1246   int64_t db_size;
1247   ASSERT_TRUE(base::GetFileSize(db_path_, &db_size));
1248   ASSERT_GT(db_size, expected_size);
1249
1250   // Make a query covering most of the database file to make sure that the
1251   // blocks are actually mapped into memory.  Empirically, the truncate problem
1252   // doesn't seem to happen if no blocks are mapped.
1253   EXPECT_EQ("24576",
1254             ExecuteWithResult(db_.get(), "SELECT SUM(LENGTH(value)) FROM foo"));
1255
1256   ASSERT_TRUE(db_->Raze());
1257   ASSERT_TRUE(base::GetFileSize(db_path_, &db_size));
1258   ASSERT_EQ(expected_size, db_size);
1259 }
1260
1261 #if BUILDFLAG(IS_ANDROID)
1262 TEST_P(SQLDatabaseTest, SetTempDirForSQL) {
1263   MetaTable meta_table;
1264   // Below call needs a temporary directory in sqlite3
1265   // On Android, it can pass only when the temporary directory is set.
1266   // Otherwise, sqlite3 doesn't find the correct directory to store
1267   // temporary files and will report the error 'unable to open
1268   // database file'.
1269   ASSERT_TRUE(meta_table.Init(db_.get(), 4, 4));
1270 }
1271 #endif  // BUILDFLAG(IS_ANDROID)
1272
1273 TEST_P(SQLDatabaseTest, Delete) {
1274   EXPECT_TRUE(db_->Execute("CREATE TABLE x (x)"));
1275   db_->Close();
1276
1277   base::FilePath journal_path = Database::JournalPath(db_path_);
1278   base::FilePath wal_path = Database::WriteAheadLogPath(db_path_);
1279
1280   // Should have both a main database file and a journal file if
1281   // journal_mode is TRUNCATE. There is no WAL file as it is deleted on Close.
1282   ASSERT_TRUE(base::PathExists(db_path_));
1283   if (!IsWALEnabled()) {  // TRUNCATE mode
1284     ASSERT_TRUE(base::PathExists(journal_path));
1285   }
1286
1287   Database::Delete(db_path_);
1288   EXPECT_FALSE(base::PathExists(db_path_));
1289   EXPECT_FALSE(base::PathExists(journal_path));
1290   EXPECT_FALSE(base::PathExists(wal_path));
1291 }
1292
1293 #if BUILDFLAG(IS_POSIX)  // This test operates on POSIX file permissions.
1294 TEST_P(SQLDatabaseTest, PosixFilePermissions) {
1295   db_->Close();
1296   Database::Delete(db_path_);
1297   ASSERT_FALSE(base::PathExists(db_path_));
1298
1299   // If the bots all had a restrictive umask setting such that databases are
1300   // always created with only the owner able to read them, then the code could
1301   // break without breaking the tests. Temporarily provide a more permissive
1302   // umask.
1303   ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
1304
1305   ASSERT_TRUE(db_->Open(db_path_));
1306
1307   // Cause the journal file to be created. If the default journal_mode is
1308   // changed back to DELETE, this test will need to be updated.
1309   EXPECT_TRUE(db_->Execute("CREATE TABLE x (x)"));
1310
1311   int mode;
1312   ASSERT_TRUE(base::PathExists(db_path_));
1313   EXPECT_TRUE(base::GetPosixFilePermissions(db_path_, &mode));
1314   ASSERT_EQ(mode, 0600);
1315
1316   if (IsWALEnabled()) {  // WAL mode
1317     // The WAL file is created lazily on first change.
1318     ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
1319
1320     base::FilePath wal_path = Database::WriteAheadLogPath(db_path_);
1321     ASSERT_TRUE(base::PathExists(wal_path));
1322     EXPECT_TRUE(base::GetPosixFilePermissions(wal_path, &mode));
1323     ASSERT_EQ(mode, 0600);
1324
1325     // The shm file doesn't exist in exclusive locking mode.
1326     if (ExecuteWithResult(db_.get(), "PRAGMA locking_mode") == "normal") {
1327       base::FilePath shm_path = Database::SharedMemoryFilePath(db_path_);
1328       ASSERT_TRUE(base::PathExists(shm_path));
1329       EXPECT_TRUE(base::GetPosixFilePermissions(shm_path, &mode));
1330       ASSERT_EQ(mode, 0600);
1331     }
1332   } else {  // Truncate mode
1333     base::FilePath journal_path = Database::JournalPath(db_path_);
1334     DLOG(ERROR) << "journal_path: " << journal_path;
1335     ASSERT_TRUE(base::PathExists(journal_path));
1336     EXPECT_TRUE(base::GetPosixFilePermissions(journal_path, &mode));
1337     ASSERT_EQ(mode, 0600);
1338   }
1339 }
1340 #endif  // BUILDFLAG(IS_POSIX)
1341
1342 TEST_P(SQLDatabaseTest, Poison_IsOpen) {
1343   db_->Poison();
1344   EXPECT_FALSE(db_->is_open())
1345       << "Poison() did not mark the database as closed";
1346 }
1347
1348 TEST_P(SQLDatabaseTest, Poison_Close_Reopen_NoChanges) {
1349   db_->Poison();
1350   EXPECT_FALSE(
1351       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
1352       << "Execute() should return false after Poison()";
1353
1354   db_->Close();
1355   ASSERT_TRUE(db_->Open(db_path_)) << "Poison() damaged the database";
1356   EXPECT_TRUE(
1357       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"))
1358       << "Execute() returned false but went through after Poison()";
1359 }
1360
1361 TEST_P(SQLDatabaseTest, Poison_Preload_NoCrash) {
1362   db_->Preload();
1363   db_->Poison();
1364   db_->Preload();
1365 }
1366
1367 TEST_P(SQLDatabaseTest, Poison_DoesTableExist) {
1368   ASSERT_TRUE(
1369       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1370   ASSERT_TRUE(db_->DoesTableExist("rows")) << "Incorrect test setup";
1371
1372   db_->Poison();
1373   EXPECT_FALSE(db_->DoesTableExist("rows"))
1374       << "DoesTableExist() should return false after Poison()";
1375 }
1376
1377 TEST_P(SQLDatabaseTest, Poison_IsSQLValid) {
1378   ASSERT_TRUE(db_->IsSQLValid("SELECT 1")) << "Incorrect test setup";
1379
1380   db_->Poison();
1381   EXPECT_FALSE(db_->IsSQLValid("SELECT 1"))
1382       << "IsSQLValid() should return false after Poison()";
1383 }
1384
1385 TEST_P(SQLDatabaseTest, Poison_Execute) {
1386   ASSERT_TRUE(db_->Execute("SELECT 1")) << "Incorrect test setup";
1387
1388   db_->Poison();
1389   EXPECT_FALSE(db_->Execute("SELECT 1"))
1390       << "Execute() should return false after Poison()";
1391 }
1392
1393 TEST_P(SQLDatabaseTest, Poison_GetUniqueStatement) {
1394   {
1395     Statement select(db_->GetUniqueStatement("SELECT 1"));
1396     ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1397   }
1398
1399   db_->Poison();
1400   {
1401     Statement select(db_->GetUniqueStatement("SELECT 1"));
1402     EXPECT_FALSE(select.Step())
1403         << "GetUniqueStatement() should return an invalid Statement after "
1404         << "Poison()";
1405   }
1406 }
1407
1408 TEST_P(SQLDatabaseTest, Poison_GetCachedStatement) {
1409   {
1410     Statement select(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
1411     ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1412   }
1413
1414   db_->Poison();
1415   {
1416     Statement select(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
1417     EXPECT_FALSE(select.Step())
1418         << "GetCachedStatement() should return an invalid Statement after "
1419         << "Poison()";
1420   }
1421 }
1422
1423 TEST_P(SQLDatabaseTest, Poison_InvalidatesUniqueStatement) {
1424   Statement select(db_->GetUniqueStatement("SELECT 1"));
1425   ASSERT_TRUE(select.is_valid()) << "Incorrect test setup";
1426   ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1427   select.Reset(/*clear_bound_vars=*/true);
1428
1429   db_->Poison();
1430   EXPECT_FALSE(select.is_valid())
1431       << "Poison() should invalidate live Statements";
1432   EXPECT_FALSE(select.Step()) << "Poison() should invalidate live Statements";
1433 }
1434
1435 TEST_P(SQLDatabaseTest, Poison_InvalidatesCachedStatement) {
1436   Statement select(db_->GetCachedStatement(SQL_FROM_HERE, "SELECT 1"));
1437   ASSERT_TRUE(select.is_valid()) << "Incorrect test setup";
1438   ASSERT_TRUE(select.Step()) << "Incorrect test setup";
1439   select.Reset(/*clear_bound_vars=*/true);
1440
1441   db_->Poison();
1442   EXPECT_FALSE(select.is_valid())
1443       << "Poison() should invalidate live Statements";
1444   EXPECT_FALSE(select.Step()) << "Poison() should invalidate live Statements";
1445 }
1446
1447 TEST_P(SQLDatabaseTest, Poison_TransactionBegin) {
1448   {
1449     Transaction transaction(db_.get());
1450     ASSERT_TRUE(transaction.Begin()) << "Incorrect test setup";
1451     ASSERT_TRUE(transaction.Commit()) << "Incorrect test setup";
1452   }
1453
1454   db_->Poison();
1455   {
1456     Transaction transaction(db_.get());
1457     EXPECT_FALSE(transaction.Begin())
1458         << "Transaction::Begin() should return false after Poison()";
1459     EXPECT_FALSE(transaction.IsActiveForTesting())
1460         << "Poison() should block transactions from starting";
1461   }
1462 }
1463
1464 TEST_P(SQLDatabaseTest, Poison_OpenTransaction) {
1465   Transaction transaction(db_.get());
1466   ASSERT_TRUE(transaction.Begin());
1467
1468   db_->Poison();
1469   EXPECT_FALSE(transaction.Commit())
1470       << "Poison() did not cancel the transaction";
1471 }
1472
1473 TEST_P(SQLDatabaseTest, AttachDatabase) {
1474   ASSERT_TRUE(
1475       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1476
1477   // Create a database to attach to.
1478   base::FilePath attach_path =
1479       db_path_.DirName().AppendASCII("attach_database_test.db");
1480   static constexpr char kAttachmentPoint[] = "other";
1481   {
1482     Database other_db;
1483     ASSERT_TRUE(other_db.Open(attach_path));
1484     ASSERT_TRUE(
1485         other_db.Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1486     ASSERT_TRUE(other_db.Execute("INSERT INTO rows VALUES(42)"));
1487   }
1488
1489   // Cannot see the attached database, yet.
1490   EXPECT_FALSE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1491
1492   EXPECT_TRUE(DatabaseTestPeer::AttachDatabase(db_.get(), attach_path,
1493                                                kAttachmentPoint));
1494   EXPECT_TRUE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1495
1496   // Queries can touch both databases after the ATTACH.
1497   EXPECT_TRUE(db_->Execute("INSERT INTO rows SELECT id FROM other.rows"));
1498   {
1499     Statement select(db_->GetUniqueStatement("SELECT COUNT(*) FROM rows"));
1500     ASSERT_TRUE(select.Step());
1501     EXPECT_EQ(1, select.ColumnInt(0));
1502   }
1503
1504   EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(db_.get(), kAttachmentPoint));
1505   EXPECT_FALSE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1506 }
1507
1508 TEST_P(SQLDatabaseTest, AttachDatabaseWithOpenTransaction) {
1509   ASSERT_TRUE(
1510       db_->Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1511
1512   // Create a database to attach to.
1513   base::FilePath attach_path =
1514       db_path_.DirName().AppendASCII("attach_database_test.db");
1515   static constexpr char kAttachmentPoint[] = "other";
1516   {
1517     Database other_db;
1518     ASSERT_TRUE(other_db.Open(attach_path));
1519     ASSERT_TRUE(
1520         other_db.Execute("CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL)"));
1521     ASSERT_TRUE(other_db.Execute("INSERT INTO rows VALUES(42)"));
1522   }
1523
1524   // Cannot see the attached database, yet.
1525   EXPECT_FALSE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1526
1527   // Attach succeeds in a transaction.
1528   Transaction transaction(db_.get());
1529   EXPECT_TRUE(transaction.Begin());
1530   EXPECT_TRUE(DatabaseTestPeer::AttachDatabase(db_.get(), attach_path,
1531                                                kAttachmentPoint));
1532   EXPECT_TRUE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1533
1534   // Queries can touch both databases after the ATTACH.
1535   EXPECT_TRUE(db_->Execute("INSERT INTO rows SELECT id FROM other.rows"));
1536   {
1537     Statement select(db_->GetUniqueStatement("SELECT COUNT(*) FROM rows"));
1538     ASSERT_TRUE(select.Step());
1539     EXPECT_EQ(1, select.ColumnInt(0));
1540   }
1541
1542   // Detaching the same database fails, database is locked in the transaction.
1543   {
1544     sql::test::ScopedErrorExpecter expecter;
1545     expecter.ExpectError(SQLITE_ERROR);
1546     EXPECT_FALSE(DatabaseTestPeer::DetachDatabase(db_.get(), kAttachmentPoint));
1547     ASSERT_TRUE(expecter.SawExpectedErrors());
1548   }
1549   EXPECT_TRUE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1550
1551   // Detach succeeds when the transaction is closed.
1552   transaction.Rollback();
1553   EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(db_.get(), kAttachmentPoint));
1554   EXPECT_FALSE(db_->IsSQLValid("SELECT COUNT(*) from other.rows"));
1555 }
1556
1557 TEST_P(SQLDatabaseTest, FullIntegrityCheck) {
1558   static constexpr char kTableSql[] =
1559       "CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL, value TEXT NOT NULL)";
1560   ASSERT_TRUE(db_->Execute(kTableSql));
1561   ASSERT_TRUE(db_->Execute("CREATE INDEX rows_by_value ON rows(value)"));
1562
1563   {
1564     std::vector<std::string> messages;
1565     EXPECT_TRUE(db_->FullIntegrityCheck(&messages))
1566         << "FullIntegrityCheck() failed before database was corrupted";
1567     EXPECT_THAT(messages, testing::ElementsAre("ok"))
1568         << "FullIntegrityCheck() should report ok before database is corrupted";
1569   }
1570
1571   db_->Close();
1572   ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_by_value"));
1573   ASSERT_TRUE(db_->Open(db_path_));
1574
1575   {
1576     std::vector<std::string> messages;
1577     EXPECT_TRUE(db_->FullIntegrityCheck(&messages))
1578         << "FullIntegrityCheck() failed on corrupted database";
1579     EXPECT_THAT(messages, testing::Not(testing::ElementsAre("ok")))
1580         << "FullIntegrityCheck() should not report ok for a corrupted database";
1581   }
1582 }
1583
1584 TEST_P(SQLDatabaseTest, OnMemoryDump) {
1585   base::trace_event::MemoryDumpArgs args = {
1586       base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
1587   base::trace_event::ProcessMemoryDump pmd(args);
1588   ASSERT_TRUE(db_->memory_dump_provider_->OnMemoryDump(args, &pmd));
1589   EXPECT_GE(pmd.allocator_dumps().size(), 1u);
1590 }
1591
1592 // Test that the functions to collect diagnostic data run to completion, without
1593 // worrying too much about what they generate (since that will change).
1594 TEST_P(SQLDatabaseTest, CollectDiagnosticInfo) {
1595   const std::string corruption_info = db_->CollectCorruptionInfo();
1596   EXPECT_NE(std::string::npos, corruption_info.find("SQLITE_CORRUPT"));
1597   EXPECT_NE(std::string::npos, corruption_info.find("integrity_check"));
1598
1599   // A statement to see in the results.
1600   const char* kSimpleSql = "SELECT 'mountain'";
1601   Statement s(db_->GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
1602
1603   // Error includes the statement.
1604   {
1605     DatabaseDiagnostics diagnostics;
1606     const std::string readonly_info =
1607         db_->CollectErrorInfo(SQLITE_READONLY, &s, &diagnostics);
1608     EXPECT_NE(std::string::npos, readonly_info.find(kSimpleSql));
1609     EXPECT_EQ(diagnostics.sql_statement, kSimpleSql);
1610   }
1611
1612   // Some other error doesn't include the statement.
1613   {
1614     DatabaseDiagnostics diagnostics;
1615     const std::string full_info =
1616         db_->CollectErrorInfo(SQLITE_FULL, nullptr, &diagnostics);
1617     EXPECT_EQ(std::string::npos, full_info.find(kSimpleSql));
1618     EXPECT_TRUE(diagnostics.sql_statement.empty());
1619   }
1620
1621   // A table to see in the SQLITE_ERROR results.
1622   EXPECT_TRUE(db_->Execute("CREATE TABLE volcano (x)"));
1623
1624   // Version info to see in the SQLITE_ERROR results.
1625   MetaTable meta_table;
1626   ASSERT_TRUE(meta_table.Init(db_.get(), 4, 4));
1627
1628   {
1629     DatabaseDiagnostics diagnostics;
1630     const std::string error_info =
1631         db_->CollectErrorInfo(SQLITE_ERROR, &s, &diagnostics);
1632     EXPECT_NE(std::string::npos, error_info.find(kSimpleSql));
1633     EXPECT_NE(std::string::npos, error_info.find("volcano"));
1634     EXPECT_NE(std::string::npos, error_info.find("version: 4"));
1635     EXPECT_EQ(diagnostics.sql_statement, kSimpleSql);
1636     EXPECT_EQ(diagnostics.version, 4);
1637
1638     ASSERT_EQ(diagnostics.schema_sql_rows.size(), 2U);
1639     EXPECT_EQ(diagnostics.schema_sql_rows[0], "CREATE TABLE volcano (x)");
1640     EXPECT_EQ(diagnostics.schema_sql_rows[1],
1641               "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, "
1642               "value LONGVARCHAR)");
1643
1644     ASSERT_EQ(diagnostics.schema_other_row_names.size(), 1U);
1645     EXPECT_EQ(diagnostics.schema_other_row_names[0], "sqlite_autoindex_meta_1");
1646   }
1647
1648   // Test that an error message is included in the diagnostics.
1649   {
1650     sql::test::ScopedErrorExpecter error_expecter;
1651     error_expecter.ExpectError(SQLITE_ERROR);
1652     EXPECT_FALSE(
1653         db_->Execute("INSERT INTO volcano VALUES ('bound_value1', 42, 1234)"));
1654     EXPECT_TRUE(error_expecter.SawExpectedErrors());
1655
1656     DatabaseDiagnostics diagnostics;
1657     const std::string error_info =
1658         db_->CollectErrorInfo(SQLITE_ERROR, &s, &diagnostics);
1659     // Expect that the error message contains the table name and a column error.
1660     EXPECT_NE(diagnostics.error_message.find("table"), std::string::npos);
1661     EXPECT_NE(diagnostics.error_message.find("volcano"), std::string::npos);
1662     EXPECT_NE(diagnostics.error_message.find("column"), std::string::npos);
1663
1664     // Expect that bound values are not present.
1665     EXPECT_EQ(diagnostics.error_message.find("bound_value1"),
1666               std::string::npos);
1667     EXPECT_EQ(diagnostics.error_message.find("42"), std::string::npos);
1668     EXPECT_EQ(diagnostics.error_message.find("1234"), std::string::npos);
1669   }
1670 }
1671
1672 // Test that a fresh database has mmap enabled by default, if mmap'ed I/O is
1673 // enabled by SQLite.
1674 TEST_P(SQLDatabaseTest, MmapInitiallyEnabled) {
1675   {
1676     Statement s(db_->GetUniqueStatement("PRAGMA mmap_size"));
1677     ASSERT_TRUE(s.Step())
1678         << "All supported SQLite versions should have mmap support";
1679
1680     // If mmap I/O is not on, attempt to turn it on.  If that succeeds, then
1681     // Open() should have turned it on.  If mmap support is disabled, 0 is
1682     // returned.  If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
1683     // instance MojoVFS), -1 is returned.
1684     if (s.ColumnInt(0) <= 0) {
1685       ASSERT_TRUE(db_->Execute("PRAGMA mmap_size = 1048576"));
1686       s.Reset(true);
1687       ASSERT_TRUE(s.Step());
1688       EXPECT_LE(s.ColumnInt(0), 0);
1689     }
1690   }
1691
1692   // Test that explicit disable prevents mmap'ed I/O.
1693   db_->Close();
1694   Database::Delete(db_path_);
1695   db_->set_mmap_disabled();
1696   ASSERT_TRUE(db_->Open(db_path_));
1697   EXPECT_EQ("0", ExecuteWithResult(db_.get(), "PRAGMA mmap_size"));
1698 }
1699
1700 // Test whether a fresh database gets mmap enabled when using alternate status
1701 // storage.
1702 TEST_P(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
1703   // Re-open fresh database with alt-status flag set.
1704   db_->Close();
1705   Database::Delete(db_path_);
1706
1707   DatabaseOptions options = GetDBOptions();
1708   options.mmap_alt_status_discouraged = true;
1709   options.enable_views_discouraged = true;
1710   db_ = std::make_unique<Database>(options);
1711   ASSERT_TRUE(db_->Open(db_path_));
1712
1713   {
1714     Statement s(db_->GetUniqueStatement("PRAGMA mmap_size"));
1715     ASSERT_TRUE(s.Step())
1716         << "All supported SQLite versions should have mmap support";
1717
1718     // If mmap I/O is not on, attempt to turn it on.  If that succeeds, then
1719     // Open() should have turned it on.  If mmap support is disabled, 0 is
1720     // returned.  If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
1721     // instance MojoVFS), -1 is returned.
1722     if (s.ColumnInt(0) <= 0) {
1723       ASSERT_TRUE(db_->Execute("PRAGMA mmap_size = 1048576"));
1724       s.Reset(true);
1725       ASSERT_TRUE(s.Step());
1726       EXPECT_LE(s.ColumnInt(0), 0);
1727     }
1728   }
1729
1730   // Test that explicit disable overrides set_mmap_alt_status().
1731   db_->Close();
1732   Database::Delete(db_path_);
1733   db_->set_mmap_disabled();
1734   ASSERT_TRUE(db_->Open(db_path_));
1735   EXPECT_EQ("0", ExecuteWithResult(db_.get(), "PRAGMA mmap_size"));
1736 }
1737
1738 TEST_P(SQLDatabaseTest, ComputeMmapSizeForOpen) {
1739   const size_t kMmapAlot = 25 * 1024 * 1024;
1740   int64_t mmap_status = MetaTable::kMmapFailure;
1741
1742   // If there is no meta table (as for a fresh database), assume that everything
1743   // should be mapped, and the status of the meta table is not affected.
1744   ASSERT_TRUE(!db_->DoesTableExist("meta"));
1745   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1746   ASSERT_TRUE(!db_->DoesTableExist("meta"));
1747
1748   // When the meta table is first created, it sets up to map everything.
1749   MetaTable().Init(db_.get(), 1, 1);
1750   ASSERT_TRUE(db_->DoesTableExist("meta"));
1751   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1752   ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
1753   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1754
1755   // Preload with partial progress of one page.  Should map everything.
1756   ASSERT_TRUE(db_->Execute("REPLACE INTO meta VALUES ('mmap_status', 1)"));
1757   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1758   ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
1759   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1760
1761   // Failure status maps nothing.
1762   ASSERT_TRUE(db_->Execute("REPLACE INTO meta VALUES ('mmap_status', -2)"));
1763   ASSERT_EQ(0UL, db_->ComputeMmapSizeForOpen());
1764
1765   // Re-initializing the meta table does not re-create the key if the table
1766   // already exists.
1767   ASSERT_TRUE(db_->Execute("DELETE FROM meta WHERE key = 'mmap_status'"));
1768   MetaTable().Init(db_.get(), 1, 1);
1769   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1770   ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
1771   ASSERT_EQ(0, mmap_status);
1772
1773   // With no key, map everything and create the key.
1774   // TODO(shess): This really should be "maps everything after validating it",
1775   // but that is more complicated to structure.
1776   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1777   ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
1778   ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
1779 }
1780
1781 TEST_P(SQLDatabaseTest, ComputeMmapSizeForOpenAltStatus) {
1782   const size_t kMmapAlot = 25 * 1024 * 1024;
1783
1784   // At this point, Database still expects a future [meta] table.
1785   ASSERT_FALSE(db_->DoesTableExist("meta"));
1786   ASSERT_FALSE(db_->DoesViewExist("MmapStatus"));
1787   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1788   ASSERT_FALSE(db_->DoesTableExist("meta"));
1789   ASSERT_FALSE(db_->DoesViewExist("MmapStatus"));
1790
1791   // Using alt status, everything should be mapped, with state in the view.
1792   DatabaseOptions options = GetDBOptions();
1793   options.mmap_alt_status_discouraged = true;
1794   options.enable_views_discouraged = true;
1795   db_ = std::make_unique<Database>(options);
1796   ASSERT_TRUE(db_->Open(db_path_));
1797
1798   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1799   ASSERT_FALSE(db_->DoesTableExist("meta"));
1800   ASSERT_TRUE(db_->DoesViewExist("MmapStatus"));
1801   EXPECT_EQ(base::NumberToString(MetaTable::kMmapSuccess),
1802             ExecuteWithResult(db_.get(), "SELECT * FROM MmapStatus"));
1803
1804   // Also maps everything when kMmapSuccess is already in the view.
1805   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1806
1807   // Preload with partial progress of one page.  Should map everything.
1808   ASSERT_TRUE(db_->Execute("DROP VIEW MmapStatus"));
1809   ASSERT_TRUE(db_->Execute("CREATE VIEW MmapStatus (value) AS SELECT 1"));
1810   ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot);
1811   EXPECT_EQ(base::NumberToString(MetaTable::kMmapSuccess),
1812             ExecuteWithResult(db_.get(), "SELECT * FROM MmapStatus"));
1813
1814   // Failure status leads to nothing being mapped.
1815   ASSERT_TRUE(db_->Execute("DROP VIEW MmapStatus"));
1816   ASSERT_TRUE(db_->Execute("CREATE VIEW MmapStatus (value) AS SELECT -2"));
1817   ASSERT_EQ(0UL, db_->ComputeMmapSizeForOpen());
1818   EXPECT_EQ(base::NumberToString(MetaTable::kMmapFailure),
1819             ExecuteWithResult(db_.get(), "SELECT * FROM MmapStatus"));
1820 }
1821
1822 TEST_P(SQLDatabaseTest, GetMemoryUsage) {
1823   // Databases with mmap enabled may not follow the assumptions below.
1824   db_->Close();
1825   db_->set_mmap_disabled();
1826   ASSERT_TRUE(db_->Open(db_path_));
1827
1828   int initial_memory = db_->GetMemoryUsage();
1829   EXPECT_GT(initial_memory, 0)
1830       << "SQLite should always use some memory for a database";
1831
1832   ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
1833   ASSERT_TRUE(db_->Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
1834
1835   int post_query_memory = db_->GetMemoryUsage();
1836   EXPECT_GT(post_query_memory, initial_memory)
1837       << "Page cache usage should go up after executing queries";
1838
1839   db_->TrimMemory();
1840   int post_trim_memory = db_->GetMemoryUsage();
1841   EXPECT_GT(post_query_memory, post_trim_memory)
1842       << "Page cache usage should go down after calling TrimMemory()";
1843 }
1844
1845 TEST_P(SQLDatabaseTest, DoubleQuotedStringLiteralsDisabledByDefault) {
1846   ASSERT_TRUE(db_->Execute("CREATE TABLE data(item TEXT NOT NULL);"));
1847
1848   struct TestCase {
1849     const char* sql;
1850     bool is_valid;
1851   };
1852   std::vector<TestCase> test_cases = {
1853       // DML tests.
1854       {"SELECT item FROM data WHERE item >= 'string literal'", true},
1855       {"SELECT item FROM data WHERE item >= \"string literal\"", false},
1856       {"INSERT INTO data(item) VALUES('string literal')", true},
1857       {"INSERT INTO data(item) VALUES(\"string literal\")", false},
1858       {"UPDATE data SET item = 'string literal'", true},
1859       {"UPDATE data SET item = \"string literal\"", false},
1860       {"DELETE FROM data WHERE item >= 'string literal'", true},
1861       {"DELETE FROM data WHERE item >= \"string literal\"", false},
1862
1863       // DDL tests.
1864       {"CREATE INDEX data_item ON data(item) WHERE item >= 'string literal'",
1865        true},
1866       {"CREATE INDEX data_item ON data(item) WHERE item >= \"string literal\"",
1867        false},
1868       {"CREATE TABLE data2(item TEXT DEFAULT 'string literal')", true},
1869
1870       // This should be an invalid DDL statement, due to the double-quoted
1871       // string literal. However, SQLite currently parses it.
1872       {"CREATE TABLE data2(item TEXT DEFAULT \"string literal\")", true},
1873   };
1874
1875   for (const TestCase& test_case : test_cases) {
1876     SCOPED_TRACE(test_case.sql);
1877
1878     EXPECT_EQ(test_case.is_valid, db_->IsSQLValid(test_case.sql));
1879   }
1880 }
1881
1882 TEST_P(SQLDatabaseTest, ForeignKeyEnforcementDisabledByDefault) {
1883   EXPECT_FALSE(GetDBOptions().enable_foreign_keys_discouraged);
1884
1885   ASSERT_TRUE(db_->Execute("CREATE TABLE targets(id INTEGER PRIMARY KEY)"));
1886   // sqlite3_db_config() currently only disables foreign key enforcement. Schema
1887   // operations on foreign keys are still allowed.
1888   ASSERT_TRUE(
1889       db_->Execute("CREATE TABLE refs("
1890                    "id INTEGER PRIMARY KEY,"
1891                    "target_id INTEGER REFERENCES targets(id))"));
1892
1893   ASSERT_TRUE(db_->Execute("INSERT INTO targets(id) VALUES(42)"));
1894   ASSERT_TRUE(db_->Execute("INSERT INTO refs(id, target_id) VALUES(42, 42)"));
1895
1896   EXPECT_TRUE(db_->Execute("DELETE FROM targets WHERE id=42"))
1897       << "Foreign key enforcement is not disabled";
1898 }
1899
1900 TEST_P(SQLDatabaseTest, ForeignKeyEnforcementEnabled) {
1901   DatabaseOptions options = GetDBOptions();
1902   options.enable_foreign_keys_discouraged = true;
1903   db_ = std::make_unique<Database>(options);
1904   ASSERT_TRUE(db_->Open(db_path_));
1905
1906   ASSERT_TRUE(db_->Execute("CREATE TABLE targets(id INTEGER PRIMARY KEY)"));
1907   ASSERT_TRUE(
1908       db_->Execute("CREATE TABLE refs("
1909                    "id INTEGER PRIMARY KEY,"
1910                    "target_id INTEGER REFERENCES targets(id))"));
1911
1912   ASSERT_TRUE(db_->Execute("INSERT INTO targets(id) VALUES(42)"));
1913   ASSERT_TRUE(db_->Execute("INSERT INTO refs(id, target_id) VALUES(42, 42)"));
1914
1915   {
1916     sql::test::ScopedErrorExpecter expecter;
1917     expecter.ExpectError(SQLITE_CONSTRAINT_FOREIGNKEY);
1918     EXPECT_FALSE(db_->Execute("DELETE FROM targets WHERE id=42"))
1919         << "Foreign key enforcement is disabled";
1920     EXPECT_TRUE(expecter.SawExpectedErrors());
1921   }
1922 }
1923
1924 TEST_P(SQLDatabaseTest, TriggersDisabledByDefault) {
1925   ASSERT_TRUE(db_->Execute("CREATE TABLE data(id INTEGER)"));
1926
1927   // sqlite3_db_config() currently only disables running triggers. Schema
1928   // operations on triggers are still allowed.
1929   EXPECT_TRUE(
1930       db_->Execute("CREATE TRIGGER trigger AFTER INSERT ON data "
1931                    "BEGIN DELETE FROM data; END"));
1932
1933   ASSERT_TRUE(db_->Execute("INSERT INTO data(id) VALUES(42)"));
1934
1935   Statement select(db_->GetUniqueStatement("SELECT id FROM data"));
1936   EXPECT_TRUE(select.Step())
1937       << "If the trigger did not run, the table should not be empty.";
1938   EXPECT_EQ(42, select.ColumnInt64(0));
1939
1940   // sqlite3_db_config() currently only disables running triggers. Schema
1941   // operations on triggers are still allowed.
1942   EXPECT_TRUE(db_->Execute("DROP TRIGGER IF EXISTS trigger"));
1943 }
1944
1945 class SQLDatabaseTestExclusiveMode : public testing::Test,
1946                                      public testing::WithParamInterface<bool> {
1947  public:
1948   ~SQLDatabaseTestExclusiveMode() override = default;
1949
1950   void SetUp() override {
1951     db_ = std::make_unique<Database>(GetDBOptions());
1952     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1953     db_path_ = temp_dir_.GetPath().AppendASCII("recovery_test.sqlite");
1954     ASSERT_TRUE(db_->Open(db_path_));
1955   }
1956
1957   DatabaseOptions GetDBOptions() {
1958     DatabaseOptions options;
1959     options.wal_mode = IsWALEnabled();
1960     options.exclusive_locking = true;
1961     return options;
1962   }
1963
1964   bool IsWALEnabled() { return GetParam(); }
1965
1966  protected:
1967   base::ScopedTempDir temp_dir_;
1968   base::FilePath db_path_;
1969   std::unique_ptr<Database> db_;
1970 };
1971
1972 TEST_P(SQLDatabaseTestExclusiveMode, LockingModeExclusive) {
1973   EXPECT_EQ(ExecuteWithResult(db_.get(), "PRAGMA locking_mode"), "exclusive");
1974 }
1975
1976 TEST_P(SQLDatabaseTest, LockingModeNormal) {
1977   EXPECT_EQ(ExecuteWithResult(db_.get(), "PRAGMA locking_mode"), "normal");
1978 }
1979
1980 TEST_P(SQLDatabaseTest, OpenedInCorrectMode) {
1981   std::string expected_mode = IsWALEnabled() ? "wal" : "truncate";
1982   EXPECT_EQ(ExecuteWithResult(db_.get(), "PRAGMA journal_mode"), expected_mode);
1983 }
1984
1985 TEST_P(SQLDatabaseTest, CheckpointDatabase) {
1986   if (!IsWALEnabled())
1987     return;
1988
1989   base::FilePath wal_path = Database::WriteAheadLogPath(db_path_);
1990
1991   int64_t wal_size = 0;
1992   // WAL file initially empty.
1993   EXPECT_TRUE(base::PathExists(wal_path));
1994   base::GetFileSize(wal_path, &wal_size);
1995   EXPECT_EQ(wal_size, 0);
1996
1997   ASSERT_TRUE(
1998       db_->Execute("CREATE TABLE foo (id INTEGER UNIQUE, value INTEGER)"));
1999   ASSERT_TRUE(db_->Execute("INSERT INTO foo VALUES (1, 1)"));
2000   ASSERT_TRUE(db_->Execute("INSERT INTO foo VALUES (2, 2)"));
2001
2002   // Writes reach WAL file but not db file.
2003   base::GetFileSize(wal_path, &wal_size);
2004   EXPECT_GT(wal_size, 0);
2005
2006   int64_t db_size = 0;
2007   base::GetFileSize(db_path_, &db_size);
2008   EXPECT_EQ(db_size, db_->page_size());
2009
2010   // Checkpoint database to immediately propagate writes to DB file.
2011   EXPECT_TRUE(db_->CheckpointDatabase());
2012
2013   base::GetFileSize(db_path_, &db_size);
2014   EXPECT_GT(db_size, db_->page_size());
2015   EXPECT_EQ(ExecuteWithResult(db_.get(), "SELECT value FROM foo where id=1"),
2016             "1");
2017   EXPECT_EQ(ExecuteWithResult(db_.get(), "SELECT value FROM foo where id=2"),
2018             "2");
2019 }
2020
2021 TEST_P(SQLDatabaseTest, OpenFailsAfterCorruptSizeInHeader) {
2022   // The database file ends up empty if we don't create at least one table.
2023   ASSERT_TRUE(
2024       db_->Execute("CREATE TABLE rows(i INTEGER PRIMARY KEY NOT NULL)"));
2025   db_->Close();
2026
2027   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
2028   {
2029     sql::test::ScopedErrorExpecter expecter;
2030     expecter.ExpectError(SQLITE_CORRUPT);
2031     ASSERT_TRUE(db_->Open(db_path_));
2032     EXPECT_TRUE(expecter.SawExpectedErrors());
2033   }
2034 }
2035
2036 TEST_P(SQLDatabaseTest, ExecuteFailsAfterCorruptSizeInHeader) {
2037   ASSERT_TRUE(
2038       db_->Execute("CREATE TABLE rows(i INTEGER PRIMARY KEY NOT NULL)"));
2039   constexpr static char kSelectSql[] = "SELECT * from rows";
2040   EXPECT_TRUE(db_->Execute(kSelectSql))
2041       << "The test Execute() statement fails before the header is corrupted";
2042   db_->Close();
2043
2044   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
2045   {
2046     sql::test::ScopedErrorExpecter expecter;
2047     expecter.ExpectError(SQLITE_CORRUPT);
2048     ASSERT_TRUE(db_->Open(db_path_));
2049     EXPECT_TRUE(expecter.SawExpectedErrors())
2050         << "Database::Open() did not encounter SQLITE_CORRUPT";
2051   }
2052   {
2053     sql::test::ScopedErrorExpecter expecter;
2054     expecter.ExpectError(SQLITE_CORRUPT);
2055     EXPECT_FALSE(db_->Execute(kSelectSql));
2056     EXPECT_TRUE(expecter.SawExpectedErrors())
2057         << "Database::Execute() did not encounter SQLITE_CORRUPT";
2058   }
2059 }
2060
2061 TEST_P(SQLDatabaseTest, SchemaFailsAfterCorruptSizeInHeader) {
2062   ASSERT_TRUE(
2063       db_->Execute("CREATE TABLE rows(i INTEGER PRIMARY KEY NOT NULL)"));
2064   ASSERT_TRUE(db_->DoesTableExist("rows"))
2065       << "The test schema check fails before the header is corrupted";
2066   db_->Close();
2067
2068   ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
2069   {
2070     sql::test::ScopedErrorExpecter expecter;
2071     expecter.ExpectError(SQLITE_CORRUPT);
2072     ASSERT_TRUE(db_->Open(db_path_));
2073     EXPECT_TRUE(expecter.SawExpectedErrors())
2074         << "Database::Open() did not encounter SQLITE_CORRUPT";
2075   }
2076   {
2077     sql::test::ScopedErrorExpecter expecter;
2078     expecter.ExpectError(SQLITE_CORRUPT);
2079     EXPECT_FALSE(db_->DoesTableExist("rows"));
2080     EXPECT_TRUE(expecter.SawExpectedErrors())
2081         << "Database::DoesTableExist() did not encounter SQLITE_CORRUPT";
2082   }
2083 }
2084
2085 TEST(SQLEmptyPathDatabaseTest, EmptyPathTest) {
2086   Database db;
2087   EXPECT_TRUE(db.OpenInMemory());
2088   EXPECT_TRUE(db.is_open());
2089   EXPECT_TRUE(db.DbPath().empty());
2090 }
2091
2092 // WAL mode is currently not supported on Fuchsia.
2093 #if !BUILDFLAG(IS_FUCHSIA)
2094 INSTANTIATE_TEST_SUITE_P(JournalMode, SQLDatabaseTest, testing::Bool());
2095 INSTANTIATE_TEST_SUITE_P(JournalMode,
2096                          SQLDatabaseTestExclusiveMode,
2097                          testing::Bool());
2098 #else
2099 INSTANTIATE_TEST_SUITE_P(JournalMode, SQLDatabaseTest, testing::Values(false));
2100 INSTANTIATE_TEST_SUITE_P(JournalMode,
2101                          SQLDatabaseTestExclusiveMode,
2102                          testing::Values(false));
2103 #endif
2104 }  // namespace sql