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/proxy.h"
16 #include "sql/statement.h"
17 #include "sql/test/error_callback_support.h"
18 #include "sql/test/scoped_error_ignorer.h"
19 #include "sql/test/test_helpers.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/sqlite/sqlite3.h"
26 // Replaces the database time source with an object that steps forward 1ms on
27 // each check, and which can be jumped forward an arbitrary amount of time
29 class ScopedMockTimeSource
{
31 ScopedMockTimeSource(Connection
& db
)
33 delta_(base::TimeDelta::FromMilliseconds(1)) {
34 // Save the current source and replace it.
35 save_
.swap(db_
.clock_
);
36 db_
.clock_
.reset(new MockTimeSource(*this));
38 ~ScopedMockTimeSource() {
39 // Put original source back.
40 db_
.clock_
.swap(save_
);
43 void adjust(const base::TimeDelta
& delta
) {
44 current_time_
+= delta
;
48 class MockTimeSource
: public TimeSource
{
50 MockTimeSource(ScopedMockTimeSource
& owner
)
53 ~MockTimeSource() override
{}
55 base::TimeTicks
Now() override
{
56 base::TimeTicks
ret(owner_
.current_time_
);
57 owner_
.current_time_
+= owner_
.delta_
;
62 ScopedMockTimeSource
& owner_
;
63 DISALLOW_COPY_AND_ASSIGN(MockTimeSource
);
68 // Saves original source from |db_|.
69 scoped_ptr
<TimeSource
> save_
;
71 // Current time returned by mock.
72 base::TimeTicks current_time_
;
74 // How far to jump on each Now() call.
75 base::TimeDelta delta_
;
77 DISALLOW_COPY_AND_ASSIGN(ScopedMockTimeSource
);
80 // Allow a test to add a SQLite function in a scoped context.
81 class ScopedScalarFunction
{
85 const char* function_name
,
87 base::Callback
<void(sqlite3_context
*,int,sqlite3_value
**)> cb
)
88 : db_(db
.db_
), function_name_(function_name
), cb_(cb
) {
89 sql::sqlite3_create_function_v2(db_
, function_name
, args
, SQLITE_UTF8
,
90 this, &Run
, NULL
, NULL
, NULL
);
92 ~ScopedScalarFunction() {
93 sql::sqlite3_create_function_v2(db_
, function_name_
, 0, SQLITE_UTF8
,
94 NULL
, NULL
, NULL
, NULL
, NULL
);
98 static void Run(sqlite3_context
* context
, int argc
, sqlite3_value
** argv
) {
99 ScopedScalarFunction
* t
= static_cast<ScopedScalarFunction
*>(
100 sqlite3_user_data(context
));
101 t
->cb_
.Run(context
, argc
, argv
);
105 const char* function_name_
;
106 base::Callback
<void(sqlite3_context
*,int,sqlite3_value
**)> cb_
;
108 DISALLOW_COPY_AND_ASSIGN(ScopedScalarFunction
);
111 // Allow a test to add a SQLite commit hook in a scoped context.
112 class ScopedCommitHook
{
114 ScopedCommitHook(sql::Connection
& db
,
115 base::Callback
<int(void)> cb
)
118 sql::sqlite3_commit_hook(db_
, &Run
, this);
120 ~ScopedCommitHook() {
121 sql::sqlite3_commit_hook(db_
, NULL
, NULL
);
125 static int Run(void* p
) {
126 ScopedCommitHook
* t
= static_cast<ScopedCommitHook
*>(p
);
131 base::Callback
<int(void)> cb_
;
133 DISALLOW_COPY_AND_ASSIGN(ScopedCommitHook
);
141 // Helper to return the count of items in sqlite_master. Return -1 in
143 int SqliteMasterCount(sql::Connection
* db
) {
144 const char* kMasterCount
= "SELECT COUNT(*) FROM sqlite_master";
145 sql::Statement
s(db
->GetUniqueStatement(kMasterCount
));
146 return s
.Step() ? s
.ColumnInt(0) : -1;
149 // Track the number of valid references which share the same pointer.
150 // This is used to allow testing an implicitly use-after-free case by
151 // explicitly having the ref count live longer than the object.
154 RefCounter(size_t* counter
)
155 : counter_(counter
) {
158 RefCounter(const RefCounter
& other
)
159 : counter_(other
.counter_
) {
169 DISALLOW_ASSIGN(RefCounter
);
172 // Empty callback for implementation of ErrorCallbackSetHelper().
173 void IgnoreErrorCallback(int error
, sql::Statement
* stmt
) {
176 void ErrorCallbackSetHelper(sql::Connection
* db
,
179 int error
, sql::Statement
* stmt
) {
180 // The ref count should not go to zero when changing the callback.
181 EXPECT_GT(*counter
, 0u);
182 db
->set_error_callback(base::Bind(&IgnoreErrorCallback
));
183 EXPECT_GT(*counter
, 0u);
186 void ErrorCallbackResetHelper(sql::Connection
* db
,
189 int error
, sql::Statement
* stmt
) {
190 // The ref count should not go to zero when clearing the callback.
191 EXPECT_GT(*counter
, 0u);
192 db
->reset_error_callback();
193 EXPECT_GT(*counter
, 0u);
196 #if defined(OS_POSIX)
197 // Set a umask and restore the old mask on destruction. Cribbed from
198 // shared_memory_unittest.cc. Used by POSIX-only UserPermission test.
199 class ScopedUmaskSetter
{
201 explicit ScopedUmaskSetter(mode_t target_mask
) {
202 old_umask_
= umask(target_mask
);
204 ~ScopedUmaskSetter() { umask(old_umask_
); }
207 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter
);
211 class SQLConnectionTest
: public sql::SQLTestBase
{
213 void SetUp() override
{
214 // Any macro histograms which fire before the recorder is initialized cannot
215 // be tested. So this needs to be ahead of Open().
216 base::StatisticsRecorder::Initialize();
218 SQLTestBase::SetUp();
221 // Handle errors by blowing away the database.
222 void RazeErrorCallback(int expected_error
, int error
, sql::Statement
* stmt
) {
223 EXPECT_EQ(expected_error
, error
);
228 TEST_F(SQLConnectionTest
, Execute
) {
229 // Valid statement should return true.
230 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
231 EXPECT_EQ(SQLITE_OK
, db().GetErrorCode());
233 // Invalid statement should fail.
234 ASSERT_EQ(SQLITE_ERROR
,
235 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
236 EXPECT_EQ(SQLITE_ERROR
, db().GetErrorCode());
239 TEST_F(SQLConnectionTest
, ExecuteWithErrorCode
) {
241 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
242 ASSERT_EQ(SQLITE_ERROR
,
243 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
244 ASSERT_EQ(SQLITE_ERROR
,
245 db().ExecuteAndReturnErrorCode(
246 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
249 TEST_F(SQLConnectionTest
, CachedStatement
) {
250 sql::StatementID
id1("foo", 12);
252 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
253 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
255 // Create a new cached statement.
257 sql::Statement
s(db().GetCachedStatement(id1
, "SELECT a FROM foo"));
258 ASSERT_TRUE(s
.is_valid());
260 ASSERT_TRUE(s
.Step());
261 EXPECT_EQ(12, s
.ColumnInt(0));
264 // The statement should be cached still.
265 EXPECT_TRUE(db().HasCachedStatement(id1
));
268 // Get the same statement using different SQL. This should ignore our
269 // SQL and use the cached one (so it will be valid).
270 sql::Statement
s(db().GetCachedStatement(id1
, "something invalid("));
271 ASSERT_TRUE(s
.is_valid());
273 ASSERT_TRUE(s
.Step());
274 EXPECT_EQ(12, s
.ColumnInt(0));
277 // Make sure other statements aren't marked as cached.
278 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE
));
281 TEST_F(SQLConnectionTest
, IsSQLValidTest
) {
282 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
283 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
284 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
287 TEST_F(SQLConnectionTest
, DoesStuffExist
) {
288 // Test DoesTableExist.
289 EXPECT_FALSE(db().DoesTableExist("foo"));
290 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
291 ASSERT_TRUE(db().Execute("CREATE INDEX foo_a ON foo (a)"));
292 EXPECT_TRUE(db().DoesTableExist("foo"));
293 EXPECT_TRUE(db().DoesIndexExist("foo_a"));
295 // Test DoesColumnExist.
296 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
297 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
299 // Testing for a column on a nonexistent table.
300 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
302 // Names are not case sensitive.
303 EXPECT_TRUE(db().DoesTableExist("FOO"));
304 EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
307 TEST_F(SQLConnectionTest
, GetLastInsertRowId
) {
308 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
310 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
312 // Last insert row ID should be valid.
313 int64_t row
= db().GetLastInsertRowId();
316 // It should be the primary key of the row we just inserted.
317 sql::Statement
s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
319 ASSERT_TRUE(s
.Step());
320 EXPECT_EQ(12, s
.ColumnInt(0));
323 TEST_F(SQLConnectionTest
, Rollback
) {
324 ASSERT_TRUE(db().BeginTransaction());
325 ASSERT_TRUE(db().BeginTransaction());
326 EXPECT_EQ(2, db().transaction_nesting());
327 db().RollbackTransaction();
328 EXPECT_FALSE(db().CommitTransaction());
329 EXPECT_TRUE(db().BeginTransaction());
332 // Test the scoped error ignorer by attempting to insert a duplicate
333 // value into an index.
334 TEST_F(SQLConnectionTest
, ScopedIgnoreError
) {
335 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER UNIQUE)";
336 ASSERT_TRUE(db().Execute(kCreateSql
));
337 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
340 sql::ScopedErrorIgnorer ignore_errors
;
341 ignore_errors
.IgnoreError(SQLITE_CONSTRAINT
);
342 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
343 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
347 // Test that clients of GetUntrackedStatement() can test corruption-handling
348 // with ScopedErrorIgnorer.
349 TEST_F(SQLConnectionTest
, ScopedIgnoreUntracked
) {
350 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER UNIQUE)";
351 ASSERT_TRUE(db().Execute(kCreateSql
));
352 ASSERT_FALSE(db().DoesTableExist("bar"));
353 ASSERT_TRUE(db().DoesTableExist("foo"));
354 ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
357 // Corrupt the database so that nothing works, including PRAGMAs.
358 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
361 sql::ScopedErrorIgnorer ignore_errors
;
362 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
363 ASSERT_TRUE(db().Open(db_path()));
364 ASSERT_FALSE(db().DoesTableExist("bar"));
365 ASSERT_FALSE(db().DoesTableExist("foo"));
366 ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
367 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
371 TEST_F(SQLConnectionTest
, ErrorCallback
) {
372 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER UNIQUE)";
373 ASSERT_TRUE(db().Execute(kCreateSql
));
374 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
376 int error
= SQLITE_OK
;
378 sql::ScopedErrorCallback
sec(
379 &db(), base::Bind(&sql::CaptureErrorCallback
, &error
));
380 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
382 // Later versions of SQLite throw SQLITE_CONSTRAINT_UNIQUE. The specific
383 // sub-error isn't really important.
384 EXPECT_EQ(SQLITE_CONSTRAINT
, (error
&0xff));
387 // Callback is no longer in force due to reset.
390 sql::ScopedErrorIgnorer ignore_errors
;
391 ignore_errors
.IgnoreError(SQLITE_CONSTRAINT
);
392 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
393 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
394 EXPECT_EQ(SQLITE_OK
, error
);
397 // base::Bind() can curry arguments to be passed by const reference
398 // to the callback function. If the callback function calls
399 // re/set_error_callback(), the storage for those arguments can be
400 // deleted while the callback function is still executing.
402 // RefCounter() counts how many objects are live using an external
403 // count. The same counter is passed to the callback, so that it
404 // can check directly even if the RefCounter object is no longer
408 sql::ScopedErrorCallback
sec(
409 &db(), base::Bind(&ErrorCallbackSetHelper
,
410 &db(), &count
, RefCounter(&count
)));
412 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
415 // Same test, but reset_error_callback() case.
418 sql::ScopedErrorCallback
sec(
419 &db(), base::Bind(&ErrorCallbackResetHelper
,
420 &db(), &count
, RefCounter(&count
)));
422 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
426 // Test that sql::Connection::Raze() results in a database without the
427 // tables from the original database.
428 TEST_F(SQLConnectionTest
, Raze
) {
429 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
430 ASSERT_TRUE(db().Execute(kCreateSql
));
431 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
433 int pragma_auto_vacuum
= 0;
435 sql::Statement
s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
436 ASSERT_TRUE(s
.Step());
437 pragma_auto_vacuum
= s
.ColumnInt(0);
438 ASSERT_TRUE(pragma_auto_vacuum
== 0 || pragma_auto_vacuum
== 1);
441 // If auto_vacuum is set, there's an extra page to maintain a freelist.
442 const int kExpectedPageCount
= 2 + pragma_auto_vacuum
;
445 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_count"));
446 ASSERT_TRUE(s
.Step());
447 EXPECT_EQ(kExpectedPageCount
, s
.ColumnInt(0));
451 sql::Statement
s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
452 ASSERT_TRUE(s
.Step());
453 EXPECT_EQ("table", s
.ColumnString(0));
454 EXPECT_EQ("foo", s
.ColumnString(1));
455 EXPECT_EQ("foo", s
.ColumnString(2));
456 // Table "foo" is stored in the last page of the file.
457 EXPECT_EQ(kExpectedPageCount
, s
.ColumnInt(3));
458 EXPECT_EQ(kCreateSql
, s
.ColumnString(4));
461 ASSERT_TRUE(db().Raze());
464 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_count"));
465 ASSERT_TRUE(s
.Step());
466 EXPECT_EQ(1, s
.ColumnInt(0));
469 ASSERT_EQ(0, SqliteMasterCount(&db()));
472 sql::Statement
s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
473 ASSERT_TRUE(s
.Step());
474 // The new database has the same auto_vacuum as a fresh database.
475 EXPECT_EQ(pragma_auto_vacuum
, s
.ColumnInt(0));
479 // Test that Raze() maintains page_size.
480 TEST_F(SQLConnectionTest
, RazePageSize
) {
481 // Fetch the default page size and double it for use in this test.
482 // Scoped to release statement before Close().
483 int default_page_size
= 0;
485 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_size"));
486 ASSERT_TRUE(s
.Step());
487 default_page_size
= s
.ColumnInt(0);
489 ASSERT_GT(default_page_size
, 0);
490 const int kPageSize
= 2 * default_page_size
;
492 // Re-open the database to allow setting the page size.
494 db().set_page_size(kPageSize
);
495 ASSERT_TRUE(db().Open(db_path()));
497 // page_size should match the indicated value.
498 sql::Statement
s(db().GetUniqueStatement("PRAGMA page_size"));
499 ASSERT_TRUE(s
.Step());
500 ASSERT_EQ(kPageSize
, s
.ColumnInt(0));
502 // After raze, page_size should still match the indicated value.
503 ASSERT_TRUE(db().Raze());
505 ASSERT_TRUE(s
.Step());
506 ASSERT_EQ(kPageSize
, s
.ColumnInt(0));
509 // Test that Raze() results are seen in other connections.
510 TEST_F(SQLConnectionTest
, RazeMultiple
) {
511 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
512 ASSERT_TRUE(db().Execute(kCreateSql
));
514 sql::Connection other_db
;
515 ASSERT_TRUE(other_db
.Open(db_path()));
517 // Check that the second connection sees the table.
518 ASSERT_EQ(1, SqliteMasterCount(&other_db
));
520 ASSERT_TRUE(db().Raze());
522 // The second connection sees the updated database.
523 ASSERT_EQ(0, SqliteMasterCount(&other_db
));
526 // TODO(erg): Enable this in the next patch once I add locking.
527 #if !defined(MOJO_APPTEST_IMPL)
528 TEST_F(SQLConnectionTest
, RazeLocked
) {
529 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
530 ASSERT_TRUE(db().Execute(kCreateSql
));
532 // Open a transaction and write some data in a second connection.
533 // This will acquire a PENDING or EXCLUSIVE transaction, which will
534 // cause the raze to fail.
535 sql::Connection other_db
;
536 ASSERT_TRUE(other_db
.Open(db_path()));
537 ASSERT_TRUE(other_db
.BeginTransaction());
538 const char* kInsertSql
= "INSERT INTO foo VALUES (1, 'data')";
539 ASSERT_TRUE(other_db
.Execute(kInsertSql
));
541 ASSERT_FALSE(db().Raze());
543 // Works after COMMIT.
544 ASSERT_TRUE(other_db
.CommitTransaction());
545 ASSERT_TRUE(db().Raze());
547 // Re-create the database.
548 ASSERT_TRUE(db().Execute(kCreateSql
));
549 ASSERT_TRUE(db().Execute(kInsertSql
));
551 // An unfinished read transaction in the other connection also
553 const char *kQuery
= "SELECT COUNT(*) FROM foo";
554 sql::Statement
s(other_db
.GetUniqueStatement(kQuery
));
555 ASSERT_TRUE(s
.Step());
556 ASSERT_FALSE(db().Raze());
558 // Complete the statement unlocks the database.
559 ASSERT_FALSE(s
.Step());
560 ASSERT_TRUE(db().Raze());
564 // Verify that Raze() can handle an empty file. SQLite should treat
565 // this as an empty database.
566 TEST_F(SQLConnectionTest
, RazeEmptyDB
) {
567 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
568 ASSERT_TRUE(db().Execute(kCreateSql
));
573 ASSERT_TRUE(db().Open(db_path()));
574 ASSERT_TRUE(db().Raze());
575 EXPECT_EQ(0, SqliteMasterCount(&db()));
578 // Verify that Raze() can handle a file of junk.
579 TEST_F(SQLConnectionTest
, RazeNOTADB
) {
581 sql::Connection::Delete(db_path());
582 ASSERT_FALSE(GetPathExists(db_path()));
584 WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE_AND_TRUNCATE
);
585 ASSERT_TRUE(GetPathExists(db_path()));
587 // SQLite will successfully open the handle, but fail when running PRAGMA
588 // statements that access the database.
590 sql::ScopedErrorIgnorer ignore_errors
;
592 // Earlier versions of Chromium compiled against SQLite 3.6.7.3, which
593 // returned SQLITE_IOERR_SHORT_READ in this case. Some platforms may still
594 // compile against an earlier SQLite via USE_SYSTEM_SQLITE.
595 if (ignore_errors
.SQLiteLibVersionNumber() < 3008005) {
596 ignore_errors
.IgnoreError(SQLITE_IOERR_SHORT_READ
);
598 ignore_errors
.IgnoreError(SQLITE_NOTADB
);
601 EXPECT_TRUE(db().Open(db_path()));
602 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
604 EXPECT_TRUE(db().Raze());
607 // Now empty, the open should open an empty database.
608 EXPECT_TRUE(db().Open(db_path()));
609 EXPECT_EQ(0, SqliteMasterCount(&db()));
612 // Verify that Raze() can handle a database overwritten with garbage.
613 TEST_F(SQLConnectionTest
, RazeNOTADB2
) {
614 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
615 ASSERT_TRUE(db().Execute(kCreateSql
));
616 ASSERT_EQ(1, SqliteMasterCount(&db()));
619 WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE
);
621 // SQLite will successfully open the handle, but will fail with
622 // SQLITE_NOTADB on pragma statemenets which attempt to read the
625 sql::ScopedErrorIgnorer ignore_errors
;
626 ignore_errors
.IgnoreError(SQLITE_NOTADB
);
627 EXPECT_TRUE(db().Open(db_path()));
628 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
630 EXPECT_TRUE(db().Raze());
633 // Now empty, the open should succeed with an empty database.
634 EXPECT_TRUE(db().Open(db_path()));
635 EXPECT_EQ(0, SqliteMasterCount(&db()));
638 // Test that a callback from Open() can raze the database. This is
639 // essential for cases where the Open() can fail entirely, so the
640 // Raze() cannot happen later. Additionally test that when the
641 // callback does this during Open(), the open is retried and succeeds.
642 TEST_F(SQLConnectionTest
, RazeCallbackReopen
) {
643 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
644 ASSERT_TRUE(db().Execute(kCreateSql
));
645 ASSERT_EQ(1, SqliteMasterCount(&db()));
648 // Corrupt the database so that nothing works, including PRAGMAs.
649 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
651 // Open() will succeed, even though the PRAGMA calls within will
652 // fail with SQLITE_CORRUPT, as will this PRAGMA.
654 sql::ScopedErrorIgnorer ignore_errors
;
655 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
656 ASSERT_TRUE(db().Open(db_path()));
657 ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
659 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
662 db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback
,
663 base::Unretained(this),
666 // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
667 // callback will call RazeAndClose(). Open() will then fail and be
668 // retried. The second Open() on the empty database will succeed
670 ASSERT_TRUE(db().Open(db_path()));
671 ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
672 EXPECT_EQ(0, SqliteMasterCount(&db()));
675 // Basic test of RazeAndClose() operation.
676 TEST_F(SQLConnectionTest
, RazeAndClose
) {
677 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
678 const char* kPopulateSql
= "INSERT INTO foo (value) VALUES (12)";
680 // Test that RazeAndClose() closes the database, and that the
681 // database is empty when re-opened.
682 ASSERT_TRUE(db().Execute(kCreateSql
));
683 ASSERT_TRUE(db().Execute(kPopulateSql
));
684 ASSERT_TRUE(db().RazeAndClose());
685 ASSERT_FALSE(db().is_open());
687 ASSERT_TRUE(db().Open(db_path()));
688 ASSERT_EQ(0, SqliteMasterCount(&db()));
690 // Test that RazeAndClose() can break transactions.
691 ASSERT_TRUE(db().Execute(kCreateSql
));
692 ASSERT_TRUE(db().Execute(kPopulateSql
));
693 ASSERT_TRUE(db().BeginTransaction());
694 ASSERT_TRUE(db().RazeAndClose());
695 ASSERT_FALSE(db().is_open());
696 ASSERT_FALSE(db().CommitTransaction());
698 ASSERT_TRUE(db().Open(db_path()));
699 ASSERT_EQ(0, SqliteMasterCount(&db()));
702 // Test that various operations fail without crashing after
704 TEST_F(SQLConnectionTest
, RazeAndCloseDiagnostics
) {
705 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
706 const char* kPopulateSql
= "INSERT INTO foo (value) VALUES (12)";
707 const char* kSimpleSql
= "SELECT 1";
709 ASSERT_TRUE(db().Execute(kCreateSql
));
710 ASSERT_TRUE(db().Execute(kPopulateSql
));
712 // Test baseline expectations.
714 ASSERT_TRUE(db().DoesTableExist("foo"));
715 ASSERT_TRUE(db().IsSQLValid(kSimpleSql
));
716 ASSERT_EQ(SQLITE_OK
, db().ExecuteAndReturnErrorCode(kSimpleSql
));
717 ASSERT_TRUE(db().Execute(kSimpleSql
));
718 ASSERT_TRUE(db().is_open());
720 sql::Statement
s(db().GetUniqueStatement(kSimpleSql
));
721 ASSERT_TRUE(s
.Step());
724 sql::Statement
s(db().GetCachedStatement(SQL_FROM_HERE
, kSimpleSql
));
725 ASSERT_TRUE(s
.Step());
727 ASSERT_TRUE(db().BeginTransaction());
728 ASSERT_TRUE(db().CommitTransaction());
729 ASSERT_TRUE(db().BeginTransaction());
730 db().RollbackTransaction();
732 ASSERT_TRUE(db().RazeAndClose());
734 // At this point, they should all fail, but not crash.
736 ASSERT_FALSE(db().DoesTableExist("foo"));
737 ASSERT_FALSE(db().IsSQLValid(kSimpleSql
));
738 ASSERT_EQ(SQLITE_ERROR
, db().ExecuteAndReturnErrorCode(kSimpleSql
));
739 ASSERT_FALSE(db().Execute(kSimpleSql
));
740 ASSERT_FALSE(db().is_open());
742 sql::Statement
s(db().GetUniqueStatement(kSimpleSql
));
743 ASSERT_FALSE(s
.Step());
746 sql::Statement
s(db().GetCachedStatement(SQL_FROM_HERE
, kSimpleSql
));
747 ASSERT_FALSE(s
.Step());
749 ASSERT_FALSE(db().BeginTransaction());
750 ASSERT_FALSE(db().CommitTransaction());
751 ASSERT_FALSE(db().BeginTransaction());
752 db().RollbackTransaction();
754 // Close normally to reset the poisoned flag.
757 // DEATH tests not supported on Android or iOS.
758 #if !defined(OS_ANDROID) && !defined(OS_IOS)
759 // Once the real Close() has been called, various calls enforce API
760 // usage by becoming fatal in debug mode. Since DEATH tests are
761 // expensive, just test one of them.
762 if (DLOG_IS_ON(FATAL
)) {
764 db().IsSQLValid(kSimpleSql
);
765 }, "Illegal use of connection without a db");
770 // TODO(shess): Spin up a background thread to hold other_db, to more
771 // closely match real life. That would also allow testing
772 // RazeWithTimeout().
774 #if defined(OS_ANDROID)
775 TEST_F(SQLConnectionTest
, SetTempDirForSQL
) {
777 sql::MetaTable meta_table
;
778 // Below call needs a temporary directory in sqlite3
779 // On Android, it can pass only when the temporary directory is set.
780 // Otherwise, sqlite3 doesn't find the correct directory to store
781 // temporary files and will report the error 'unable to open
783 ASSERT_TRUE(meta_table
.Init(&db(), 4, 4));
787 TEST_F(SQLConnectionTest
, Delete
) {
788 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
791 // Should have both a main database file and a journal file because
792 // of journal_mode TRUNCATE.
793 base::FilePath
journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
794 ASSERT_TRUE(GetPathExists(db_path()));
795 ASSERT_TRUE(GetPathExists(journal
));
797 sql::Connection::Delete(db_path());
798 EXPECT_FALSE(GetPathExists(db_path()));
799 EXPECT_FALSE(GetPathExists(journal
));
802 // This test manually sets on disk permissions; this doesn't apply to the mojo
804 #if defined(OS_POSIX) && !defined(MOJO_APPTEST_IMPL)
805 // Test that set_restrict_to_user() trims database permissions so that
806 // only the owner (and root) can read.
807 TEST_F(SQLConnectionTest
, UserPermission
) {
808 // If the bots all had a restrictive umask setting such that
809 // databases are always created with only the owner able to read
810 // them, then the code could break without breaking the tests.
811 // Temporarily provide a more permissive umask.
813 sql::Connection::Delete(db_path());
814 ASSERT_FALSE(GetPathExists(db_path()));
815 ScopedUmaskSetter
permissive_umask(S_IWGRP
| S_IWOTH
);
816 ASSERT_TRUE(db().Open(db_path()));
818 // Cause the journal file to be created. If the default
819 // journal_mode is changed back to DELETE, then parts of this test
820 // will need to be updated.
821 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
823 base::FilePath
journal(db_path().value() + FILE_PATH_LITERAL("-journal"));
826 // Given a permissive umask, the database is created with permissive
827 // read access for the database and journal.
828 ASSERT_TRUE(GetPathExists(db_path()));
829 ASSERT_TRUE(GetPathExists(journal
));
830 mode
= base::FILE_PERMISSION_MASK
;
831 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode
));
832 ASSERT_NE((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
833 mode
= base::FILE_PERMISSION_MASK
;
834 EXPECT_TRUE(base::GetPosixFilePermissions(journal
, &mode
));
835 ASSERT_NE((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
837 // Re-open with restricted permissions and verify that the modes
838 // changed for both the main database and the journal.
840 db().set_restrict_to_user();
841 ASSERT_TRUE(db().Open(db_path()));
842 ASSERT_TRUE(GetPathExists(db_path()));
843 ASSERT_TRUE(GetPathExists(journal
));
844 mode
= base::FILE_PERMISSION_MASK
;
845 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode
));
846 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
847 mode
= base::FILE_PERMISSION_MASK
;
848 EXPECT_TRUE(base::GetPosixFilePermissions(journal
, &mode
));
849 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
851 // Delete and re-create the database, the restriction should still apply.
853 sql::Connection::Delete(db_path());
854 ASSERT_TRUE(db().Open(db_path()));
855 ASSERT_TRUE(GetPathExists(db_path()));
856 ASSERT_FALSE(GetPathExists(journal
));
857 mode
= base::FILE_PERMISSION_MASK
;
858 EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode
));
859 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
861 // Verify that journal creation inherits the restriction.
862 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
863 ASSERT_TRUE(GetPathExists(journal
));
864 mode
= base::FILE_PERMISSION_MASK
;
865 EXPECT_TRUE(base::GetPosixFilePermissions(journal
, &mode
));
866 ASSERT_EQ((mode
& base::FILE_PERMISSION_USER_MASK
), mode
);
868 #endif // defined(OS_POSIX)
870 // Test that errors start happening once Poison() is called.
871 TEST_F(SQLConnectionTest
, Poison
) {
872 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
874 // Before the Poison() call, things generally work.
875 EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
876 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
878 sql::Statement
s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
879 ASSERT_TRUE(s
.is_valid());
880 ASSERT_TRUE(s
.Step());
883 // Get a statement which is valid before and will exist across Poison().
884 sql::Statement
valid_statement(
885 db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
886 ASSERT_TRUE(valid_statement
.is_valid());
887 ASSERT_TRUE(valid_statement
.Step());
888 valid_statement
.Reset(true);
892 // After the Poison() call, things fail.
893 EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
894 EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
896 sql::Statement
s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
897 ASSERT_FALSE(s
.is_valid());
898 ASSERT_FALSE(s
.Step());
901 // The existing statement has become invalid.
902 ASSERT_FALSE(valid_statement
.is_valid());
903 ASSERT_FALSE(valid_statement
.Step());
906 // Test attaching and detaching databases from the connection.
907 TEST_F(SQLConnectionTest
, Attach
) {
908 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
910 // Create a database to attach to.
911 base::FilePath attach_path
=
912 db_path().DirName().AppendASCII("SQLConnectionAttach.db");
913 const char kAttachmentPoint
[] = "other";
915 sql::Connection other_db
;
916 ASSERT_TRUE(other_db
.Open(attach_path
));
917 EXPECT_TRUE(other_db
.Execute("CREATE TABLE bar (a, b)"));
918 EXPECT_TRUE(other_db
.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
921 // Cannot see the attached database, yet.
922 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
924 // Attach fails in a transaction.
925 EXPECT_TRUE(db().BeginTransaction());
927 sql::ScopedErrorIgnorer ignore_errors
;
928 ignore_errors
.IgnoreError(SQLITE_ERROR
);
929 EXPECT_FALSE(db().AttachDatabase(attach_path
, kAttachmentPoint
));
930 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
933 // Attach succeeds when the transaction is closed.
934 db().RollbackTransaction();
935 EXPECT_TRUE(db().AttachDatabase(attach_path
, kAttachmentPoint
));
936 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
938 // Queries can touch both databases.
939 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
941 sql::Statement
s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
942 ASSERT_TRUE(s
.Step());
943 EXPECT_EQ(1, s
.ColumnInt(0));
946 // Detach also fails in a transaction.
947 EXPECT_TRUE(db().BeginTransaction());
949 sql::ScopedErrorIgnorer ignore_errors
;
950 ignore_errors
.IgnoreError(SQLITE_ERROR
);
951 EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint
));
952 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
953 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
956 // Detach succeeds outside of a transaction.
957 db().RollbackTransaction();
958 EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint
));
960 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
963 TEST_F(SQLConnectionTest
, Basic_QuickIntegrityCheck
) {
964 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
965 ASSERT_TRUE(db().Execute(kCreateSql
));
966 EXPECT_TRUE(db().QuickIntegrityCheck());
969 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
972 sql::ScopedErrorIgnorer ignore_errors
;
973 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
974 ASSERT_TRUE(db().Open(db_path()));
975 EXPECT_FALSE(db().QuickIntegrityCheck());
976 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
980 TEST_F(SQLConnectionTest
, Basic_FullIntegrityCheck
) {
981 const std::string
kOk("ok");
982 std::vector
<std::string
> messages
;
984 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
985 ASSERT_TRUE(db().Execute(kCreateSql
));
986 EXPECT_TRUE(db().FullIntegrityCheck(&messages
));
987 EXPECT_EQ(1u, messages
.size());
988 EXPECT_EQ(kOk
, messages
[0]);
991 ASSERT_TRUE(CorruptSizeInHeaderOfDB());
994 sql::ScopedErrorIgnorer ignore_errors
;
995 ignore_errors
.IgnoreError(SQLITE_CORRUPT
);
996 ASSERT_TRUE(db().Open(db_path()));
997 EXPECT_TRUE(db().FullIntegrityCheck(&messages
));
998 EXPECT_LT(1u, messages
.size());
999 EXPECT_NE(kOk
, messages
[0]);
1000 ASSERT_TRUE(ignore_errors
.CheckIgnoredErrors());
1003 // TODO(shess): CorruptTableOrIndex could be used to produce a
1004 // file that would pass the quick check and fail the full check.
1007 // Test Sqlite.Stats histogram for execute-oriented calls.
1008 TEST_F(SQLConnectionTest
, EventsExecute
) {
1009 // Re-open with histogram tag.
1011 db().set_histogram_tag("Test");
1012 ASSERT_TRUE(db().Open(db_path()));
1014 // Open() uses Execute() extensively, don't track those calls.
1015 base::HistogramTester tester
;
1017 const char kHistogramName
[] = "Sqlite.Stats.Test";
1018 const char kGlobalHistogramName
[] = "Sqlite.Stats";
1020 ASSERT_TRUE(db().BeginTransaction());
1021 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1022 EXPECT_TRUE(db().Execute(kCreateSql
));
1023 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, 'text')"));
1024 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, 'text')"));
1025 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (12, 'text')"));
1026 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (13, 'text')"));
1027 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (14, 'text')"));
1028 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (15, 'text');"
1029 "INSERT INTO foo VALUES (16, 'text');"
1030 "INSERT INTO foo VALUES (17, 'text');"
1031 "INSERT INTO foo VALUES (18, 'text');"
1032 "INSERT INTO foo VALUES (19, 'text')"));
1033 ASSERT_TRUE(db().CommitTransaction());
1034 ASSERT_TRUE(db().BeginTransaction());
1035 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (20, 'text')"));
1036 db().RollbackTransaction();
1037 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (20, 'text')"));
1038 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (21, 'text')"));
1040 // The create, 5 inserts, multi-statement insert, rolled-back insert, 2
1041 // inserts outside transaction.
1042 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_EXECUTE
, 10);
1043 tester
.ExpectBucketCount(kGlobalHistogramName
,
1044 sql::Connection::EVENT_EXECUTE
, 10);
1046 // All of the executes, with the multi-statement inserts broken out, plus one
1047 // for each begin, commit, and rollback.
1048 tester
.ExpectBucketCount(kHistogramName
,
1049 sql::Connection::EVENT_STATEMENT_RUN
, 18);
1050 tester
.ExpectBucketCount(kGlobalHistogramName
,
1051 sql::Connection::EVENT_STATEMENT_RUN
, 18);
1053 tester
.ExpectBucketCount(kHistogramName
,
1054 sql::Connection::EVENT_STATEMENT_ROWS
, 0);
1055 tester
.ExpectBucketCount(kGlobalHistogramName
,
1056 sql::Connection::EVENT_STATEMENT_ROWS
, 0);
1057 tester
.ExpectBucketCount(kHistogramName
,
1058 sql::Connection::EVENT_STATEMENT_SUCCESS
, 18);
1059 tester
.ExpectBucketCount(kGlobalHistogramName
,
1060 sql::Connection::EVENT_STATEMENT_SUCCESS
, 18);
1062 // The 2 inserts outside the transaction.
1063 tester
.ExpectBucketCount(kHistogramName
,
1064 sql::Connection::EVENT_CHANGES_AUTOCOMMIT
, 2);
1065 tester
.ExpectBucketCount(kGlobalHistogramName
,
1066 sql::Connection::EVENT_CHANGES_AUTOCOMMIT
, 2);
1068 // 11 inserts inside transactions.
1069 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_CHANGES
, 11);
1070 tester
.ExpectBucketCount(kGlobalHistogramName
,
1071 sql::Connection::EVENT_CHANGES
, 11);
1073 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_BEGIN
, 2);
1074 tester
.ExpectBucketCount(kGlobalHistogramName
,
1075 sql::Connection::EVENT_BEGIN
, 2);
1076 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_COMMIT
, 1);
1077 tester
.ExpectBucketCount(kGlobalHistogramName
,
1078 sql::Connection::EVENT_COMMIT
, 1);
1079 tester
.ExpectBucketCount(kHistogramName
, sql::Connection::EVENT_ROLLBACK
, 1);
1080 tester
.ExpectBucketCount(kGlobalHistogramName
,
1081 sql::Connection::EVENT_ROLLBACK
, 1);
1084 // Test Sqlite.Stats histogram for prepared statements.
1085 TEST_F(SQLConnectionTest
, EventsStatement
) {
1086 // Re-open with histogram tag.
1088 db().set_histogram_tag("Test");
1089 ASSERT_TRUE(db().Open(db_path()));
1091 const char kHistogramName
[] = "Sqlite.Stats.Test";
1092 const char kGlobalHistogramName
[] = "Sqlite.Stats";
1094 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1095 EXPECT_TRUE(db().Execute(kCreateSql
));
1096 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, 'text')"));
1097 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (11, 'text')"));
1098 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (12, 'text')"));
1101 base::HistogramTester tester
;
1104 sql::Statement
s(db().GetUniqueStatement("SELECT value FROM foo"));
1109 tester
.ExpectBucketCount(kHistogramName
,
1110 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1111 tester
.ExpectBucketCount(kGlobalHistogramName
,
1112 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1113 tester
.ExpectBucketCount(kHistogramName
,
1114 sql::Connection::EVENT_STATEMENT_ROWS
, 3);
1115 tester
.ExpectBucketCount(kGlobalHistogramName
,
1116 sql::Connection::EVENT_STATEMENT_ROWS
, 3);
1117 tester
.ExpectBucketCount(kHistogramName
,
1118 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1119 tester
.ExpectBucketCount(kGlobalHistogramName
,
1120 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1124 base::HistogramTester tester
;
1127 sql::Statement
s(db().GetUniqueStatement(
1128 "SELECT value FROM foo WHERE id > 10"));
1133 tester
.ExpectBucketCount(kHistogramName
,
1134 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1135 tester
.ExpectBucketCount(kGlobalHistogramName
,
1136 sql::Connection::EVENT_STATEMENT_RUN
, 1);
1137 tester
.ExpectBucketCount(kHistogramName
,
1138 sql::Connection::EVENT_STATEMENT_ROWS
, 2);
1139 tester
.ExpectBucketCount(kGlobalHistogramName
,
1140 sql::Connection::EVENT_STATEMENT_ROWS
, 2);
1141 tester
.ExpectBucketCount(kHistogramName
,
1142 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1143 tester
.ExpectBucketCount(kGlobalHistogramName
,
1144 sql::Connection::EVENT_STATEMENT_SUCCESS
, 1);
1148 // SQLite function to adjust mock time by |argv[0]| milliseconds.
1149 void sqlite_adjust_millis(sql::test::ScopedMockTimeSource
* time_mock
,
1150 sqlite3_context
* context
,
1151 int argc
, sqlite3_value
** argv
) {
1152 int64 milliseconds
= argc
> 0 ? sqlite3_value_int64(argv
[0]) : 1000;
1153 time_mock
->adjust(base::TimeDelta::FromMilliseconds(milliseconds
));
1154 sqlite3_result_int64(context
, milliseconds
);
1157 // Adjust mock time by |milliseconds| on commit.
1158 int adjust_commit_hook(sql::test::ScopedMockTimeSource
* time_mock
,
1159 int64 milliseconds
) {
1160 time_mock
->adjust(base::TimeDelta::FromMilliseconds(milliseconds
));
1164 const char kCommitTime
[] = "Sqlite.CommitTime.Test";
1165 const char kAutoCommitTime
[] = "Sqlite.AutoCommitTime.Test";
1166 const char kUpdateTime
[] = "Sqlite.UpdateTime.Test";
1167 const char kQueryTime
[] = "Sqlite.QueryTime.Test";
1169 // Read-only query allocates time to QueryTime, but not others.
1170 TEST_F(SQLConnectionTest
, TimeQuery
) {
1171 // Re-open with histogram tag. Use an in-memory database to minimize variance
1172 // due to filesystem.
1174 db().set_histogram_tag("Test");
1175 ASSERT_TRUE(db().OpenInMemory());
1177 sql::test::ScopedMockTimeSource
time_mock(db());
1179 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1180 EXPECT_TRUE(db().Execute(kCreateSql
));
1182 // Function to inject pauses into statements.
1183 sql::test::ScopedScalarFunction
scoper(
1184 db(), "milliadjust", 1, base::Bind(&sqlite_adjust_millis
, &time_mock
));
1186 base::HistogramTester tester
;
1188 EXPECT_TRUE(db().Execute("SELECT milliadjust(10)"));
1190 scoped_ptr
<base::HistogramSamples
> samples(
1191 tester
.GetHistogramSamplesSinceCreation(kQueryTime
));
1192 ASSERT_TRUE(samples
);
1193 // 10 for the adjust, 1 for the measurement.
1194 EXPECT_EQ(11, samples
->sum());
1196 samples
= tester
.GetHistogramSamplesSinceCreation(kUpdateTime
);
1197 EXPECT_TRUE(!samples
|| samples
->sum() == 0);
1199 samples
= tester
.GetHistogramSamplesSinceCreation(kCommitTime
);
1200 EXPECT_TRUE(!samples
|| samples
->sum() == 0);
1202 samples
= tester
.GetHistogramSamplesSinceCreation(kAutoCommitTime
);
1203 EXPECT_TRUE(!samples
|| samples
->sum() == 0);
1206 // Autocommit update allocates time to QueryTime, UpdateTime, and
1208 TEST_F(SQLConnectionTest
, TimeUpdateAutocommit
) {
1209 // Re-open with histogram tag. Use an in-memory database to minimize variance
1210 // due to filesystem.
1212 db().set_histogram_tag("Test");
1213 ASSERT_TRUE(db().OpenInMemory());
1215 sql::test::ScopedMockTimeSource
time_mock(db());
1217 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1218 EXPECT_TRUE(db().Execute(kCreateSql
));
1220 // Function to inject pauses into statements.
1221 sql::test::ScopedScalarFunction
scoper(
1222 db(), "milliadjust", 1, base::Bind(&sqlite_adjust_millis
, &time_mock
));
1224 base::HistogramTester tester
;
1226 EXPECT_TRUE(db().Execute("INSERT INTO foo VALUES (10, milliadjust(10))"));
1228 scoped_ptr
<base::HistogramSamples
> samples(
1229 tester
.GetHistogramSamplesSinceCreation(kQueryTime
));
1230 ASSERT_TRUE(samples
);
1231 // 10 for the adjust, 1 for the measurement.
1232 EXPECT_EQ(11, samples
->sum());
1234 samples
= tester
.GetHistogramSamplesSinceCreation(kUpdateTime
);
1235 ASSERT_TRUE(samples
);
1236 // 10 for the adjust, 1 for the measurement.
1237 EXPECT_EQ(11, samples
->sum());
1239 samples
= tester
.GetHistogramSamplesSinceCreation(kCommitTime
);
1240 EXPECT_TRUE(!samples
|| samples
->sum() == 0);
1242 samples
= tester
.GetHistogramSamplesSinceCreation(kAutoCommitTime
);
1243 ASSERT_TRUE(samples
);
1244 // 10 for the adjust, 1 for the measurement.
1245 EXPECT_EQ(11, samples
->sum());
1248 // Update with explicit transaction allocates time to QueryTime, UpdateTime, and
1250 TEST_F(SQLConnectionTest
, TimeUpdateTransaction
) {
1251 // Re-open with histogram tag. Use an in-memory database to minimize variance
1252 // due to filesystem.
1254 db().set_histogram_tag("Test");
1255 ASSERT_TRUE(db().OpenInMemory());
1257 sql::test::ScopedMockTimeSource
time_mock(db());
1259 const char* kCreateSql
= "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
1260 EXPECT_TRUE(db().Execute(kCreateSql
));
1262 // Function to inject pauses into statements.
1263 sql::test::ScopedScalarFunction
scoper(
1264 db(), "milliadjust", 1, base::Bind(&sqlite_adjust_millis
, &time_mock
));
1266 base::HistogramTester tester
;
1269 // Make the commit slow.
1270 sql::test::ScopedCommitHook
scoped_hook(
1271 db(), base::Bind(adjust_commit_hook
, &time_mock
, 100));
1272 ASSERT_TRUE(db().BeginTransaction());
1273 EXPECT_TRUE(db().Execute(
1274 "INSERT INTO foo VALUES (11, milliadjust(10))"));
1275 EXPECT_TRUE(db().Execute(
1276 "UPDATE foo SET value = milliadjust(10) WHERE id = 11"));
1277 EXPECT_TRUE(db().CommitTransaction());
1280 scoped_ptr
<base::HistogramSamples
> samples(
1281 tester
.GetHistogramSamplesSinceCreation(kQueryTime
));
1282 ASSERT_TRUE(samples
);
1283 // 10 for insert adjust, 10 for update adjust, 100 for commit adjust, 1 for
1284 // measuring each of BEGIN, INSERT, UPDATE, and COMMIT.
1285 EXPECT_EQ(124, samples
->sum());
1287 samples
= tester
.GetHistogramSamplesSinceCreation(kUpdateTime
);
1288 ASSERT_TRUE(samples
);
1289 // 10 for insert adjust, 10 for update adjust, 100 for commit adjust, 1 for
1290 // measuring each of INSERT, UPDATE, and COMMIT.
1291 EXPECT_EQ(123, samples
->sum());
1293 samples
= tester
.GetHistogramSamplesSinceCreation(kCommitTime
);
1294 ASSERT_TRUE(samples
);
1295 // 100 for commit adjust, 1 for measuring COMMIT.
1296 EXPECT_EQ(101, samples
->sum());
1298 samples
= tester
.GetHistogramSamplesSinceCreation(kAutoCommitTime
);
1299 EXPECT_TRUE(!samples
|| samples
->sum() == 0);