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.
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_file.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/logging.h"
10 #include "base/metrics/statistics_recorder.h"
11 #include "base/test/histogram_tester.h"
12 #include "sql/connection.h"
13 #include "sql/correct_sql_test_base.h"
14 #include "sql/meta_table.h"
15 #include "sql/statement.h"
16 #include "sql/test/error_callback_support.h"
17 #include "sql/test/scoped_error_ignorer.h"
18 #include "sql/test/test_helpers.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/sqlite/sqlite3.h"
25 // Replaces the database time source with an object that steps forward 1ms on
26 // each check, and which can be jumped forward an arbitrary amount of time
28 class ScopedMockTimeSource
{
30 ScopedMockTimeSource(Connection
& db
)
32 delta_(base::TimeDelta::FromMilliseconds(1)) {
33 // Save the current source and replace it.
34 save_
.swap(db_
.clock_
);
35 db_
.clock_
.reset(new MockTimeSource(*this));
37 ~ScopedMockTimeSource() {
38 // Put original source back.
39 db_
.clock_
.swap(save_
);
42 void adjust(const base::TimeDelta
& delta
) {
43 current_time_
+= delta
;
47 class MockTimeSource
: public TimeSource
{
49 MockTimeSource(ScopedMockTimeSource
& owner
)
52 ~MockTimeSource() override
{}
54 base::TimeTicks
Now() override
{
55 base::TimeTicks
ret(owner_
.current_time_
);
56 owner_
.current_time_
+= owner_
.delta_
;
61 ScopedMockTimeSource
& owner_
;
62 DISALLOW_COPY_AND_ASSIGN(MockTimeSource
);
67 // Saves original source from |db_|.
68 scoped_ptr
<TimeSource
> save_
;
70 // Current time returned by mock.
71 base::TimeTicks current_time_
;
73 // How far to jump on each Now() call.
74 base::TimeDelta delta_
;
76 DISALLOW_COPY_AND_ASSIGN(ScopedMockTimeSource
);
79 // Allow a test to add a SQLite function in a scoped context.
80 class ScopedScalarFunction
{
84 const char* function_name
,
86 base::Callback
<void(sqlite3_context
*,int,sqlite3_value
**)> cb
)
87 : db_(db
.db_
), function_name_(function_name
), cb_(cb
) {
88 sqlite3_create_function_v2(db_
, function_name
, args
, SQLITE_UTF8
,
89 this, &Run
, NULL
, NULL
, NULL
);
91 ~ScopedScalarFunction() {
92 sqlite3_create_function_v2(db_
, function_name_
, 0, SQLITE_UTF8
,
93 NULL
, NULL
, NULL
, NULL
, NULL
);
97 static void Run(sqlite3_context
* context
, int argc
, sqlite3_value
** argv
) {
98 ScopedScalarFunction
* t
= static_cast<ScopedScalarFunction
*>(
99 sqlite3_user_data(context
));
100 t
->cb_
.Run(context
, argc
, argv
);
104 const char* function_name_
;
105 base::Callback
<void(sqlite3_context
*,int,sqlite3_value
**)> cb_
;
107 DISALLOW_COPY_AND_ASSIGN(ScopedScalarFunction
);
110 // Allow a test to add a SQLite commit hook in a scoped context.
111 class ScopedCommitHook
{
113 ScopedCommitHook(sql::Connection
& db
,
114 base::Callback
<int(void)> cb
)
117 sqlite3_commit_hook(db_
, &Run
, this);
119 ~ScopedCommitHook() {
120 sqlite3_commit_hook(db_
, NULL
, NULL
);
124 static int Run(void* p
) {
125 ScopedCommitHook
* t
= static_cast<ScopedCommitHook
*>(p
);
130 base::Callback
<int(void)> cb_
;
132 DISALLOW_COPY_AND_ASSIGN(ScopedCommitHook
);
140 // Helper to return the count of items in sqlite_master. Return -1 in
142 int SqliteMasterCount(sql::Connection
* db
) {
143 const char* kMasterCount
= "SELECT COUNT(*) FROM sqlite_master";
144 sql::Statement
s(db
->GetUniqueStatement(kMasterCount
));
145 return s
.Step() ? s
.ColumnInt(0) : -1;
148 // Track the number of valid references which share the same pointer.
149 // This is used to allow testing an implicitly use-after-free case by
150 // explicitly having the ref count live longer than the object.
153 RefCounter(size_t* counter
)
154 : counter_(counter
) {
157 RefCounter(const RefCounter
& other
)
158 : counter_(other
.counter_
) {
168 DISALLOW_ASSIGN(RefCounter
);
171 // Empty callback for implementation of ErrorCallbackSetHelper().
172 void IgnoreErrorCallback(int error
, sql::Statement
* stmt
) {
175 void ErrorCallbackSetHelper(sql::Connection
* db
,
178 int error
, sql::Statement
* stmt
) {
179 // The ref count should not go to zero when changing the callback.
180 EXPECT_GT(*counter
, 0u);
181 db
->set_error_callback(base::Bind(&IgnoreErrorCallback
));
182 EXPECT_GT(*counter
, 0u);
185 void ErrorCallbackResetHelper(sql::Connection
* db
,
188 int error
, sql::Statement
* stmt
) {
189 // The ref count should not go to zero when clearing the callback.
190 EXPECT_GT(*counter
, 0u);
191 db
->reset_error_callback();
192 EXPECT_GT(*counter
, 0u);
195 #if defined(OS_POSIX)
196 // Set a umask and restore the old mask on destruction. Cribbed from
197 // shared_memory_unittest.cc. Used by POSIX-only UserPermission test.
198 class ScopedUmaskSetter
{
200 explicit ScopedUmaskSetter(mode_t target_mask
) {
201 old_umask_
= umask(target_mask
);
203 ~ScopedUmaskSetter() { umask(old_umask_
); }
206 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter
);
210 class SQLConnectionTest
: public sql::SQLTestBase
{
212 void SetUp() override
{
213 // Any macro histograms which fire before the recorder is initialized cannot
214 // be tested. So this needs to be ahead of Open().
215 base::StatisticsRecorder::Initialize();
217 SQLTestBase::SetUp();
220 // Handle errors by blowing away the database.
221 void RazeErrorCallback(int expected_error
, int error
, sql::Statement
* stmt
) {
222 EXPECT_EQ(expected_error
, error
);
227 TEST_F(SQLConnectionTest
, Execute
) {
228 // Valid statement should return true.
229 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
230 EXPECT_EQ(SQLITE_OK
, db().GetErrorCode());
232 // Invalid statement should fail.
233 ASSERT_EQ(SQLITE_ERROR
,
234 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
235 EXPECT_EQ(SQLITE_ERROR
, db().GetErrorCode());
238 TEST_F(SQLConnectionTest
, ExecuteWithErrorCode
) {
240 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
241 ASSERT_EQ(SQLITE_ERROR
,
242 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
243 ASSERT_EQ(SQLITE_ERROR
,
244 db().ExecuteAndReturnErrorCode(
245 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
248 TEST_F(SQLConnectionTest
, CachedStatement
) {
249 sql::StatementID
id1("foo", 12);
251 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
252 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
254 // Create a new cached statement.
256 sql::Statement
s(db().GetCachedStatement(id1
, "SELECT a FROM foo"));
257 ASSERT_TRUE(s
.is_valid());
259 ASSERT_TRUE(s
.Step());
260 EXPECT_EQ(12, s
.ColumnInt(0));
263 // The statement should be cached still.
264 EXPECT_TRUE(db().HasCachedStatement(id1
));
267 // Get the same statement using different SQL. This should ignore our
268 // SQL and use the cached one (so it will be valid).
269 sql::Statement
s(db().GetCachedStatement(id1
, "something invalid("));
270 ASSERT_TRUE(s
.is_valid());
272 ASSERT_TRUE(s
.Step());
273 EXPECT_EQ(12, s
.ColumnInt(0));
276 // Make sure other statements aren't marked as cached.
277 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE
));
280 TEST_F(SQLConnectionTest
, IsSQLValidTest
) {
281 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
282 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
283 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
286 TEST_F(SQLConnectionTest
, DoesStuffExist
) {
287 // Test DoesTableExist.
288 EXPECT_FALSE(db().DoesTableExist("foo"));
289 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
290 ASSERT_TRUE(db().Execute("CREATE INDEX foo_a ON foo (a)"));
291 EXPECT_TRUE(db().DoesTableExist("foo"));
292 EXPECT_TRUE(db().DoesIndexExist("foo_a"));
294 // Test DoesColumnExist.
295 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
296 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
298 // Testing for a column on a nonexistent table.
299 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
301 // Names are not case sensitive.
302 EXPECT_TRUE(db().DoesTableExist("FOO"));
303 EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
306 TEST_F(SQLConnectionTest
, GetLastInsertRowId
) {
307 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
309 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
311 // Last insert row ID should be valid.
312 int64_t row
= db().GetLastInsertRowId();
315 // It should be the primary key of the row we just inserted.
316 sql::Statement
s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
318 ASSERT_TRUE(s
.Step());
319 EXPECT_EQ(12, s
.ColumnInt(0));
322 TEST_F(SQLConnectionTest
, Rollback
) {
323 ASSERT_TRUE(db().BeginTransaction());
324 ASSERT_TRUE(db().BeginTransaction());
325 EXPECT_EQ(2, db().transaction_nesting());
326 db().RollbackTransaction();
327 EXPECT_FALSE(db().CommitTransaction());
328 EXPECT_TRUE(db().BeginTransaction());
331 // Test the scoped error ignorer by attempting to insert a duplicate
332 // value into an index.
333 TEST_F(SQLConnectionTest
, ScopedIgnoreError
) {
334 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER UNIQUE)";
335 ASSERT_TRUE(db().Execute(kCreateSql
));
336 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
339 sql::ScopedErrorIgnorer ignore_errors
;
340 ignore_errors
.IgnoreError(SQLITE_CONSTRAINT
);
341 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
342 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
346 // Test that clients of GetUntrackedStatement() can test corruption-handling
347 // with ScopedErrorIgnorer.
348 TEST_F(SQLConnectionTest
, ScopedIgnoreUntracked
) {
349 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER UNIQUE)";
350 ASSERT_TRUE(db().Execute(kCreateSql
));
351 ASSERT_FALSE(db().DoesTableExist("bar"));
352 ASSERT_TRUE(db().DoesTableExist("foo"));
353 ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
356 // Corrupt the database so that nothing works, including PRAGMAs.
357 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
360 sql::ScopedErrorIgnorer ignore_errors
;
361 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
362 ASSERT_TRUE(db().Open(db_path()));
363 ASSERT_FALSE(db().DoesTableExist("bar"));
364 ASSERT_FALSE(db().DoesTableExist("foo"));
365 ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
366 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
370 TEST_F(SQLConnectionTest
, ErrorCallback
) {
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)"));
375 int error
= SQLITE_OK
;
377 sql::ScopedErrorCallback
sec(
378 &db(), base::Bind(&sql::CaptureErrorCallback
, &error
));
379 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
381 // Later versions of SQLite throw SQLITE_CONSTRAINT_UNIQUE. The specific
382 // sub-error isn't really important.
383 EXPECT_EQ(SQLITE_CONSTRAINT
, (error
&0xff));
386 // Callback is no longer in force due to reset.
389 sql::ScopedErrorIgnorer ignore_errors
;
390 ignore_errors
.IgnoreError(SQLITE_CONSTRAINT
);
391 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
392 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
393 EXPECT_EQ(SQLITE_OK
, error
);
396 // base::Bind() can curry arguments to be passed by const reference
397 // to the callback function. If the callback function calls
398 // re/set_error_callback(), the storage for those arguments can be
399 // deleted while the callback function is still executing.
401 // RefCounter() counts how many objects are live using an external
402 // count. The same counter is passed to the callback, so that it
403 // can check directly even if the RefCounter object is no longer
407 sql::ScopedErrorCallback
sec(
408 &db(), base::Bind(&ErrorCallbackSetHelper
,
409 &db(), &count
, RefCounter(&count
)));
411 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
414 // Same test, but reset_error_callback() case.
417 sql::ScopedErrorCallback
sec(
418 &db(), base::Bind(&ErrorCallbackResetHelper
,
419 &db(), &count
, RefCounter(&count
)));
421 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
425 // Test that sql::Connection::Raze() results in a database without the
426 // tables from the original database.
427 TEST_F(SQLConnectionTest
, Raze
) {
428 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
429 ASSERT_TRUE(db().Execute(kCreateSql
));
430 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
432 int pragma_auto_vacuum
= 0;
434 sql::Statement
s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
435 ASSERT_TRUE(s
.Step());
436 pragma_auto_vacuum
= s
.ColumnInt(0);
437 ASSERT_TRUE(pragma_auto_vacuum
== 0 || pragma_auto_vacuum
== 1);
440 // If auto_vacuum is set, there's an extra page to maintain a freelist.
441 const int kExpectedPageCount
= 2 + pragma_auto_vacuum
;
444 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_count"));
445 ASSERT_TRUE(s
.Step());
446 EXPECT_EQ(kExpectedPageCount
, s
.ColumnInt(0));
450 sql::Statement
s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
451 ASSERT_TRUE(s
.Step());
452 EXPECT_EQ("table", s
.ColumnString(0));
453 EXPECT_EQ("foo", s
.ColumnString(1));
454 EXPECT_EQ("foo", s
.ColumnString(2));
455 // Table "foo" is stored in the last page of the file.
456 EXPECT_EQ(kExpectedPageCount
, s
.ColumnInt(3));
457 EXPECT_EQ(kCreateSql
, s
.ColumnString(4));
460 ASSERT_TRUE(db().Raze());
463 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_count"));
464 ASSERT_TRUE(s
.Step());
465 EXPECT_EQ(1, s
.ColumnInt(0));
468 ASSERT_EQ(0, SqliteMasterCount(&db()));
471 sql::Statement
s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
472 ASSERT_TRUE(s
.Step());
473 // The new database has the same auto_vacuum as a fresh database.
474 EXPECT_EQ(pragma_auto_vacuum
, s
.ColumnInt(0));
478 // Test that Raze() maintains page_size.
479 TEST_F(SQLConnectionTest
, RazePageSize
) {
480 // Fetch the default page size and double it for use in this test.
481 // Scoped to release statement before Close().
482 int default_page_size
= 0;
484 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_size"));
485 ASSERT_TRUE(s
.Step());
486 default_page_size
= s
.ColumnInt(0);
488 ASSERT_GT(default_page_size
, 0);
489 const int kPageSize
= 2 * default_page_size
;
491 // Re-open the database to allow setting the page size.
493 db().set_page_size(kPageSize
);
494 ASSERT_TRUE(db().Open(db_path()));
496 // page_size should match the indicated value.
497 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_size"));
498 ASSERT_TRUE(s
.Step());
499 ASSERT_EQ(kPageSize
, s
.ColumnInt(0));
501 // After raze, page_size should still match the indicated value.
502 ASSERT_TRUE(db().Raze());
504 ASSERT_TRUE(s
.Step());
505 ASSERT_EQ(kPageSize
, s
.ColumnInt(0));
508 // Test that Raze() results are seen in other connections.
509 TEST_F(SQLConnectionTest
, RazeMultiple
) {
510 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
511 ASSERT_TRUE(db().Execute(kCreateSql
));
513 sql::Connection other_db
;
514 ASSERT_TRUE(other_db
.Open(db_path()));
516 // Check that the second connection sees the table.
517 ASSERT_EQ(1, SqliteMasterCount(&other_db
));
519 ASSERT_TRUE(db().Raze());
521 // The second connection sees the updated database.
522 ASSERT_EQ(0, SqliteMasterCount(&other_db
));
525 // TODO(erg): Enable this in the next patch once I add locking.
526 #if !defined(MOJO_APPTEST_IMPL)
527 TEST_F(SQLConnectionTest
, RazeLocked
) {
528 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
529 ASSERT_TRUE(db().Execute(kCreateSql
));
531 // Open a transaction and write some data in a second connection.
532 // This will acquire a PENDING or EXCLUSIVE transaction, which will
533 // cause the raze to fail.
534 sql::Connection other_db
;
535 ASSERT_TRUE(other_db
.Open(db_path()));
536 ASSERT_TRUE(other_db
.BeginTransaction());
537 const char* kInsertSql
= "INSERT INTO foo VALUES (1, 'data')";
538 ASSERT_TRUE(other_db
.Execute(kInsertSql
));
540 ASSERT_FALSE(db().Raze());
542 // Works after COMMIT.
543 ASSERT_TRUE(other_db
.CommitTransaction());
544 ASSERT_TRUE(db().Raze());
546 // Re-create the database.
547 ASSERT_TRUE(db().Execute(kCreateSql
));
548 ASSERT_TRUE(db().Execute(kInsertSql
));
550 // An unfinished read transaction in the other connection also
552 const char *kQuery
= "SELECT COUNT(*) FROM foo";
553 sql::Statement
s(other_db
.GetUniqueStatement(kQuery
));
554 ASSERT_TRUE(s
.Step());
555 ASSERT_FALSE(db().Raze());
557 // Complete the statement unlocks the database.
558 ASSERT_FALSE(s
.Step());
559 ASSERT_TRUE(db().Raze());
563 // Verify that Raze() can handle an empty file. SQLite should treat
564 // this as an empty database.
565 TEST_F(SQLConnectionTest
, RazeEmptyDB
) {
566 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
567 ASSERT_TRUE(db().Execute(kCreateSql
));
572 ASSERT_TRUE(db().Open(db_path()));
573 ASSERT_TRUE(db().Raze());
574 EXPECT_EQ(0, SqliteMasterCount(&db()));
577 // Verify that Raze() can handle a file of junk.
578 TEST_F(SQLConnectionTest
, RazeNOTADB
) {
580 sql::Connection::Delete(db_path());
581 ASSERT_FALSE(GetPathExists(db_path()));
583 WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE_AND_TRUNCATE
);
584 ASSERT_TRUE(GetPathExists(db_path()));
586 // SQLite will successfully open the handle, but fail when running PRAGMA
587 // statements that access the database.
589 sql::ScopedErrorIgnorer ignore_errors
;
591 // Earlier versions of Chromium compiled against SQLite 3.6.7.3, which
592 // returned SQLITE_IOERR_SHORT_READ in this case. Some platforms may still
593 // compile against an earlier SQLite via USE_SYSTEM_SQLITE.
594 if (ignore_errors
.SQLiteLibVersionNumber() < 3008005) {
595 ignore_errors
.IgnoreError(SQLITE_IOERR_SHORT_READ
);
597 ignore_errors
.IgnoreError(SQLITE_NOTADB
);
600 EXPECT_TRUE(db().Open(db_path()));
601 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
603 EXPECT_TRUE(db().Raze());
606 // Now empty, the open should open an empty database.
607 EXPECT_TRUE(db().Open(db_path()));
608 EXPECT_EQ(0, SqliteMasterCount(&db()));
611 // Verify that Raze() can handle a database overwritten with garbage.
612 TEST_F(SQLConnectionTest
, RazeNOTADB2
) {
613 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
614 ASSERT_TRUE(db().Execute(kCreateSql
));
615 ASSERT_EQ(1, SqliteMasterCount(&db()));
618 WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE
);
620 // SQLite will successfully open the handle, but will fail with
621 // SQLITE_NOTADB on pragma statemenets which attempt to read the
624 sql::ScopedErrorIgnorer ignore_errors
;
625 ignore_errors
.IgnoreError(SQLITE_NOTADB
);
626 EXPECT_TRUE(db().Open(db_path()));
627 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
629 EXPECT_TRUE(db().Raze());
632 // Now empty, the open should succeed with an empty database.
633 EXPECT_TRUE(db().Open(db_path()));
634 EXPECT_EQ(0, SqliteMasterCount(&db()));
637 // Test that a callback from Open() can raze the database. This is
638 // essential for cases where the Open() can fail entirely, so the
639 // Raze() cannot happen later. Additionally test that when the
640 // callback does this during Open(), the open is retried and succeeds.
641 TEST_F(SQLConnectionTest
, RazeCallbackReopen
) {
642 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
643 ASSERT_TRUE(db().Execute(kCreateSql
));
644 ASSERT_EQ(1, SqliteMasterCount(&db()));
647 // Corrupt the database so that nothing works, including PRAGMAs.
648 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
650 // Open() will succeed, even though the PRAGMA calls within will
651 // fail with SQLITE_CORRUPT, as will this PRAGMA.
653 sql::ScopedErrorIgnorer ignore_errors
;
654 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
655 ASSERT_TRUE(db().Open(db_path()));
656 ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
658 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
661 db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback
,
662 base::Unretained(this),
665 // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
666 // callback will call RazeAndClose(). Open() will then fail and be
667 // retried. The second Open() on the empty database will succeed
669 ASSERT_TRUE(db().Open(db_path()));
670 ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
671 EXPECT_EQ(0, SqliteMasterCount(&db()));
674 // Basic test of RazeAndClose() operation.
675 TEST_F(SQLConnectionTest
, RazeAndClose
) {
676 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
677 const char* kPopulateSql
= "INSERT INTO foo (value) VALUES (12)";
679 // Test that RazeAndClose() closes the database, and that the
680 // database is empty when re-opened.
681 ASSERT_TRUE(db().Execute(kCreateSql
));
682 ASSERT_TRUE(db().Execute(kPopulateSql
));
683 ASSERT_TRUE(db().RazeAndClose());
684 ASSERT_FALSE(db().is_open());
686 ASSERT_TRUE(db().Open(db_path()));
687 ASSERT_EQ(0, SqliteMasterCount(&db()));
689 // Test that RazeAndClose() can break transactions.
690 ASSERT_TRUE(db().Execute(kCreateSql
));
691 ASSERT_TRUE(db().Execute(kPopulateSql
));
692 ASSERT_TRUE(db().BeginTransaction());
693 ASSERT_TRUE(db().RazeAndClose());
694 ASSERT_FALSE(db().is_open());
695 ASSERT_FALSE(db().CommitTransaction());
697 ASSERT_TRUE(db().Open(db_path()));
698 ASSERT_EQ(0, SqliteMasterCount(&db()));
701 // Test that various operations fail without crashing after
703 TEST_F(SQLConnectionTest
, RazeAndCloseDiagnostics
) {
704 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
705 const char* kPopulateSql
= "INSERT INTO foo (value) VALUES (12)";
706 const char* kSimpleSql
= "SELECT 1";
708 ASSERT_TRUE(db().Execute(kCreateSql
));
709 ASSERT_TRUE(db().Execute(kPopulateSql
));
711 // Test baseline expectations.
713 ASSERT_TRUE(db().DoesTableExist("foo"));
714 ASSERT_TRUE(db().IsSQLValid(kSimpleSql
));
715 ASSERT_EQ(SQLITE_OK
, db().ExecuteAndReturnErrorCode(kSimpleSql
));
716 ASSERT_TRUE(db().Execute(kSimpleSql
));
717 ASSERT_TRUE(db().is_open());
719 sql::Statement
s(db().GetUniqueStatement(kSimpleSql
));
720 ASSERT_TRUE(s
.Step());
723 sql::Statement
s(db().GetCachedStatement(SQL_FROM_HERE
, kSimpleSql
));
724 ASSERT_TRUE(s
.Step());
726 ASSERT_TRUE(db().BeginTransaction());
727 ASSERT_TRUE(db().CommitTransaction());
728 ASSERT_TRUE(db().BeginTransaction());
729 db().RollbackTransaction();
731 ASSERT_TRUE(db().RazeAndClose());
733 // At this point, they should all fail, but not crash.
735 ASSERT_FALSE(db().DoesTableExist("foo"));
736 ASSERT_FALSE(db().IsSQLValid(kSimpleSql
));
737 ASSERT_EQ(SQLITE_ERROR
, db().ExecuteAndReturnErrorCode(kSimpleSql
));
738 ASSERT_FALSE(db().Execute(kSimpleSql
));
739 ASSERT_FALSE(db().is_open());
741 sql::Statement
s(db().GetUniqueStatement(kSimpleSql
));
742 ASSERT_FALSE(s
.Step());
745 sql::Statement
s(db().GetCachedStatement(SQL_FROM_HERE
, kSimpleSql
));
746 ASSERT_FALSE(s
.Step());
748 ASSERT_FALSE(db().BeginTransaction());
749 ASSERT_FALSE(db().CommitTransaction());
750 ASSERT_FALSE(db().BeginTransaction());
751 db().RollbackTransaction();
753 // Close normally to reset the poisoned flag.
756 // DEATH tests not supported on Android or iOS.
757 #if !defined(OS_ANDROID) && !defined(OS_IOS)
758 // Once the real Close() has been called, various calls enforce API
759 // usage by becoming fatal in debug mode. Since DEATH tests are
760 // expensive, just test one of them.
761 if (DLOG_IS_ON(FATAL
)) {
763 db().IsSQLValid(kSimpleSql
);
764 }, "Illegal use of connection without a db");
769 // TODO(shess): Spin up a background thread to hold other_db, to more
770 // closely match real life. That would also allow testing
771 // RazeWithTimeout().
773 #if defined(OS_ANDROID)
774 TEST_F(SQLConnectionTest
, SetTempDirForSQL
) {
776 sql::MetaTable meta_table
;
777 // Below call needs a temporary directory in sqlite3
778 // On Android, it can pass only when the temporary directory is set.
779 // Otherwise, sqlite3 doesn't find the correct directory to store
780 // temporary files and will report the error 'unable to open
782 ASSERT_TRUE(meta_table
.Init(&db(), 4, 4));
786 TEST_F(SQLConnectionTest
, Delete
) {
787 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
790 // Should have both a main database file and a journal file because
791 // of journal_mode TRUNCATE.
792 base::FilePath
journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
793 ASSERT_TRUE(GetPathExists(db_path()));
794 ASSERT_TRUE(GetPathExists(journal
));
796 sql::Connection::Delete(db_path());
797 EXPECT_FALSE(GetPathExists(db_path()));
798 EXPECT_FALSE(GetPathExists(journal
));
801 // This test manually sets on disk permissions; this doesn't apply to the mojo
803 #if defined(OS_POSIX) && !defined(MOJO_APPTEST_IMPL)
804 // Test that set_restrict_to_user() trims database permissions so that
805 // only the owner (and root) can read.
806 TEST_F(SQLConnectionTest
, UserPermission
) {
807 // If the bots all had a restrictive umask setting such that
808 // databases are always created with only the owner able to read
809 // them, then the code could break without breaking the tests.
810 // Temporarily provide a more permissive umask.
812 sql::Connection::Delete(db_path());
813 ASSERT_FALSE(GetPathExists(db_path()));
814 ScopedUmaskSetter
permissive_umask(S_IWGRP
| S_IWOTH
);
815 ASSERT_TRUE(db().Open(db_path()));
817 // Cause the journal file to be created. If the default
818 // journal_mode is changed back to DELETE, then parts of this test
819 // will need to be updated.
820 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
822 base::FilePath
journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
825 // Given a permissive umask, the database is created with permissive
826 // read access for the database and journal.
827 ASSERT_TRUE(GetPathExists(db_path()));
828 ASSERT_TRUE(GetPathExists(journal
));
829 mode
= base::FILE_PERMISSION_MASK
;
830 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode
));
831 ASSERT_NE((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
832 mode
= base::FILE_PERMISSION_MASK
;
833 EXPECT_TRUE(base::GetPosixFilePermissions(journal
, &mode
));
834 ASSERT_NE((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
836 // Re-open with restricted permissions and verify that the modes
837 // changed for both the main database and the journal.
839 db().set_restrict_to_user();
840 ASSERT_TRUE(db().Open(db_path()));
841 ASSERT_TRUE(GetPathExists(db_path()));
842 ASSERT_TRUE(GetPathExists(journal
));
843 mode
= base::FILE_PERMISSION_MASK
;
844 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode
));
845 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
846 mode
= base::FILE_PERMISSION_MASK
;
847 EXPECT_TRUE(base::GetPosixFilePermissions(journal
, &mode
));
848 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
850 // Delete and re-create the database, the restriction should still apply.
852 sql::Connection::Delete(db_path());
853 ASSERT_TRUE(db().Open(db_path()));
854 ASSERT_TRUE(GetPathExists(db_path()));
855 ASSERT_FALSE(GetPathExists(journal
));
856 mode
= base::FILE_PERMISSION_MASK
;
857 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode
));
858 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
860 // Verify that journal creation inherits the restriction.
861 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
862 ASSERT_TRUE(GetPathExists(journal
));
863 mode
= base::FILE_PERMISSION_MASK
;
864 EXPECT_TRUE(base::GetPosixFilePermissions(journal
, &mode
));
865 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
867 #endif // defined(OS_POSIX)
869 // Test that errors start happening once Poison() is called.
870 TEST_F(SQLConnectionTest
, Poison
) {
871 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
873 // Before the Poison() call, things generally work.
874 EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
875 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
877 sql::Statement
s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
878 ASSERT_TRUE(s
.is_valid());
879 ASSERT_TRUE(s
.Step());
882 // Get a statement which is valid before and will exist across Poison().
883 sql::Statement
valid_statement(
884 db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
885 ASSERT_TRUE(valid_statement
.is_valid());
886 ASSERT_TRUE(valid_statement
.Step());
887 valid_statement
.Reset(true);
891 // After the Poison() call, things fail.
892 EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
893 EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
895 sql::Statement
s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
896 ASSERT_FALSE(s
.is_valid());
897 ASSERT_FALSE(s
.Step());
900 // The existing statement has become invalid.
901 ASSERT_FALSE(valid_statement
.is_valid());
902 ASSERT_FALSE(valid_statement
.Step());
905 // Test attaching and detaching databases from the connection.
906 TEST_F(SQLConnectionTest
, Attach
) {
907 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
909 // Create a database to attach to.
910 base::FilePath attach_path
=
911 db_path().DirName().AppendASCII("SQLConnectionAttach.db");
912 const char kAttachmentPoint
[] = "other";
914 sql::Connection other_db
;
915 ASSERT_TRUE(other_db
.Open(attach_path
));
916 EXPECT_TRUE(other_db
.Execute("CREATE TABLE bar (a, b)"));
917 EXPECT_TRUE(other_db
.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
920 // Cannot see the attached database, yet.
921 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
923 // Attach fails in a transaction.
924 EXPECT_TRUE(db().BeginTransaction());
926 sql::ScopedErrorIgnorer ignore_errors
;
927 ignore_errors
.IgnoreError(SQLITE_ERROR
);
928 EXPECT_FALSE(db().AttachDatabase(attach_path
, kAttachmentPoint
));
929 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
932 // Attach succeeds when the transaction is closed.
933 db().RollbackTransaction();
934 EXPECT_TRUE(db().AttachDatabase(attach_path
, kAttachmentPoint
));
935 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
937 // Queries can touch both databases.
938 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
940 sql::Statement
s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
941 ASSERT_TRUE(s
.Step());
942 EXPECT_EQ(1, s
.ColumnInt(0));
945 // Detach also fails in a transaction.
946 EXPECT_TRUE(db().BeginTransaction());
948 sql::ScopedErrorIgnorer ignore_errors
;
949 ignore_errors
.IgnoreError(SQLITE_ERROR
);
950 EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint
));
951 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
952 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
955 // Detach succeeds outside of a transaction.
956 db().RollbackTransaction();
957 EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint
));
959 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
962 TEST_F(SQLConnectionTest
, Basic_QuickIntegrityCheck
) {
963 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
964 ASSERT_TRUE(db().Execute(kCreateSql
));
965 EXPECT_TRUE(db().QuickIntegrityCheck());
968 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
971 sql::ScopedErrorIgnorer ignore_errors
;
972 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
973 ASSERT_TRUE(db().Open(db_path()));
974 EXPECT_FALSE(db().QuickIntegrityCheck());
975 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
979 TEST_F(SQLConnectionTest
, Basic_FullIntegrityCheck
) {
980 const std::string
kOk("ok");
981 std::vector
<std::string
> messages
;
983 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
984 ASSERT_TRUE(db().Execute(kCreateSql
));
985 EXPECT_TRUE(db().FullIntegrityCheck(&messages
));
986 EXPECT_EQ(1u, messages
.size());
987 EXPECT_EQ(kOk
, messages
[0]);
990 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
993 sql::ScopedErrorIgnorer ignore_errors
;
994 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
995 ASSERT_TRUE(db().Open(db_path()));
996 EXPECT_TRUE(db().FullIntegrityCheck(&messages
));
997 EXPECT_LT(1u, messages
.size());
998 EXPECT_NE(kOk
, messages
[0]);
999 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
1002 // TODO(shess): CorruptTableOrIndex could be used to produce a
1003 // file that would pass the quick check and fail the full check.
1006 // Test Sqlite.Stats histogram for execute-oriented calls.
1007 TEST_F(SQLConnectionTest
, EventsExecute
) {
1008 // Re-open with histogram tag.
1010 db().set_histogram_tag("Test");
1011 ASSERT_TRUE(db().Open(db_path()));
1013 // Open() uses Execute() extensively, don't track those calls.
1014 base::HistogramTester tester
;
1016 const char kHistogramName
[] = "Sqlite.Stats.Test";
1017 const char kGlobalHistogramName
[] = "Sqlite.Stats";
1019 ASSERT_TRUE(db().BeginTransaction());
1020 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1021 EXPECT_TRUE(db().Execute(kCreateSql
));
1022 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, 'text')"));
1023 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, 'text')"));
1024 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (12, 'text')"));
1025 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (13, 'text')"));
1026 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (14, 'text')"));
1027 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (15, 'text');"
1028 "INSERT INTO foo VALUES (16, 'text');"
1029 "INSERT INTO foo VALUES (17, 'text');"
1030 "INSERT INTO foo VALUES (18, 'text');"
1031 "INSERT INTO foo VALUES (19, 'text')"));
1032 ASSERT_TRUE(db().CommitTransaction());
1033 ASSERT_TRUE(db().BeginTransaction());
1034 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (20, 'text')"));
1035 db().RollbackTransaction();
1036 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (20, 'text')"));
1037 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (21, 'text')"));
1039 // The create, 5 inserts, multi-statement insert, rolled-back insert, 2
1040 // inserts outside transaction.
1041 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_EXECUTE
, 10);
1042 tester
.ExpectBucketCount(kGlobalHistogramName
,
1043 sql::Connection::EVENT_EXECUTE
, 10);
1045 // All of the executes, with the multi-statement inserts broken out, plus one
1046 // for each begin, commit, and rollback.
1047 tester
.ExpectBucketCount(kHistogramName
,
1048 sql::Connection::EVENT_STATEMENT_RUN
, 18);
1049 tester
.ExpectBucketCount(kGlobalHistogramName
,
1050 sql::Connection::EVENT_STATEMENT_RUN
, 18);
1052 tester
.ExpectBucketCount(kHistogramName
,
1053 sql::Connection::EVENT_STATEMENT_ROWS
, 0);
1054 tester
.ExpectBucketCount(kGlobalHistogramName
,
1055 sql::Connection::EVENT_STATEMENT_ROWS
, 0);
1056 tester
.ExpectBucketCount(kHistogramName
,
1057 sql::Connection::EVENT_STATEMENT_SUCCESS
, 18);
1058 tester
.ExpectBucketCount(kGlobalHistogramName
,
1059 sql::Connection::EVENT_STATEMENT_SUCCESS
, 18);
1061 // The 2 inserts outside the transaction.
1062 tester
.ExpectBucketCount(kHistogramName
,
1063 sql::Connection::EVENT_CHANGES_AUTOCOMMIT
, 2);
1064 tester
.ExpectBucketCount(kGlobalHistogramName
,
1065 sql::Connection::EVENT_CHANGES_AUTOCOMMIT
, 2);
1067 // 11 inserts inside transactions.
1068 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_CHANGES
, 11);
1069 tester
.ExpectBucketCount(kGlobalHistogramName
,
1070 sql::Connection::EVENT_CHANGES
, 11);
1072 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_BEGIN
, 2);
1073 tester
.ExpectBucketCount(kGlobalHistogramName
,
1074 sql::Connection::EVENT_BEGIN
, 2);
1075 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_COMMIT
, 1);
1076 tester
.ExpectBucketCount(kGlobalHistogramName
,
1077 sql::Connection::EVENT_COMMIT
, 1);
1078 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_ROLLBACK
, 1);
1079 tester
.ExpectBucketCount(kGlobalHistogramName
,
1080 sql::Connection::EVENT_ROLLBACK
, 1);
1083 // Test Sqlite.Stats histogram for prepared statements.
1084 TEST_F(SQLConnectionTest
, EventsStatement
) {
1085 // Re-open with histogram tag.
1087 db().set_histogram_tag("Test");
1088 ASSERT_TRUE(db().Open(db_path()));
1090 const char kHistogramName
[] = "Sqlite.Stats.Test";
1091 const char kGlobalHistogramName
[] = "Sqlite.Stats";
1093 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1094 EXPECT_TRUE(db().Execute(kCreateSql
));
1095 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, 'text')"));
1096 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, 'text')"));
1097 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (12, 'text')"));
1100 base::HistogramTester tester
;
1103 sql::Statement
s(db().GetUniqueStatement("SELECT value FROM foo"));
1108 tester
.ExpectBucketCount(kHistogramName
,
1109 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1110 tester
.ExpectBucketCount(kGlobalHistogramName
,
1111 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1112 tester
.ExpectBucketCount(kHistogramName
,
1113 sql::Connection::EVENT_STATEMENT_ROWS
, 3);
1114 tester
.ExpectBucketCount(kGlobalHistogramName
,
1115 sql::Connection::EVENT_STATEMENT_ROWS
, 3);
1116 tester
.ExpectBucketCount(kHistogramName
,
1117 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1118 tester
.ExpectBucketCount(kGlobalHistogramName
,
1119 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1123 base::HistogramTester tester
;
1126 sql::Statement
s(db().GetUniqueStatement(
1127 "SELECT value FROM foo WHERE id > 10"));
1132 tester
.ExpectBucketCount(kHistogramName
,
1133 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1134 tester
.ExpectBucketCount(kGlobalHistogramName
,
1135 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1136 tester
.ExpectBucketCount(kHistogramName
,
1137 sql::Connection::EVENT_STATEMENT_ROWS
, 2);
1138 tester
.ExpectBucketCount(kGlobalHistogramName
,
1139 sql::Connection::EVENT_STATEMENT_ROWS
, 2);
1140 tester
.ExpectBucketCount(kHistogramName
,
1141 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1142 tester
.ExpectBucketCount(kGlobalHistogramName
,
1143 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1147 // SQLite function to adjust mock time by |argv[0]| milliseconds.
1148 void sqlite_adjust_millis(sql::test::ScopedMockTimeSource
* time_mock
,
1149 sqlite3_context
* context
,
1150 int argc
, sqlite3_value
** argv
) {
1151 int64 milliseconds
= argc
> 0 ? sqlite3_value_int64(argv
[0]) : 1000;
1152 time_mock
->adjust(base::TimeDelta::FromMilliseconds(milliseconds
));
1153 sqlite3_result_int64(context
, milliseconds
);
1156 // Adjust mock time by |milliseconds| on commit.
1157 int adjust_commit_hook(sql::test::ScopedMockTimeSource
* time_mock
,
1158 int64 milliseconds
) {
1159 time_mock
->adjust(base::TimeDelta::FromMilliseconds(milliseconds
));
1163 const char kCommitTime
[] = "Sqlite.CommitTime.Test";
1164 const char kAutoCommitTime
[] = "Sqlite.AutoCommitTime.Test";
1165 const char kUpdateTime
[] = "Sqlite.UpdateTime.Test";
1166 const char kQueryTime
[] = "Sqlite.QueryTime.Test";
1168 // Read-only query allocates time to QueryTime, but not others.
1169 TEST_F(SQLConnectionTest
, TimeQuery
) {
1170 // Re-open with histogram tag. Use an in-memory database to minimize variance
1171 // due to filesystem.
1173 db().set_histogram_tag("Test");
1174 ASSERT_TRUE(db().OpenInMemory());
1176 sql::test::ScopedMockTimeSource
time_mock(db());
1178 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1179 EXPECT_TRUE(db().Execute(kCreateSql
));
1181 // Function to inject pauses into statements.
1182 sql::test::ScopedScalarFunction
scoper(
1183 db(), "milliadjust", 1, base::Bind(&sqlite_adjust_millis
, &time_mock
));
1185 base::HistogramTester tester
;
1187 EXPECT_TRUE(db().Execute("SELECT milliadjust(10)"));
1189 scoped_ptr
<base::HistogramSamples
> samples(
1190 tester
.GetHistogramSamplesSinceCreation(kQueryTime
));
1191 ASSERT_TRUE(samples
);
1192 // 10 for the adjust, 1 for the measurement.
1193 EXPECT_EQ(11, samples
->sum());
1195 samples
= tester
.GetHistogramSamplesSinceCreation(kUpdateTime
);
1196 EXPECT_EQ(0, samples
->sum());
1198 samples
= tester
.GetHistogramSamplesSinceCreation(kCommitTime
);
1199 EXPECT_EQ(0, samples
->sum());
1201 samples
= tester
.GetHistogramSamplesSinceCreation(kAutoCommitTime
);
1202 EXPECT_EQ(0, samples
->sum());
1205 // Autocommit update allocates time to QueryTime, UpdateTime, and
1207 TEST_F(SQLConnectionTest
, TimeUpdateAutocommit
) {
1208 // Re-open with histogram tag. Use an in-memory database to minimize variance
1209 // due to filesystem.
1211 db().set_histogram_tag("Test");
1212 ASSERT_TRUE(db().OpenInMemory());
1214 sql::test::ScopedMockTimeSource
time_mock(db());
1216 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1217 EXPECT_TRUE(db().Execute(kCreateSql
));
1219 // Function to inject pauses into statements.
1220 sql::test::ScopedScalarFunction
scoper(
1221 db(), "milliadjust", 1, base::Bind(&sqlite_adjust_millis
, &time_mock
));
1223 base::HistogramTester tester
;
1225 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, milliadjust(10))"));
1227 scoped_ptr
<base::HistogramSamples
> samples(
1228 tester
.GetHistogramSamplesSinceCreation(kQueryTime
));
1229 ASSERT_TRUE(samples
);
1230 // 10 for the adjust, 1 for the measurement.
1231 EXPECT_EQ(11, samples
->sum());
1233 samples
= tester
.GetHistogramSamplesSinceCreation(kUpdateTime
);
1234 ASSERT_TRUE(samples
);
1235 // 10 for the adjust, 1 for the measurement.
1236 EXPECT_EQ(11, samples
->sum());
1238 samples
= tester
.GetHistogramSamplesSinceCreation(kCommitTime
);
1239 EXPECT_EQ(0, samples
->sum());
1241 samples
= tester
.GetHistogramSamplesSinceCreation(kAutoCommitTime
);
1242 ASSERT_TRUE(samples
);
1243 // 10 for the adjust, 1 for the measurement.
1244 EXPECT_EQ(11, samples
->sum());
1247 // Update with explicit transaction allocates time to QueryTime, UpdateTime, and
1249 TEST_F(SQLConnectionTest
, TimeUpdateTransaction
) {
1250 // Re-open with histogram tag. Use an in-memory database to minimize variance
1251 // due to filesystem.
1253 db().set_histogram_tag("Test");
1254 ASSERT_TRUE(db().OpenInMemory());
1256 sql::test::ScopedMockTimeSource
time_mock(db());
1258 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1259 EXPECT_TRUE(db().Execute(kCreateSql
));
1261 // Function to inject pauses into statements.
1262 sql::test::ScopedScalarFunction
scoper(
1263 db(), "milliadjust", 1, base::Bind(&sqlite_adjust_millis
, &time_mock
));
1265 base::HistogramTester tester
;
1268 // Make the commit slow.
1269 sql::test::ScopedCommitHook
scoped_hook(
1270 db(), base::Bind(adjust_commit_hook
, &time_mock
, 100));
1271 ASSERT_TRUE(db().BeginTransaction());
1272 EXPECT_TRUE(db().Execute(
1273 "INSERT INTO foo VALUES (11, milliadjust(10))"));
1274 EXPECT_TRUE(db().Execute(
1275 "UPDATE foo SET value = milliadjust(10) WHERE id = 11"));
1276 EXPECT_TRUE(db().CommitTransaction());
1279 scoped_ptr
<base::HistogramSamples
> samples(
1280 tester
.GetHistogramSamplesSinceCreation(kQueryTime
));
1281 ASSERT_TRUE(samples
);
1282 // 10 for insert adjust, 10 for update adjust, 100 for commit adjust, 1 for
1283 // measuring each of BEGIN, INSERT, UPDATE, and COMMIT.
1284 EXPECT_EQ(124, samples
->sum());
1286 samples
= tester
.GetHistogramSamplesSinceCreation(kUpdateTime
);
1287 ASSERT_TRUE(samples
);
1288 // 10 for insert adjust, 10 for update adjust, 100 for commit adjust, 1 for
1289 // measuring each of INSERT, UPDATE, and COMMIT.
1290 EXPECT_EQ(123, samples
->sum());
1292 samples
= tester
.GetHistogramSamplesSinceCreation(kCommitTime
);
1293 ASSERT_TRUE(samples
);
1294 // 100 for commit adjust, 1 for measuring COMMIT.
1295 EXPECT_EQ(101, samples
->sum());
1297 samples
= tester
.GetHistogramSamplesSinceCreation(kAutoCommitTime
);
1298 EXPECT_EQ(0, samples
->sum());