OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/files/scoped_file.h" | 10 #include "base/files/scoped_file.h" |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE)); | 308 EXPECT_FALSE(db().HasCachedStatement(SQL_FROM_HERE)); |
309 } | 309 } |
310 | 310 |
311 TEST_F(SQLConnectionTest, IsSQLValidTest) { | 311 TEST_F(SQLConnectionTest, IsSQLValidTest) { |
312 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); | 312 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); |
313 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo")); | 313 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo")); |
314 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo")); | 314 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo")); |
315 } | 315 } |
316 | 316 |
317 TEST_F(SQLConnectionTest, DoesStuffExist) { | 317 TEST_F(SQLConnectionTest, DoesStuffExist) { |
318 // Test DoesTableExist. | 318 // Test DoesTableExist and DoesIndexExist. |
319 EXPECT_FALSE(db().DoesTableExist("foo")); | 319 EXPECT_FALSE(db().DoesTableExist("foo")); |
320 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); | 320 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); |
321 ASSERT_TRUE(db().Execute("CREATE INDEX foo_a ON foo (a)")); | 321 ASSERT_TRUE(db().Execute("CREATE INDEX foo_a ON foo (a)")); |
| 322 EXPECT_FALSE(db().DoesIndexExist("foo")); |
322 EXPECT_TRUE(db().DoesTableExist("foo")); | 323 EXPECT_TRUE(db().DoesTableExist("foo")); |
323 EXPECT_TRUE(db().DoesIndexExist("foo_a")); | 324 EXPECT_TRUE(db().DoesIndexExist("foo_a")); |
| 325 EXPECT_FALSE(db().DoesTableExist("foo_a")); |
| 326 |
| 327 // Test DoesViewExist. The CREATE VIEW is an older form because some iOS |
| 328 // versions use an earlier version of SQLite, and the difference isn't |
| 329 // relevant for this test. |
| 330 EXPECT_FALSE(db().DoesViewExist("voo")); |
| 331 ASSERT_TRUE(db().Execute("CREATE VIEW voo AS SELECT 1")); |
| 332 EXPECT_FALSE(db().DoesIndexExist("voo")); |
| 333 EXPECT_FALSE(db().DoesTableExist("voo")); |
| 334 EXPECT_TRUE(db().DoesViewExist("voo")); |
324 | 335 |
325 // Test DoesColumnExist. | 336 // Test DoesColumnExist. |
326 EXPECT_FALSE(db().DoesColumnExist("foo", "bar")); | 337 EXPECT_FALSE(db().DoesColumnExist("foo", "bar")); |
327 EXPECT_TRUE(db().DoesColumnExist("foo", "a")); | 338 EXPECT_TRUE(db().DoesColumnExist("foo", "a")); |
328 | 339 |
329 // Testing for a column on a nonexistent table. | 340 // Testing for a column on a nonexistent table. |
330 EXPECT_FALSE(db().DoesColumnExist("bar", "b")); | 341 EXPECT_FALSE(db().DoesColumnExist("bar", "b")); |
331 | 342 |
332 // Names are not case sensitive. | 343 // Names are not case sensitive. |
333 EXPECT_TRUE(db().DoesTableExist("FOO")); | 344 EXPECT_TRUE(db().DoesTableExist("FOO")); |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 ASSERT_TRUE(s.Step()); | 1475 ASSERT_TRUE(s.Step()); |
1465 EXPECT_LE(s.ColumnInt(0), 0); | 1476 EXPECT_LE(s.ColumnInt(0), 0); |
1466 } | 1477 } |
1467 } | 1478 } |
1468 | 1479 |
1469 // Test that explicit disable prevents mmap'ed I/O. | 1480 // Test that explicit disable prevents mmap'ed I/O. |
1470 db().Close(); | 1481 db().Close(); |
1471 sql::Connection::Delete(db_path()); | 1482 sql::Connection::Delete(db_path()); |
1472 db().set_mmap_disabled(); | 1483 db().set_mmap_disabled(); |
1473 ASSERT_TRUE(db().Open(db_path())); | 1484 ASSERT_TRUE(db().Open(db_path())); |
| 1485 EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size")); |
| 1486 } |
| 1487 |
| 1488 // Test whether a fresh database gets mmap enabled when using alternate status |
| 1489 // storage. |
| 1490 TEST_F(SQLConnectionTest, MmapInitiallyEnabledAltStatus) { |
| 1491 // Re-open fresh database with alt-status flag set. |
| 1492 db().Close(); |
| 1493 sql::Connection::Delete(db_path()); |
| 1494 db().set_mmap_alt_status(); |
| 1495 ASSERT_TRUE(db().Open(db_path())); |
| 1496 |
1474 { | 1497 { |
1475 sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size")); | 1498 sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size")); |
1476 ASSERT_TRUE(s.Step()); | 1499 |
1477 EXPECT_LE(s.ColumnInt(0), 0); | 1500 // SQLite doesn't have mmap support (perhaps an early iOS release). |
| 1501 if (!s.Step()) |
| 1502 return; |
| 1503 |
| 1504 // If mmap I/O is not on, attempt to turn it on. If that succeeds, then |
| 1505 // Open() should have turned it on. If mmap support is disabled, 0 is |
| 1506 // returned. If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for |
| 1507 // instance MojoVFS), -1 is returned. |
| 1508 if (s.ColumnInt(0) <= 0) { |
| 1509 ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576")); |
| 1510 s.Reset(true); |
| 1511 ASSERT_TRUE(s.Step()); |
| 1512 EXPECT_LE(s.ColumnInt(0), 0); |
| 1513 } |
1478 } | 1514 } |
| 1515 |
| 1516 // Test that explicit disable overrides set_mmap_alt_status(). |
| 1517 db().Close(); |
| 1518 sql::Connection::Delete(db_path()); |
| 1519 db().set_mmap_disabled(); |
| 1520 ASSERT_TRUE(db().Open(db_path())); |
| 1521 EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size")); |
1479 } | 1522 } |
1480 | 1523 |
1481 TEST_F(SQLConnectionTest, GetAppropriateMmapSize) { | 1524 TEST_F(SQLConnectionTest, GetAppropriateMmapSize) { |
1482 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) | 1525 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
1483 // Mmap is not supported on iOS9. | 1526 // Mmap is not supported on iOS9. |
1484 if (!base::ios::IsRunningOnIOS10OrLater()) { | 1527 if (!base::ios::IsRunningOnIOS10OrLater()) { |
1485 ASSERT_EQ(0UL, db().GetAppropriateMmapSize()); | 1528 ASSERT_EQ(0UL, db().GetAppropriateMmapSize()); |
1486 return; | 1529 return; |
1487 } | 1530 } |
1488 #endif | 1531 #endif |
(...skipping 27 matching lines...) Expand all Loading... |
1516 ASSERT_EQ(0, mmap_status); | 1559 ASSERT_EQ(0, mmap_status); |
1517 | 1560 |
1518 // With no key, map everything and create the key. | 1561 // With no key, map everything and create the key. |
1519 // TODO(shess): This really should be "maps everything after validating it", | 1562 // TODO(shess): This really should be "maps everything after validating it", |
1520 // but that is more complicated to structure. | 1563 // but that is more complicated to structure. |
1521 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot); | 1564 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot); |
1522 ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status)); | 1565 ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status)); |
1523 ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status); | 1566 ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status); |
1524 } | 1567 } |
1525 | 1568 |
| 1569 TEST_F(SQLConnectionTest, GetAppropriateMmapSizeAltStatus) { |
| 1570 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
| 1571 // Mmap is not supported on iOS9. Make sure that test takes precedence. |
| 1572 if (!base::ios::IsRunningOnIOS10OrLater()) { |
| 1573 db().set_mmap_alt_status(); |
| 1574 ASSERT_EQ(0UL, db().GetAppropriateMmapSize()); |
| 1575 return; |
| 1576 } |
| 1577 #endif |
| 1578 |
| 1579 const size_t kMmapAlot = 25 * 1024 * 1024; |
| 1580 |
| 1581 // At this point, Connection still expects a future [meta] table. |
| 1582 ASSERT_FALSE(db().DoesTableExist("meta")); |
| 1583 ASSERT_FALSE(db().DoesViewExist("MmapStatus")); |
| 1584 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot); |
| 1585 ASSERT_FALSE(db().DoesTableExist("meta")); |
| 1586 ASSERT_FALSE(db().DoesViewExist("MmapStatus")); |
| 1587 |
| 1588 // Using alt status, everything should be mapped, with state in the view. |
| 1589 db().set_mmap_alt_status(); |
| 1590 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot); |
| 1591 ASSERT_FALSE(db().DoesTableExist("meta")); |
| 1592 ASSERT_TRUE(db().DoesViewExist("MmapStatus")); |
| 1593 EXPECT_EQ(base::IntToString(MetaTable::kMmapSuccess), |
| 1594 ExecuteWithResult(&db(), "SELECT * FROM MmapStatus")); |
| 1595 |
| 1596 // Also maps everything when kMmapSuccess is in the view. |
| 1597 ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot); |
| 1598 |
| 1599 // Failure status leads to nothing being mapped. |
| 1600 ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus")); |
| 1601 ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus AS SELECT -2")); |
| 1602 ASSERT_EQ(0UL, db().GetAppropriateMmapSize()); |
| 1603 EXPECT_EQ(base::IntToString(MetaTable::kMmapFailure), |
| 1604 ExecuteWithResult(&db(), "SELECT * FROM MmapStatus")); |
| 1605 } |
| 1606 |
1526 // To prevent invalid SQL from accidentally shipping to production, prepared | 1607 // To prevent invalid SQL from accidentally shipping to production, prepared |
1527 // statements which fail to compile with SQLITE_ERROR call DLOG(FATAL). This | 1608 // statements which fail to compile with SQLITE_ERROR call DLOG(FATAL). This |
1528 // case cannot be suppressed with an error callback. | 1609 // case cannot be suppressed with an error callback. |
1529 TEST_F(SQLConnectionTest, CompileError) { | 1610 TEST_F(SQLConnectionTest, CompileError) { |
1530 // DEATH tests not supported on Android or iOS. | 1611 // DEATH tests not supported on Android or iOS. |
1531 #if !defined(OS_ANDROID) && !defined(OS_IOS) | 1612 #if !defined(OS_ANDROID) && !defined(OS_IOS) |
1532 if (DLOG_IS_ON(FATAL)) { | 1613 if (DLOG_IS_ON(FATAL)) { |
1533 db().set_error_callback(base::Bind(&IgnoreErrorCallback)); | 1614 db().set_error_callback(base::Bind(&IgnoreErrorCallback)); |
1534 ASSERT_DEATH({ | 1615 ASSERT_DEATH({ |
1535 db().GetUniqueStatement("SELECT x"); | 1616 db().GetUniqueStatement("SELECT x"); |
1536 }, "SQL compile error no such column: x"); | 1617 }, "SQL compile error no such column: x"); |
1537 } | 1618 } |
1538 #endif | 1619 #endif |
1539 } | 1620 } |
1540 | 1621 |
1541 } // namespace sql | 1622 } // namespace sql |
OLD | NEW |