| Index: sql/sqlite_features_unittest.cc
|
| diff --git a/sql/sqlite_features_unittest.cc b/sql/sqlite_features_unittest.cc
|
| index 199d9446c73b14ba452297f1c9b317ddcd1565c1..ae21bae408501bd4fcfd5678ab9e8f51499a786f 100644
|
| --- a/sql/sqlite_features_unittest.cc
|
| +++ b/sql/sqlite_features_unittest.cc
|
| @@ -24,8 +24,12 @@
|
|
|
| // Test that certain features are/are-not enabled in our SQLite.
|
|
|
| +namespace sql {
|
| namespace {
|
|
|
| +using sql::test::ExecuteWithResult;
|
| +using sql::test::ExecuteWithResults;
|
| +
|
| void CaptureErrorCallback(int* error_pointer, std::string* sql_text,
|
| int error, sql::Statement* stmt) {
|
| *error_pointer = error;
|
| @@ -33,6 +37,8 @@ void CaptureErrorCallback(int* error_pointer, std::string* sql_text,
|
| *sql_text = text ? text : "no statement available";
|
| }
|
|
|
| +} // namespace
|
| +
|
| class SQLiteFeaturesTest : public sql::SQLTestBase {
|
| public:
|
| SQLiteFeaturesTest() : error_(SQLITE_OK) {}
|
| @@ -94,10 +100,8 @@ TEST_F(SQLiteFeaturesTest, FTS3_Prefix) {
|
|
|
| ASSERT_TRUE(db().Execute("INSERT INTO foo (x) VALUES ('test')"));
|
|
|
| - sql::Statement s(db().GetUniqueStatement(
|
| - "SELECT x FROM foo WHERE x MATCH 'te*'"));
|
| - ASSERT_TRUE(s.Step());
|
| - EXPECT_EQ("test", s.ColumnString(0));
|
| + EXPECT_EQ("test",
|
| + ExecuteWithResult(&db(), "SELECT x FROM foo WHERE x MATCH 'te*'"));
|
| }
|
| #endif
|
|
|
| @@ -110,10 +114,9 @@ TEST_F(SQLiteFeaturesTest, UsesUsleep) {
|
| sqlite3_sleep(1);
|
| base::TimeDelta delta = base::TimeTicks::Now() - before;
|
|
|
| - // It is not impossible for this to be over 1000 if things are compiled the
|
| - // right way. But it is very unlikely, most platforms seem to be around
|
| - // <TBD>.
|
| - LOG(ERROR) << "Milliseconds: " << delta.InMilliseconds();
|
| + // It is not impossible for this to be over 1000 if things are compiled
|
| + // correctly, but that is very unlikely. Most platforms seem to be exactly
|
| + // 1ms, with the test at 2ms, the worst observed cases was ASAN at 7ms.
|
| EXPECT_LT(delta.InMilliseconds(), 1000);
|
| }
|
| #endif
|
| @@ -127,28 +130,29 @@ TEST_F(SQLiteFeaturesTest, ForeignKeySupport) {
|
| "CREATE TABLE children ("
|
| " id INTEGER PRIMARY KEY,"
|
| " pid INTEGER NOT NULL REFERENCES parents(id) ON DELETE CASCADE)"));
|
| + const char kSelectParents[] = "SELECT * FROM parents ORDER BY id";
|
| + const char kSelectChildren[] = "SELECT * FROM children ORDER BY id";
|
|
|
| // Inserting without a matching parent should fail with constraint violation.
|
| // Mask off any extended error codes for USE_SYSTEM_SQLITE.
|
| - int insertErr = db().ExecuteAndReturnErrorCode(
|
| + EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParents));
|
| + const int insert_error = db().ExecuteAndReturnErrorCode(
|
| "INSERT INTO children VALUES (10, 1)");
|
| - EXPECT_EQ(SQLITE_CONSTRAINT, (insertErr&0xff));
|
| -
|
| - size_t rows;
|
| - EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows));
|
| - EXPECT_EQ(0u, rows);
|
| + EXPECT_EQ(SQLITE_CONSTRAINT, (insert_error&0xff));
|
| + EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildren));
|
|
|
| // Inserting with a matching parent should work.
|
| ASSERT_TRUE(db().Execute("INSERT INTO parents VALUES (1)"));
|
| + EXPECT_EQ("1", ExecuteWithResults(&db(), kSelectParents, "|", "\n"));
|
| EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (11, 1)"));
|
| EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (12, 1)"));
|
| - EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows));
|
| - EXPECT_EQ(2u, rows);
|
| + EXPECT_EQ("11|1\n12|1",
|
| + ExecuteWithResults(&db(), kSelectChildren, "|", "\n"));
|
|
|
| - // Deleting the parent should cascade, i.e., delete the children as well.
|
| + // Deleting the parent should cascade, deleting the children as well.
|
| ASSERT_TRUE(db().Execute("DELETE FROM parents"));
|
| - EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows));
|
| - EXPECT_EQ(0u, rows);
|
| + EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParents));
|
| + EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildren));
|
| }
|
|
|
| #if defined(MOJO_APPTEST_IMPL) || defined(OS_IOS)
|
| @@ -303,4 +307,36 @@ TEST_F(SQLiteFeaturesTest, CachedRegexp) {
|
| EXPECT_EQ(7, s.ColumnInt(0));
|
| }
|
|
|
| -} // namespace
|
| +#if !defined(USE_SYSTEM_SQLITE)
|
| +// SQLite WAL mode defaults to checkpointing the WAL on close. This would push
|
| +// additional work into Chromium shutdown. Verify that SQLite supports a config
|
| +// option to not checkpoint on close.
|
| +TEST_F(SQLiteFeaturesTest, WALNoClose) {
|
| + base::FilePath wal(db_path().value() + FILE_PATH_LITERAL("-wal"));
|
| +
|
| + // Turn on WAL mode, then verify that it worked.
|
| + ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
|
| + ASSERT_EQ("wal", ExecuteWithResult(&db(), "PRAGMA journal_mode"));
|
| +
|
| + // The WAL file is created lazily on first change.
|
| + ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
|
| +
|
| + // By default, the WAL is checkpointed and deleted on close.
|
| + ASSERT_TRUE(GetPathExists(wal));
|
| + db().Close();
|
| + ASSERT_FALSE(GetPathExists(wal));
|
| +
|
| + // Reopen and configure the database to not checkpoint WAL on close.
|
| + ASSERT_TRUE(Reopen());
|
| + ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
|
| + ASSERT_TRUE(db().Execute("ALTER TABLE foo ADD COLUMN c"));
|
| + ASSERT_EQ(SQLITE_OK,
|
| + sqlite3_db_config(db().db_, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,
|
| + 1, NULL));
|
| + ASSERT_TRUE(GetPathExists(wal));
|
| + db().Close();
|
| + ASSERT_TRUE(GetPathExists(wal));
|
| +}
|
| +#endif
|
| +
|
| +} // namespace sql
|
|
|