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 <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 #if defined(OS_MACOSX) && !defined(OS_IOS) | 25 #if defined(OS_MACOSX) && !defined(OS_IOS) |
26 #include <CoreFoundation/CoreFoundation.h> | 26 #include <CoreFoundation/CoreFoundation.h> |
27 #include <CoreServices/CoreServices.h> | 27 #include <CoreServices/CoreServices.h> |
28 | 28 |
29 #include "base/mac/mac_util.h" | 29 #include "base/mac/mac_util.h" |
30 #include "base/mac/scoped_cftyperef.h" | 30 #include "base/mac/scoped_cftyperef.h" |
31 #endif | 31 #endif |
32 | 32 |
33 // Test that certain features are/are-not enabled in our SQLite. | 33 // Test that certain features are/are-not enabled in our SQLite. |
34 | 34 |
35 namespace sql { | |
35 namespace { | 36 namespace { |
36 | 37 |
38 using sql::test::ExecuteWithResult; | |
39 using sql::test::ExecuteWithResults; | |
40 | |
37 void CaptureErrorCallback(int* error_pointer, std::string* sql_text, | 41 void CaptureErrorCallback(int* error_pointer, std::string* sql_text, |
38 int error, sql::Statement* stmt) { | 42 int error, sql::Statement* stmt) { |
39 *error_pointer = error; | 43 *error_pointer = error; |
40 const char* text = stmt ? stmt->GetSQLStatement() : NULL; | 44 const char* text = stmt ? stmt->GetSQLStatement() : NULL; |
41 *sql_text = text ? text : "no statement available"; | 45 *sql_text = text ? text : "no statement available"; |
42 } | 46 } |
43 | 47 |
48 } // namespace | |
49 | |
44 class SQLiteFeaturesTest : public sql::SQLTestBase { | 50 class SQLiteFeaturesTest : public sql::SQLTestBase { |
45 public: | 51 public: |
46 SQLiteFeaturesTest() : error_(SQLITE_OK) {} | 52 SQLiteFeaturesTest() : error_(SQLITE_OK) {} |
47 | 53 |
48 void SetUp() override { | 54 void SetUp() override { |
49 SQLTestBase::SetUp(); | 55 SQLTestBase::SetUp(); |
50 | 56 |
51 // The error delegate will set |error_| and |sql_text_| when any sqlite | 57 // The error delegate will set |error_| and |sql_text_| when any sqlite |
52 // statement operation returns an error code. | 58 // statement operation returns an error code. |
53 db().set_error_callback( | 59 db().set_error_callback( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 // Originally history used fts2, which Chromium patched to treat "foo*" as a | 101 // Originally history used fts2, which Chromium patched to treat "foo*" as a |
96 // prefix search, though the icu tokenizer would return it as two tokens {"foo", | 102 // prefix search, though the icu tokenizer would return it as two tokens {"foo", |
97 // "*"}. Test that fts3 works correctly. | 103 // "*"}. Test that fts3 works correctly. |
98 TEST_F(SQLiteFeaturesTest, FTS3_Prefix) { | 104 TEST_F(SQLiteFeaturesTest, FTS3_Prefix) { |
99 const char kCreateSql[] = | 105 const char kCreateSql[] = |
100 "CREATE VIRTUAL TABLE foo USING fts3(x, tokenize icu)"; | 106 "CREATE VIRTUAL TABLE foo USING fts3(x, tokenize icu)"; |
101 ASSERT_TRUE(db().Execute(kCreateSql)); | 107 ASSERT_TRUE(db().Execute(kCreateSql)); |
102 | 108 |
103 ASSERT_TRUE(db().Execute("INSERT INTO foo (x) VALUES ('test')")); | 109 ASSERT_TRUE(db().Execute("INSERT INTO foo (x) VALUES ('test')")); |
104 | 110 |
105 sql::Statement s(db().GetUniqueStatement( | 111 EXPECT_EQ("test", |
106 "SELECT x FROM foo WHERE x MATCH 'te*'")); | 112 ExecuteWithResult(&db(), "SELECT x FROM foo WHERE x MATCH 'te*'")); |
107 ASSERT_TRUE(s.Step()); | |
108 EXPECT_EQ("test", s.ColumnString(0)); | |
109 } | 113 } |
110 #endif | 114 #endif |
111 | 115 |
112 #if !defined(USE_SYSTEM_SQLITE) | 116 #if !defined(USE_SYSTEM_SQLITE) |
113 // Verify that Chromium's SQLite is compiled with HAVE_USLEEP defined. With | 117 // Verify that Chromium's SQLite is compiled with HAVE_USLEEP defined. With |
114 // HAVE_USLEEP, SQLite uses usleep() with millisecond granularity. Otherwise it | 118 // HAVE_USLEEP, SQLite uses usleep() with millisecond granularity. Otherwise it |
115 // uses sleep() with second granularity. | 119 // uses sleep() with second granularity. |
116 TEST_F(SQLiteFeaturesTest, UsesUsleep) { | 120 TEST_F(SQLiteFeaturesTest, UsesUsleep) { |
117 base::TimeTicks before = base::TimeTicks::Now(); | 121 base::TimeTicks before = base::TimeTicks::Now(); |
118 sqlite3_sleep(1); | 122 sqlite3_sleep(1); |
119 base::TimeDelta delta = base::TimeTicks::Now() - before; | 123 base::TimeDelta delta = base::TimeTicks::Now() - before; |
120 | 124 |
121 // It is not impossible for this to be over 1000 if things are compiled the | 125 // It is not impossible for this to be over 1000 if things are compiled |
122 // right way. But it is very unlikely, most platforms seem to be around | 126 // correctly, but that is very unlikely. Most platforms seem to be exactly |
123 // <TBD>. | 127 // 1ms, with the rest at 2ms, and the worst observed cases was ASAN at 7ms. |
124 LOG(ERROR) << "Milliseconds: " << delta.InMilliseconds(); | |
125 EXPECT_LT(delta.InMilliseconds(), 1000); | 128 EXPECT_LT(delta.InMilliseconds(), 1000); |
126 } | 129 } |
127 #endif | 130 #endif |
128 | 131 |
129 // Ensure that our SQLite version has working foreign key support with cascade | 132 // Ensure that our SQLite version has working foreign key support with cascade |
130 // delete support. | 133 // delete support. |
131 TEST_F(SQLiteFeaturesTest, ForeignKeySupport) { | 134 TEST_F(SQLiteFeaturesTest, ForeignKeySupport) { |
132 ASSERT_TRUE(db().Execute("PRAGMA foreign_keys=1")); | 135 ASSERT_TRUE(db().Execute("PRAGMA foreign_keys=1")); |
133 ASSERT_TRUE(db().Execute("CREATE TABLE parents (id INTEGER PRIMARY KEY)")); | 136 ASSERT_TRUE(db().Execute("CREATE TABLE parents (id INTEGER PRIMARY KEY)")); |
134 ASSERT_TRUE(db().Execute( | 137 ASSERT_TRUE(db().Execute( |
135 "CREATE TABLE children (" | 138 "CREATE TABLE children (" |
136 " id INTEGER PRIMARY KEY," | 139 " id INTEGER PRIMARY KEY," |
137 " pid INTEGER NOT NULL REFERENCES parents(id) ON DELETE CASCADE)")); | 140 " pid INTEGER NOT NULL REFERENCES parents(id) ON DELETE CASCADE)")); |
141 const char kSelectParents[] = "SELECT * FROM parents ORDER BY id"; | |
142 const char kSelectChildren[] = "SELECT * FROM children ORDER BY id"; | |
138 | 143 |
139 // Inserting without a matching parent should fail with constraint violation. | 144 // Inserting without a matching parent should fail with constraint violation. |
140 // Mask off any extended error codes for USE_SYSTEM_SQLITE. | 145 // Mask off any extended error codes for USE_SYSTEM_SQLITE. |
141 int insertErr = db().ExecuteAndReturnErrorCode( | 146 EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParents)); |
142 "INSERT INTO children VALUES (10, 1)"); | 147 const int insert_error = |
143 EXPECT_EQ(SQLITE_CONSTRAINT, (insertErr&0xff)); | 148 db().ExecuteAndReturnErrorCode("INSERT INTO children VALUES (10, 1)"); |
144 | 149 EXPECT_EQ(SQLITE_CONSTRAINT, (insert_error & 0xff)); |
145 size_t rows; | 150 EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildren)); |
146 EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows)); | |
147 EXPECT_EQ(0u, rows); | |
148 | 151 |
149 // Inserting with a matching parent should work. | 152 // Inserting with a matching parent should work. |
150 ASSERT_TRUE(db().Execute("INSERT INTO parents VALUES (1)")); | 153 ASSERT_TRUE(db().Execute("INSERT INTO parents VALUES (1)")); |
154 EXPECT_EQ("1", ExecuteWithResults(&db(), kSelectParents, "|", "\n")); | |
151 EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (11, 1)")); | 155 EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (11, 1)")); |
152 EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (12, 1)")); | 156 EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (12, 1)")); |
153 EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows)); | 157 EXPECT_EQ("11|1\n12|1", |
154 EXPECT_EQ(2u, rows); | 158 ExecuteWithResults(&db(), kSelectChildren, "|", "\n")); |
155 | 159 |
156 // Deleting the parent should cascade, i.e., delete the children as well. | 160 // Deleting the parent should cascade, deleting the children as well. |
157 ASSERT_TRUE(db().Execute("DELETE FROM parents")); | 161 ASSERT_TRUE(db().Execute("DELETE FROM parents")); |
158 EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows)); | 162 EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParents)); |
159 EXPECT_EQ(0u, rows); | 163 EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildren)); |
160 } | 164 } |
161 | 165 |
162 #if defined(MOJO_APPTEST_IMPL) || defined(OS_IOS) | 166 #if defined(MOJO_APPTEST_IMPL) || defined(OS_IOS) |
163 // If the platform cannot support SQLite mmap'ed I/O, make sure SQLite isn't | 167 // If the platform cannot support SQLite mmap'ed I/O, make sure SQLite isn't |
164 // offering to support it. | 168 // offering to support it. |
165 TEST_F(SQLiteFeaturesTest, NoMmap) { | 169 TEST_F(SQLiteFeaturesTest, NoMmap) { |
166 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) | 170 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
167 if (base::ios::IsRunningOnIOS10OrLater()) { | 171 if (base::ios::IsRunningOnIOS10OrLater()) { |
168 // iOS 10 added mmap support for sqlite. | 172 // iOS 10 added mmap support for sqlite. |
169 return; | 173 return; |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
446 s.Reset(true); | 450 s.Reset(true); |
447 ASSERT_TRUE(s.Run()); | 451 ASSERT_TRUE(s.Run()); |
448 | 452 |
449 ASSERT_TRUE(base::GetFileSize(db_path(), &file_size_after)); | 453 ASSERT_TRUE(base::GetFileSize(db_path(), &file_size_after)); |
450 ASSERT_EQ(file_size_after, file_size_before - 4096); | 454 ASSERT_EQ(file_size_after, file_size_before - 4096); |
451 } | 455 } |
452 #endif | 456 #endif |
453 } | 457 } |
454 #endif // !defined(USE_SYSTEM_SQLITE) | 458 #endif // !defined(USE_SYSTEM_SQLITE) |
455 | 459 |
456 } // namespace | 460 #if !defined(USE_SYSTEM_SQLITE) |
pwnall
2017/04/19 20:02:23
Would tests fail anywhere if we removed this #if?
Scott Hess - ex-Googler
2017/04/19 20:15:33
iOS uses the system SQLite. Also maybe Linux dist
pwnall
2017/04/19 20:56:54
TL;DR: If the test passes on bots, I'd leave it on
Scott Hess - ex-Googler
2017/04/19 22:03:16
The SQLite change landed last fall, so it's pretty
| |
461 // SQLite WAL mode defaults to checkpointing the WAL on close. This would push | |
462 // additional work into Chromium shutdown. Verify that SQLite supports a config | |
463 // option to not checkpoint on close. | |
464 TEST_F(SQLiteFeaturesTest, WALNoClose) { | |
Scott Hess - ex-Googler
2017/04/18 23:53:39
Um, this is the main test for whether the desired
| |
465 base::FilePath wal_path(db_path().value() + FILE_PATH_LITERAL("-wal")); | |
466 | |
467 // Turn on WAL mode, then verify that the mode changed (WAL is supported). | |
468 ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL")); | |
469 ASSERT_EQ("wal", ExecuteWithResult(&db(), "PRAGMA journal_mode")); | |
470 | |
471 // The WAL file is created lazily on first change. | |
472 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); | |
473 | |
474 // By default, the WAL is checkpointed then deleted on close. | |
475 ASSERT_TRUE(GetPathExists(wal_path)); | |
476 db().Close(); | |
477 ASSERT_FALSE(GetPathExists(wal_path)); | |
478 | |
479 // Reopen and configure the database to not checkpoint WAL on close. | |
480 ASSERT_TRUE(Reopen()); | |
481 ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL")); | |
482 ASSERT_TRUE(db().Execute("ALTER TABLE foo ADD COLUMN c")); | |
483 ASSERT_EQ( | |
484 SQLITE_OK, | |
485 sqlite3_db_config(db().db_, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, NULL)); | |
486 ASSERT_TRUE(GetPathExists(wal_path)); | |
487 db().Close(); | |
488 ASSERT_TRUE(GetPathExists(wal_path)); | |
489 } | |
490 #endif | |
491 | |
492 } // namespace sql | |
OLD | NEW |