OLD | NEW |
---|---|
(Empty) | |
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 "webkit/dom_storage/dom_storage_database.h" | |
6 | |
7 #include "base/file_path.h" | |
8 #include "base/path_service.h" | |
9 #include "base/scoped_temp_dir.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "sql/statement.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 namespace dom_storage { | |
15 | |
16 class DomStorageDatabaseTest : public testing::Test { | |
17 protected: | |
18 virtual void SetUp() { | |
19 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
20 file_name_ = temp_dir_.path().AppendASCII("TestDomStorageDatabase.db"); | |
21 } | |
22 | |
23 void CreateV1Table(sql::Connection* db) { | |
24 ASSERT_FALSE(db->is_open()); | |
25 ASSERT_TRUE(db->Open(file_name_)); | |
26 ASSERT_TRUE(db->Execute("DROP TABLE IF EXISTS ItemTable")); | |
27 ASSERT_TRUE(db->Execute( | |
28 "CREATE TABLE IF NOT EXISTS ItemTable (" | |
29 "key TEXT UNIQUE ON CONFLICT REPLACE, " | |
30 "value TEXT NOT NULL ON CONFLICT FAIL)")); | |
31 } | |
32 | |
33 void InsertDataV1(sql::Connection* db, | |
34 const string16& key, | |
35 const string16& value) { | |
36 sql::Statement stmt(db->GetCachedStatement(SQL_FROM_HERE, | |
37 "INSERT INTO ItemTable VALUES (?,?)")); | |
38 stmt.BindString16(0, key); | |
39 stmt.BindString16(1, value); | |
40 ASSERT_TRUE(stmt.is_valid()); | |
41 stmt.Run(); | |
42 } | |
43 | |
44 void InsertDataV2(sql::Connection* db, | |
45 const string16& key, | |
46 const string16& value) { | |
47 sql::Statement stmt(db->GetCachedStatement(SQL_FROM_HERE, | |
48 "INSERT INTO ItemTable VALUES (?,?)")); | |
49 stmt.BindString16(0, key); | |
50 stmt.BindBlob(1, value.data(), value.length() * sizeof(char16)); | |
51 ASSERT_TRUE(stmt.is_valid()); | |
52 stmt.Run(); | |
53 } | |
54 | |
55 DomStorageDatabase::ValuesMap ReadAllRows(sql::Connection* db) { | |
56 DomStorageDatabase::ValuesMap values; | |
57 sql::Statement stmt(db->GetCachedStatement(SQL_FROM_HERE, | |
58 "SELECT * from ItemTable")); | |
59 EXPECT_TRUE(stmt.is_valid()); | |
60 while (stmt.Step()) { | |
61 string16 key = stmt.ColumnString16(0); | |
62 string16 value; | |
63 stmt.ColumnBlobAsString16(1, &value); | |
64 values[key] = NullableString16(value, false); | |
65 } | |
66 return values; | |
67 } | |
68 | |
69 void CheckValuesMatch(sql::Connection* db, | |
70 const DomStorageDatabase::ValuesMap& expected) { | |
71 const DomStorageDatabase::ValuesMap values_read = ReadAllRows(db); | |
72 EXPECT_EQ(expected.size(), values_read.size()); | |
73 | |
74 DomStorageDatabase::ValuesMap::const_iterator it = values_read.begin(); | |
75 for (; it != values_read.end(); ++it) { | |
76 string16 key = it->first; | |
77 NullableString16 value = it->second; | |
78 EXPECT_EQ((expected.find(key)->second).string(), value.string()); | |
79 } | |
80 } | |
81 | |
82 ScopedTempDir temp_dir_; | |
83 FilePath file_name_; | |
84 }; | |
85 | |
86 TEST_F(DomStorageDatabaseTest, SimpleOpenAndClose) { | |
87 DomStorageDatabase db(file_name_); | |
88 ASSERT_TRUE(db.LazyOpen(true)); | |
89 EXPECT_TRUE(db.db_->DoesTableExist("ItemTable")); | |
90 // Ensure that we've got the colums we expect. | |
91 EXPECT_TRUE(db.db_->DoesColumnExist("ItemTable", "key")); | |
92 EXPECT_TRUE(db.db_->DoesColumnExist("ItemTable", "value")); | |
93 { | |
94 sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE, | |
95 "SELECT * from ItemTable LIMIT 1")); | |
96 EXPECT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0)); | |
97 EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt.DeclaredColumnType(1)); | |
98 } | |
99 db.Close(); | |
100 EXPECT_FALSE(db.IsOpen()); | |
101 } | |
102 | |
103 TEST_F(DomStorageDatabaseTest, TestLazyOpenIsLazy) { | |
104 DomStorageDatabase db(file_name_); | |
105 EXPECT_FALSE(db.IsOpen()); | |
106 DomStorageDatabase::ValuesMap values; | |
107 db.ReadAllValues(&values); | |
108 EXPECT_FALSE(db.IsOpen()); | |
109 values[ASCIIToUTF16("key")] = NullableString16(ASCIIToUTF16("value"), false); | |
110 db.CommitChanges(false, values); | |
111 EXPECT_TRUE(db.IsOpen()); | |
112 | |
113 db.Close(); | |
114 ASSERT_FALSE(db.IsOpen()); | |
115 | |
116 db.ReadAllValues(&values); | |
117 EXPECT_TRUE(db.IsOpen()); | |
118 } | |
119 | |
120 TEST_F(DomStorageDatabaseTest, TestUpgradesV1TableToV2) { | |
121 DomStorageDatabase db(file_name_); | |
122 db.db_.reset(new sql::Connection()); | |
123 CreateV1Table(db.db_.get()); | |
124 db.Close(); | |
125 | |
126 db.LazyOpen(true); | |
127 sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE, | |
128 "SELECT * from ItemTable LIMIT 1")); | |
129 EXPECT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0)); | |
130 EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt.DeclaredColumnType(1)); | |
131 } | |
132 | |
133 TEST_F(DomStorageDatabaseTest, TestIsOpen) { | |
134 DomStorageDatabase db(file_name_); | |
135 EXPECT_FALSE(db.IsOpen()); | |
136 ASSERT_TRUE(db.LazyOpen(true)); | |
137 EXPECT_TRUE(db.IsOpen()); | |
138 db.Close(); | |
139 EXPECT_FALSE(db.IsOpen()); | |
140 } | |
141 | |
142 TEST_F(DomStorageDatabaseTest, SimpleRead) { | |
143 DomStorageDatabase db(file_name_); | |
144 db.LazyOpen(true); | |
145 | |
146 const string16 kCannedKey = ASCIIToUTF16("name"); | |
147 const string16 kCannedValue = ASCIIToUTF16("Joe Bloggs"); | |
148 InsertDataV2(db.db_.get(), kCannedKey, kCannedValue); | |
149 DomStorageDatabase::ValuesMap values; | |
150 db.ReadAllValues(&values); | |
151 | |
152 EXPECT_EQ(1u, values.size()); | |
153 EXPECT_NE(values.end(), values.find(kCannedKey)); | |
154 EXPECT_EQ(kCannedValue, values[kCannedKey].string()); | |
155 } | |
156 | |
157 TEST_F(DomStorageDatabaseTest, SimpleWrite) { | |
158 DomStorageDatabase db(file_name_); | |
159 | |
160 DomStorageDatabase::ValuesMap storage; | |
161 string16 kCannedKeys[] = { | |
162 ASCIIToUTF16("test"), | |
163 ASCIIToUTF16("company"), | |
164 ASCIIToUTF16("date") | |
165 }; | |
166 NullableString16 kCannedValues[] = { | |
167 NullableString16(ASCIIToUTF16("123"), false), | |
168 NullableString16(ASCIIToUTF16("Google"), false), | |
169 NullableString16(ASCIIToUTF16("18-01-2012"), false) | |
170 }; | |
171 for (int i = 0; i < 3; i++) { | |
172 storage[kCannedKeys[i]] = kCannedValues[i]; | |
173 } | |
174 | |
175 ASSERT_TRUE(db.CommitChanges(false, storage)); | |
176 | |
177 CheckValuesMatch(db.db_.get(), storage); | |
178 } | |
179 | |
180 TEST_F(DomStorageDatabaseTest, WriteWithClear) { | |
181 DomStorageDatabase db(file_name_); | |
182 | |
183 DomStorageDatabase::ValuesMap storage; | |
184 string16 kCannedKeys[] = { | |
185 ASCIIToUTF16("test"), | |
186 ASCIIToUTF16("company"), | |
187 ASCIIToUTF16("date") | |
188 }; | |
189 NullableString16 kCannedValues[] = { | |
190 NullableString16(ASCIIToUTF16("123"), false), | |
191 NullableString16(ASCIIToUTF16("Google"), false), | |
192 NullableString16(ASCIIToUTF16("18-01-2012"), false) | |
193 }; | |
194 for (int i = 0; i < 3; i++) { | |
195 storage[kCannedKeys[i]] = kCannedValues[i]; | |
196 } | |
197 | |
198 ASSERT_TRUE(db.CommitChanges(false, storage)); | |
199 CheckValuesMatch(db.db_.get(), storage); | |
200 | |
201 // Insert some values, clearing the database first. | |
202 storage.clear(); | |
203 storage[ASCIIToUTF16("another_key")] = | |
204 NullableString16(ASCIIToUTF16("test"), false); | |
205 ASSERT_TRUE(db.CommitChanges(true, storage)); | |
206 CheckValuesMatch(db.db_.get(), storage); | |
207 | |
208 // Now clear the values without inserting any new ones. | |
209 storage.clear(); | |
210 ASSERT_TRUE(db.CommitChanges(true, storage)); | |
211 CheckValuesMatch(db.db_.get(), storage); | |
212 } | |
213 | |
214 TEST_F(DomStorageDatabaseTest, UpgradeFromV1ToV2NoData) { | |
215 DomStorageDatabase db(file_name_); | |
216 db.db_.reset(new sql::Connection()); | |
217 CreateV1Table(db.db_.get()); | |
218 | |
219 // The database has V1 structure, try to update it to V2. | |
220 sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE, | |
221 "SELECT value from ItemTable LIMIT 1")); | |
222 ASSERT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0)); | |
223 | |
224 ASSERT_TRUE(db.UpgradeVersion1To2IfNeeded()); | |
225 | |
226 // Verify the db now has V2 structure. | |
michaeln
2012/02/01 21:03:11
a few of the test verify the schema, might be wort
benm (inactive)
2012/02/02 12:14:49
Done.
| |
227 sql::Statement stmt2(db.db_->GetCachedStatement(SQL_FROM_HERE, | |
228 "SELECT value from ItemTable LIMIT 1")); | |
229 EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt2.DeclaredColumnType(0)); | |
230 } | |
231 | |
232 TEST_F(DomStorageDatabaseTest, UpgradeFromV1ToV2WithData) { | |
233 const string16 kCannedKey = ASCIIToUTF16("foo"); | |
234 const NullableString16 kCannedValue(ASCIIToUTF16("bar"), false); | |
235 DomStorageDatabase::ValuesMap expected; | |
236 expected[kCannedKey] = kCannedValue; | |
237 | |
238 { | |
239 DomStorageDatabase db(file_name_); | |
240 db.db_.reset(new sql::Connection()); | |
241 CreateV1Table(db.db_.get()); | |
242 | |
243 // The database has V1 structure, try to update it to V2. | |
244 sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE, | |
245 "SELECT value from ItemTable LIMIT 1")); | |
246 ASSERT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0)); | |
247 | |
248 InsertDataV1(db.db_.get(), kCannedKey, kCannedValue.string()); | |
249 | |
250 ASSERT_TRUE(db.UpgradeVersion1To2IfNeeded()); | |
251 | |
252 // Verify the db now has V2 structure. | |
253 sql::Statement stmt2(db.db_->GetCachedStatement(SQL_FROM_HERE, | |
254 "SELECT value from ItemTable LIMIT 1")); | |
255 EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt2.DeclaredColumnType(0)); | |
256 | |
257 CheckValuesMatch(db.db_.get(), expected); | |
258 } | |
259 | |
260 // Now open the db again and check that the data is consistent. | |
261 { | |
262 DomStorageDatabase db(file_name_); | |
263 ASSERT_TRUE(db.LazyOpen(true)); | |
264 CheckValuesMatch(db.db_.get(), expected); | |
265 } | |
266 } | |
267 | |
268 TEST_F(DomStorageDatabaseTest, TestOpenCloseDataPreserved) { | |
269 DomStorageDatabase db(file_name_); | |
270 | |
271 ASSERT_TRUE(db.LazyOpen(true)); | |
272 | |
273 const string16 kCannedKey = ASCIIToUTF16("test"); | |
274 const NullableString16 kCannedValue(ASCIIToUTF16("data"), false); | |
275 InsertDataV2(db.db_.get(), kCannedKey, kCannedValue.string()); | |
276 db.Close(); | |
277 | |
278 ASSERT_TRUE(db.LazyOpen(true)); | |
279 DomStorageDatabase::ValuesMap expected; | |
280 expected[kCannedKey] = kCannedValue; | |
281 CheckValuesMatch(db.db_.get(), expected); | |
282 } | |
283 | |
284 TEST_F(DomStorageDatabaseTest, TestSimpleRemoveOneValue) { | |
285 DomStorageDatabase db(file_name_); | |
286 | |
287 ASSERT_TRUE(db.LazyOpen(true)); | |
288 const string16 kCannedKey = ASCIIToUTF16("test"); | |
289 const NullableString16 kCannedValue(ASCIIToUTF16("data"), false); | |
290 InsertDataV2(db.db_.get(), kCannedKey, kCannedValue.string()); | |
291 | |
292 DomStorageDatabase::ValuesMap expected; | |
293 expected[kCannedKey] = kCannedValue; | |
294 CheckValuesMatch(db.db_.get(), expected); | |
295 | |
296 DomStorageDatabase::ValuesMap values; | |
297 values[kCannedKey] = NullableString16(true); | |
298 | |
299 db.CommitChanges(false, values); | |
300 | |
301 expected.clear(); | |
302 CheckValuesMatch(db.db_.get(), expected); | |
303 } | |
304 | |
305 TEST_F(DomStorageDatabaseTest, TestCanOpenAndReadWebCoreDatabase) { | |
306 { | |
307 FilePath webcore_database; | |
308 PathService::Get(base::DIR_SOURCE_ROOT, &webcore_database); | |
309 webcore_database = webcore_database.AppendASCII("webkit"); | |
310 webcore_database = webcore_database.AppendASCII("data"); | |
311 webcore_database = webcore_database.AppendASCII("dom_storage"); | |
312 webcore_database = | |
313 webcore_database.AppendASCII("webcore_test_database.localstorage"); | |
314 | |
315 DomStorageDatabase db(webcore_database); | |
316 | |
317 DomStorageDatabase::ValuesMap values; | |
318 db.ReadAllValues(&values); | |
319 EXPECT_EQ(2u, values.size()); | |
320 | |
321 DomStorageDatabase::ValuesMap::const_iterator it = | |
322 values.find(ASCIIToUTF16("value")); | |
323 EXPECT_NE(values.end(), it); | |
324 EXPECT_EQ(ASCIIToUTF16("I am in local storage!"), it->second.string()); | |
325 | |
326 it = values.find(ASCIIToUTF16("timestamp")); | |
327 EXPECT_NE(values.end(), it); | |
328 EXPECT_EQ(ASCIIToUTF16("1326738338841"), it->second.string()); | |
329 | |
330 it = values.find(ASCIIToUTF16("not_there")); | |
331 EXPECT_EQ(values.end(), it); | |
332 } | |
333 } | |
334 | |
335 } // namespace dom_storage | |
OLD | NEW |