1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/bind.h" 6 #include "base/file_util.h" 7 #include "base/files/scoped_temp_dir.h" 8 #include "base/logging.h" 9 #include "sql/connection.h" 10 #include "sql/meta_table.h" 11 #include "sql/statement.h" 12 #include "sql/test/error_callback_support.h" 13 #include "sql/test/scoped_error_ignorer.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "third_party/sqlite/sqlite3.h" 16 17 namespace { 18 19 // Helper to return the count of items in sqlite_master. Return -1 in 20 // case of error. 21 int SqliteMasterCount(sql::Connection* db) { 22 const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master"; 23 sql::Statement s(db->GetUniqueStatement(kMasterCount)); 24 return s.Step() ? s.ColumnInt(0) : -1; 25 } 26 27 // Track the number of valid references which share the same pointer. 28 // This is used to allow testing an implicitly use-after-free case by 29 // explicitly having the ref count live longer than the object. 30 class RefCounter { 31 public: 32 RefCounter(size_t* counter) 33 : counter_(counter) { 34 (*counter_)++; 35 } 36 RefCounter(const RefCounter& other) 37 : counter_(other.counter_) { 38 (*counter_)++; 39 } 40 ~RefCounter() { 41 (*counter_)--; 42 } 43 44 private: 45 size_t* counter_; 46 47 DISALLOW_ASSIGN(RefCounter); 48 }; 49 50 // Empty callback for implementation of ErrorCallbackSetHelper(). 51 void IgnoreErrorCallback(int error, sql::Statement* stmt) { 52 } 53 54 void ErrorCallbackSetHelper(sql::Connection* db, 55 size_t* counter, 56 const RefCounter& r, 57 int error, sql::Statement* stmt) { 58 // The ref count should not go to zero when changing the callback. 59 EXPECT_GT(*counter, 0u); 60 db->set_error_callback(base::Bind(&IgnoreErrorCallback)); 61 EXPECT_GT(*counter, 0u); 62 } 63 64 void ErrorCallbackResetHelper(sql::Connection* db, 65 size_t* counter, 66 const RefCounter& r, 67 int error, sql::Statement* stmt) { 68 // The ref count should not go to zero when clearing the callback. 69 EXPECT_GT(*counter, 0u); 70 db->reset_error_callback(); 71 EXPECT_GT(*counter, 0u); 72 } 73 74 #if defined(OS_POSIX) 75 // Set a umask and restore the old mask on destruction. Cribbed from 76 // shared_memory_unittest.cc. Used by POSIX-only UserPermission test. 77 class ScopedUmaskSetter { 78 public: 79 explicit ScopedUmaskSetter(mode_t target_mask) { 80 old_umask_ = umask(target_mask); 81 } 82 ~ScopedUmaskSetter() { umask(old_umask_); } 83 private: 84 mode_t old_umask_; 85 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter); 86 }; 87 #endif 88 89 class SQLConnectionTest : public testing::Test { 90 public: 91 SQLConnectionTest() {} 92 93 virtual void SetUp() { 94 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 95 ASSERT_TRUE(db_.Open(db_path())); 96 } 97 98 virtual void TearDown() { 99 db_.Close(); 100 } 101 102 sql::Connection& db() { return db_; } 103 104 base::FilePath db_path() { 105 return temp_dir_.path().AppendASCII("SQLConnectionTest.db"); 106 } 107 108 // Handle errors by blowing away the database. 109 void RazeErrorCallback(int expected_error, int error, sql::Statement* stmt) { 110 EXPECT_EQ(expected_error, error); 111 db_.RazeAndClose(); 112 } 113 114 private: 115 base::ScopedTempDir temp_dir_; 116 sql::Connection db_; 117 }; 118 119 TEST_F(SQLConnectionTest, Execute) { 120 // Valid statement should return true. 121 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); 122 EXPECT_EQ(SQLITE_OK, db().GetErrorCode()); 123 124 // Invalid statement should fail. 125 ASSERT_EQ(SQLITE_ERROR, 126 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b")); 127 EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode()); 128 } 129 130 TEST_F(SQLConnectionTest, ExecuteWithErrorCode) { 131 ASSERT_EQ(SQLITE_OK, 132 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)")); 133 ASSERT_EQ(SQLITE_ERROR, 134 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE")); 135 ASSERT_EQ(SQLITE_ERROR, 136 db().ExecuteAndReturnErrorCode( 137 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)")); 138 } 139 140 TEST_F(SQLConnectionTest, CachedStatement) { 141 sql::StatementID id1("foo", 12); 142 143 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); 144 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)")); 145 146 // Create a new cached statement. 147 { 148 sql::Statement s(db().GetCachedStatement(id1, "SELECT a FROM foo")); 149 ASSERT_TRUE(s.is_valid()); 150 151 ASSERT_TRUE(s.Step()); 152 EXPECT_EQ(12, s.ColumnInt(0)); 153 } 154 155 // The statement should be cached still. 156 EXPECT_TRUE(db().HasCachedStatement(id1)); 157 158 { 159 // Get the same statement using different SQL. This should ignore our 160 // SQL and use the cached one (so it will be valid). 161 sql::Statement s(db().GetCachedStatement(id1, "something invalid(")); 162 ASSERT_TRUE(s.is_valid()); 163 164 ASSERT_TRUE(s.Step()); 165 EXPECT_EQ(12, s.ColumnInt(0)); 166 } 167 168 // Make sure other statements aren't marked as cached. 169 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE)); 170 } 171 172 TEST_F(SQLConnectionTest, IsSQLValidTest) { 173 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); 174 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo")); 175 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo")); 176 } 177 178 TEST_F(SQLConnectionTest, DoesStuffExist) { 179 // Test DoesTableExist. 180 EXPECT_FALSE(db().DoesTableExist("foo")); 181 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); 182 EXPECT_TRUE(db().DoesTableExist("foo")); 183 184 // Should be case sensitive. 185 EXPECT_FALSE(db().DoesTableExist("FOO")); 186 187 // Test DoesColumnExist. 188 EXPECT_FALSE(db().DoesColumnExist("foo", "bar")); 189 EXPECT_TRUE(db().DoesColumnExist("foo", "a")); 190 191 // Testing for a column on a nonexistent table. 192 EXPECT_FALSE(db().DoesColumnExist("bar", "b")); 193 } 194 195 TEST_F(SQLConnectionTest, GetLastInsertRowId) { 196 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)")); 197 198 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)")); 199 200 // Last insert row ID should be valid. 201 int64 row = db().GetLastInsertRowId(); 202 EXPECT_LT(0, row); 203 204 // It should be the primary key of the row we just inserted. 205 sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?")); 206 s.BindInt64(0, row); 207 ASSERT_TRUE(s.Step()); 208 EXPECT_EQ(12, s.ColumnInt(0)); 209 } 210 211 TEST_F(SQLConnectionTest, Rollback) { 212 ASSERT_TRUE(db().BeginTransaction()); 213 ASSERT_TRUE(db().BeginTransaction()); 214 EXPECT_EQ(2, db().transaction_nesting()); 215 db().RollbackTransaction(); 216 EXPECT_FALSE(db().CommitTransaction()); 217 EXPECT_TRUE(db().BeginTransaction()); 218 } 219 220 // Test the scoped error ignorer by attempting to insert a duplicate 221 // value into an index. 222 TEST_F(SQLConnectionTest, ScopedIgnoreError) { 223 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)"; 224 ASSERT_TRUE(db().Execute(kCreateSql)); 225 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 226 227 sql::ScopedErrorIgnorer ignore_errors; 228 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); 229 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 230 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 231 } 232 233 TEST_F(SQLConnectionTest, ErrorCallback) { 234 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)"; 235 ASSERT_TRUE(db().Execute(kCreateSql)); 236 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 237 238 int error = SQLITE_OK; 239 { 240 sql::ScopedErrorCallback sec( 241 &db(), base::Bind(&sql::CaptureErrorCallback, &error)); 242 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 243 EXPECT_EQ(SQLITE_CONSTRAINT, error); 244 } 245 246 // Callback is no longer in force due to reset. 247 { 248 error = SQLITE_OK; 249 sql::ScopedErrorIgnorer ignore_errors; 250 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); 251 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 252 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 253 EXPECT_EQ(SQLITE_OK, error); 254 } 255 256 // base::Bind() can curry arguments to be passed by const reference 257 // to the callback function. If the callback function calls 258 // re/set_error_callback(), the storage for those arguments can be 259 // deleted while the callback function is still executing. 260 // 261 // RefCounter() counts how many objects are live using an external 262 // count. The same counter is passed to the callback, so that it 263 // can check directly even if the RefCounter object is no longer 264 // live. 265 { 266 size_t count = 0; 267 sql::ScopedErrorCallback sec( 268 &db(), base::Bind(&ErrorCallbackSetHelper, 269 &db(), &count, RefCounter(&count))); 270 271 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 272 } 273 274 // Same test, but reset_error_callback() case. 275 { 276 size_t count = 0; 277 sql::ScopedErrorCallback sec( 278 &db(), base::Bind(&ErrorCallbackResetHelper, 279 &db(), &count, RefCounter(&count))); 280 281 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); 282 } 283 } 284 285 // Test that sql::Connection::Raze() results in a database without the 286 // tables from the original database. 287 TEST_F(SQLConnectionTest, Raze) { 288 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 289 ASSERT_TRUE(db().Execute(kCreateSql)); 290 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)")); 291 292 int pragma_auto_vacuum = 0; 293 { 294 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum")); 295 ASSERT_TRUE(s.Step()); 296 pragma_auto_vacuum = s.ColumnInt(0); 297 ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1); 298 } 299 300 // If auto_vacuum is set, there's an extra page to maintain a freelist. 301 const int kExpectedPageCount = 2 + pragma_auto_vacuum; 302 303 { 304 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count")); 305 ASSERT_TRUE(s.Step()); 306 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0)); 307 } 308 309 { 310 sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master")); 311 ASSERT_TRUE(s.Step()); 312 EXPECT_EQ("table", s.ColumnString(0)); 313 EXPECT_EQ("foo", s.ColumnString(1)); 314 EXPECT_EQ("foo", s.ColumnString(2)); 315 // Table "foo" is stored in the last page of the file. 316 EXPECT_EQ(kExpectedPageCount, s.ColumnInt(3)); 317 EXPECT_EQ(kCreateSql, s.ColumnString(4)); 318 } 319 320 ASSERT_TRUE(db().Raze()); 321 322 { 323 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count")); 324 ASSERT_TRUE(s.Step()); 325 EXPECT_EQ(1, s.ColumnInt(0)); 326 } 327 328 ASSERT_EQ(0, SqliteMasterCount(&db())); 329 330 { 331 sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum")); 332 ASSERT_TRUE(s.Step()); 333 // The new database has the same auto_vacuum as a fresh database. 334 EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0)); 335 } 336 } 337 338 // Test that Raze() maintains page_size. 339 TEST_F(SQLConnectionTest, RazePageSize) { 340 // Fetch the default page size and double it for use in this test. 341 // Scoped to release statement before Close(). 342 int default_page_size = 0; 343 { 344 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size")); 345 ASSERT_TRUE(s.Step()); 346 default_page_size = s.ColumnInt(0); 347 } 348 ASSERT_GT(default_page_size, 0); 349 const int kPageSize = 2 * default_page_size; 350 351 // Re-open the database to allow setting the page size. 352 db().Close(); 353 db().set_page_size(kPageSize); 354 ASSERT_TRUE(db().Open(db_path())); 355 356 // page_size should match the indicated value. 357 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size")); 358 ASSERT_TRUE(s.Step()); 359 ASSERT_EQ(kPageSize, s.ColumnInt(0)); 360 361 // After raze, page_size should still match the indicated value. 362 ASSERT_TRUE(db().Raze()); 363 s.Reset(true); 364 ASSERT_TRUE(s.Step()); 365 ASSERT_EQ(kPageSize, s.ColumnInt(0)); 366 } 367 368 // Test that Raze() results are seen in other connections. 369 TEST_F(SQLConnectionTest, RazeMultiple) { 370 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 371 ASSERT_TRUE(db().Execute(kCreateSql)); 372 373 sql::Connection other_db; 374 ASSERT_TRUE(other_db.Open(db_path())); 375 376 // Check that the second connection sees the table. 377 ASSERT_EQ(1, SqliteMasterCount(&other_db)); 378 379 ASSERT_TRUE(db().Raze()); 380 381 // The second connection sees the updated database. 382 ASSERT_EQ(0, SqliteMasterCount(&other_db)); 383 } 384 385 TEST_F(SQLConnectionTest, RazeLocked) { 386 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 387 ASSERT_TRUE(db().Execute(kCreateSql)); 388 389 // Open a transaction and write some data in a second connection. 390 // This will acquire a PENDING or EXCLUSIVE transaction, which will 391 // cause the raze to fail. 392 sql::Connection other_db; 393 ASSERT_TRUE(other_db.Open(db_path())); 394 ASSERT_TRUE(other_db.BeginTransaction()); 395 const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')"; 396 ASSERT_TRUE(other_db.Execute(kInsertSql)); 397 398 ASSERT_FALSE(db().Raze()); 399 400 // Works after COMMIT. 401 ASSERT_TRUE(other_db.CommitTransaction()); 402 ASSERT_TRUE(db().Raze()); 403 404 // Re-create the database. 405 ASSERT_TRUE(db().Execute(kCreateSql)); 406 ASSERT_TRUE(db().Execute(kInsertSql)); 407 408 // An unfinished read transaction in the other connection also 409 // blocks raze. 410 const char *kQuery = "SELECT COUNT(*) FROM foo"; 411 sql::Statement s(other_db.GetUniqueStatement(kQuery)); 412 ASSERT_TRUE(s.Step()); 413 ASSERT_FALSE(db().Raze()); 414 415 // Complete the statement unlocks the database. 416 ASSERT_FALSE(s.Step()); 417 ASSERT_TRUE(db().Raze()); 418 } 419 420 // Verify that Raze() can handle an empty file. SQLite should treat 421 // this as an empty database. 422 TEST_F(SQLConnectionTest, RazeEmptyDB) { 423 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 424 ASSERT_TRUE(db().Execute(kCreateSql)); 425 db().Close(); 426 427 { 428 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "rb+")); 429 ASSERT_TRUE(file.get() != NULL); 430 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET)); 431 ASSERT_TRUE(file_util::TruncateFile(file.get())); 432 } 433 434 ASSERT_TRUE(db().Open(db_path())); 435 ASSERT_TRUE(db().Raze()); 436 EXPECT_EQ(0, SqliteMasterCount(&db())); 437 } 438 439 // Verify that Raze() can handle a file of junk. 440 TEST_F(SQLConnectionTest, RazeNOTADB) { 441 db().Close(); 442 sql::Connection::Delete(db_path()); 443 ASSERT_FALSE(base::PathExists(db_path())); 444 445 { 446 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "wb")); 447 ASSERT_TRUE(file.get() != NULL); 448 449 const char* kJunk = "This is the hour of our discontent."; 450 fputs(kJunk, file.get()); 451 } 452 ASSERT_TRUE(base::PathExists(db_path())); 453 454 // SQLite will successfully open the handle, but will fail with 455 // SQLITE_IOERR_SHORT_READ on pragma statemenets which read the 456 // header. 457 { 458 sql::ScopedErrorIgnorer ignore_errors; 459 ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ); 460 EXPECT_TRUE(db().Open(db_path())); 461 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 462 } 463 EXPECT_TRUE(db().Raze()); 464 db().Close(); 465 466 // Now empty, the open should open an empty database. 467 EXPECT_TRUE(db().Open(db_path())); 468 EXPECT_EQ(0, SqliteMasterCount(&db())); 469 } 470 471 // Verify that Raze() can handle a database overwritten with garbage. 472 TEST_F(SQLConnectionTest, RazeNOTADB2) { 473 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 474 ASSERT_TRUE(db().Execute(kCreateSql)); 475 ASSERT_EQ(1, SqliteMasterCount(&db())); 476 db().Close(); 477 478 { 479 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "rb+")); 480 ASSERT_TRUE(file.get() != NULL); 481 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET)); 482 483 const char* kJunk = "This is the hour of our discontent."; 484 fputs(kJunk, file.get()); 485 } 486 487 // SQLite will successfully open the handle, but will fail with 488 // SQLITE_NOTADB on pragma statemenets which attempt to read the 489 // corrupted header. 490 { 491 sql::ScopedErrorIgnorer ignore_errors; 492 ignore_errors.IgnoreError(SQLITE_NOTADB); 493 EXPECT_TRUE(db().Open(db_path())); 494 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 495 } 496 EXPECT_TRUE(db().Raze()); 497 db().Close(); 498 499 // Now empty, the open should succeed with an empty database. 500 EXPECT_TRUE(db().Open(db_path())); 501 EXPECT_EQ(0, SqliteMasterCount(&db())); 502 } 503 504 // Test that a callback from Open() can raze the database. This is 505 // essential for cases where the Open() can fail entirely, so the 506 // Raze() cannot happen later. Additionally test that when the 507 // callback does this during Open(), the open is retried and succeeds. 508 // 509 // Most corruptions seen in the wild seem to happen when two pages in 510 // the database were not written transactionally (the transaction 511 // changed both, but one wasn't successfully written for some reason). 512 // A special case of that is when the header indicates that the 513 // database contains more pages than are in the file. This breaks 514 // things at a very basic level, verify that Raze() can handle it. 515 TEST_F(SQLConnectionTest, RazeCallbackReopen) { 516 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 517 ASSERT_TRUE(db().Execute(kCreateSql)); 518 ASSERT_EQ(1, SqliteMasterCount(&db())); 519 int page_size = 0; 520 { 521 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size")); 522 ASSERT_TRUE(s.Step()); 523 page_size = s.ColumnInt(0); 524 } 525 db().Close(); 526 527 // Trim a single page from the end of the file. 528 { 529 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "rb+")); 530 ASSERT_TRUE(file.get() != NULL); 531 ASSERT_EQ(0, fseek(file.get(), -page_size, SEEK_END)); 532 ASSERT_TRUE(file_util::TruncateFile(file.get())); 533 } 534 535 // Open() will succeed, even though the PRAGMA calls within will 536 // fail with SQLITE_CORRUPT, as will this PRAGMA. 537 { 538 sql::ScopedErrorIgnorer ignore_errors; 539 ignore_errors.IgnoreError(SQLITE_CORRUPT); 540 ASSERT_TRUE(db().Open(db_path())); 541 ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum")); 542 db().Close(); 543 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 544 } 545 546 db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback, 547 base::Unretained(this), 548 SQLITE_CORRUPT)); 549 550 // When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error 551 // callback will call RazeAndClose(). Open() will then fail and be 552 // retried. The second Open() on the empty database will succeed 553 // cleanly. 554 ASSERT_TRUE(db().Open(db_path())); 555 ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum")); 556 EXPECT_EQ(0, SqliteMasterCount(&db())); 557 } 558 559 // Basic test of RazeAndClose() operation. 560 TEST_F(SQLConnectionTest, RazeAndClose) { 561 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 562 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)"; 563 564 // Test that RazeAndClose() closes the database, and that the 565 // database is empty when re-opened. 566 ASSERT_TRUE(db().Execute(kCreateSql)); 567 ASSERT_TRUE(db().Execute(kPopulateSql)); 568 ASSERT_TRUE(db().RazeAndClose()); 569 ASSERT_FALSE(db().is_open()); 570 db().Close(); 571 ASSERT_TRUE(db().Open(db_path())); 572 ASSERT_EQ(0, SqliteMasterCount(&db())); 573 574 // Test that RazeAndClose() can break transactions. 575 ASSERT_TRUE(db().Execute(kCreateSql)); 576 ASSERT_TRUE(db().Execute(kPopulateSql)); 577 ASSERT_TRUE(db().BeginTransaction()); 578 ASSERT_TRUE(db().RazeAndClose()); 579 ASSERT_FALSE(db().is_open()); 580 ASSERT_FALSE(db().CommitTransaction()); 581 db().Close(); 582 ASSERT_TRUE(db().Open(db_path())); 583 ASSERT_EQ(0, SqliteMasterCount(&db())); 584 } 585 586 // Test that various operations fail without crashing after 587 // RazeAndClose(). 588 TEST_F(SQLConnectionTest, RazeAndCloseDiagnostics) { 589 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; 590 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)"; 591 const char* kSimpleSql = "SELECT 1"; 592 593 ASSERT_TRUE(db().Execute(kCreateSql)); 594 ASSERT_TRUE(db().Execute(kPopulateSql)); 595 596 // Test baseline expectations. 597 db().Preload(); 598 ASSERT_TRUE(db().DoesTableExist("foo")); 599 ASSERT_TRUE(db().IsSQLValid(kSimpleSql)); 600 ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql)); 601 ASSERT_TRUE(db().Execute(kSimpleSql)); 602 ASSERT_TRUE(db().is_open()); 603 { 604 sql::Statement s(db().GetUniqueStatement(kSimpleSql)); 605 ASSERT_TRUE(s.Step()); 606 } 607 { 608 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql)); 609 ASSERT_TRUE(s.Step()); 610 } 611 ASSERT_TRUE(db().BeginTransaction()); 612 ASSERT_TRUE(db().CommitTransaction()); 613 ASSERT_TRUE(db().BeginTransaction()); 614 db().RollbackTransaction(); 615 616 ASSERT_TRUE(db().RazeAndClose()); 617 618 // At this point, they should all fail, but not crash. 619 db().Preload(); 620 ASSERT_FALSE(db().DoesTableExist("foo")); 621 ASSERT_FALSE(db().IsSQLValid(kSimpleSql)); 622 ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql)); 623 ASSERT_FALSE(db().Execute(kSimpleSql)); 624 ASSERT_FALSE(db().is_open()); 625 { 626 sql::Statement s(db().GetUniqueStatement(kSimpleSql)); 627 ASSERT_FALSE(s.Step()); 628 } 629 { 630 sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql)); 631 ASSERT_FALSE(s.Step()); 632 } 633 ASSERT_FALSE(db().BeginTransaction()); 634 ASSERT_FALSE(db().CommitTransaction()); 635 ASSERT_FALSE(db().BeginTransaction()); 636 db().RollbackTransaction(); 637 638 // Close normally to reset the poisoned flag. 639 db().Close(); 640 641 // DEATH tests not supported on Android or iOS. 642 #if !defined(OS_ANDROID) && !defined(OS_IOS) 643 // Once the real Close() has been called, various calls enforce API 644 // usage by becoming fatal in debug mode. Since DEATH tests are 645 // expensive, just test one of them. 646 if (DLOG_IS_ON(FATAL)) { 647 ASSERT_DEATH({ 648 db().IsSQLValid(kSimpleSql); 649 }, "Illegal use of connection without a db"); 650 } 651 #endif 652 } 653 654 // TODO(shess): Spin up a background thread to hold other_db, to more 655 // closely match real life. That would also allow testing 656 // RazeWithTimeout(). 657 658 #if defined(OS_ANDROID) 659 TEST_F(SQLConnectionTest, SetTempDirForSQL) { 660 661 sql::MetaTable meta_table; 662 // Below call needs a temporary directory in sqlite3 663 // On Android, it can pass only when the temporary directory is set. 664 // Otherwise, sqlite3 doesn't find the correct directory to store 665 // temporary files and will report the error 'unable to open 666 // database file'. 667 ASSERT_TRUE(meta_table.Init(&db(), 4, 4)); 668 } 669 #endif 670 671 TEST_F(SQLConnectionTest, Delete) { 672 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)")); 673 db().Close(); 674 675 // Should have both a main database file and a journal file because 676 // of journal_mode PERSIST. 677 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal")); 678 ASSERT_TRUE(base::PathExists(db_path())); 679 ASSERT_TRUE(base::PathExists(journal)); 680 681 sql::Connection::Delete(db_path()); 682 EXPECT_FALSE(base::PathExists(db_path())); 683 EXPECT_FALSE(base::PathExists(journal)); 684 } 685 686 #if defined(OS_POSIX) 687 // Test that set_restrict_to_user() trims database permissions so that 688 // only the owner (and root) can read. 689 TEST_F(SQLConnectionTest, UserPermission) { 690 // If the bots all had a restrictive umask setting such that 691 // databases are always created with only the owner able to read 692 // them, then the code could break without breaking the tests. 693 // Temporarily provide a more permissive umask. 694 db().Close(); 695 sql::Connection::Delete(db_path()); 696 ASSERT_FALSE(base::PathExists(db_path())); 697 ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH); 698 ASSERT_TRUE(db().Open(db_path())); 699 700 // Cause the journal file to be created. If the default 701 // journal_mode is changed back to DELETE, then parts of this test 702 // will need to be updated. 703 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)")); 704 705 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal")); 706 int mode; 707 708 // Given a permissive umask, the database is created with permissive 709 // read access for the database and journal. 710 ASSERT_TRUE(base::PathExists(db_path())); 711 ASSERT_TRUE(base::PathExists(journal)); 712 mode = file_util::FILE_PERMISSION_MASK; 713 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode)); 714 ASSERT_NE((mode & file_util::FILE_PERMISSION_USER_MASK), mode); 715 mode = file_util::FILE_PERMISSION_MASK; 716 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode)); 717 ASSERT_NE((mode & file_util::FILE_PERMISSION_USER_MASK), mode); 718 719 // Re-open with restricted permissions and verify that the modes 720 // changed for both the main database and the journal. 721 db().Close(); 722 db().set_restrict_to_user(); 723 ASSERT_TRUE(db().Open(db_path())); 724 ASSERT_TRUE(base::PathExists(db_path())); 725 ASSERT_TRUE(base::PathExists(journal)); 726 mode = file_util::FILE_PERMISSION_MASK; 727 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode)); 728 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); 729 mode = file_util::FILE_PERMISSION_MASK; 730 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode)); 731 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); 732 733 // Delete and re-create the database, the restriction should still apply. 734 db().Close(); 735 sql::Connection::Delete(db_path()); 736 ASSERT_TRUE(db().Open(db_path())); 737 ASSERT_TRUE(base::PathExists(db_path())); 738 ASSERT_FALSE(base::PathExists(journal)); 739 mode = file_util::FILE_PERMISSION_MASK; 740 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode)); 741 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); 742 743 // Verify that journal creation inherits the restriction. 744 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)")); 745 ASSERT_TRUE(base::PathExists(journal)); 746 mode = file_util::FILE_PERMISSION_MASK; 747 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode)); 748 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); 749 } 750 #endif // defined(OS_POSIX) 751 752 // Test that errors start happening once Poison() is called. 753 TEST_F(SQLConnectionTest, Poison) { 754 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)")); 755 756 // Before the Poison() call, things generally work. 757 EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')")); 758 EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')")); 759 { 760 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x")); 761 ASSERT_TRUE(s.is_valid()); 762 ASSERT_TRUE(s.Step()); 763 } 764 765 // Get a statement which is valid before and will exist across Poison(). 766 sql::Statement valid_statement( 767 db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master")); 768 ASSERT_TRUE(valid_statement.is_valid()); 769 ASSERT_TRUE(valid_statement.Step()); 770 valid_statement.Reset(true); 771 772 db().Poison(); 773 774 // After the Poison() call, things fail. 775 EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')")); 776 EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')")); 777 { 778 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x")); 779 ASSERT_FALSE(s.is_valid()); 780 ASSERT_FALSE(s.Step()); 781 } 782 783 // The existing statement has become invalid. 784 ASSERT_FALSE(valid_statement.is_valid()); 785 ASSERT_FALSE(valid_statement.Step()); 786 } 787 788 // Test attaching and detaching databases from the connection. 789 TEST_F(SQLConnectionTest, Attach) { 790 EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); 791 792 // Create a database to attach to. 793 base::FilePath attach_path = 794 db_path().DirName().AppendASCII("SQLConnectionAttach.db"); 795 const char kAttachmentPoint[] = "other"; 796 { 797 sql::Connection other_db; 798 ASSERT_TRUE(other_db.Open(attach_path)); 799 EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)")); 800 EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')")); 801 } 802 803 // Cannot see the attached database, yet. 804 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar")); 805 806 // Attach fails in a transaction. 807 EXPECT_TRUE(db().BeginTransaction()); 808 { 809 sql::ScopedErrorIgnorer ignore_errors; 810 ignore_errors.IgnoreError(SQLITE_ERROR); 811 EXPECT_FALSE(db().AttachDatabase(attach_path, kAttachmentPoint)); 812 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 813 } 814 815 // Attach succeeds when the transaction is closed. 816 db().RollbackTransaction(); 817 EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint)); 818 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar")); 819 820 // Queries can touch both databases. 821 EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar")); 822 { 823 sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo")); 824 ASSERT_TRUE(s.Step()); 825 EXPECT_EQ(1, s.ColumnInt(0)); 826 } 827 828 // Detach also fails in a transaction. 829 EXPECT_TRUE(db().BeginTransaction()); 830 { 831 sql::ScopedErrorIgnorer ignore_errors; 832 ignore_errors.IgnoreError(SQLITE_ERROR); 833 EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint)); 834 EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar")); 835 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 836 } 837 838 // Detach succeeds outside of a transaction. 839 db().RollbackTransaction(); 840 EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint)); 841 842 EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar")); 843 } 844 845 } // namespace 846