OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 | 5 |
6 #include "content/browser/dom_storage/session_storage_database.h" | 6 #include "content/browser/dom_storage/session_storage_database.h" |
7 | 7 |
| 8 #include <stddef.h> |
| 9 #include <stdint.h> |
| 10 |
8 #include <algorithm> | 11 #include <algorithm> |
9 #include <map> | 12 #include <map> |
10 #include <string> | 13 #include <string> |
11 | 14 |
12 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
13 #include "base/files/scoped_temp_dir.h" | 16 #include "base/files/scoped_temp_dir.h" |
14 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/macros.h" |
15 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
16 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
17 #include "content/common/dom_storage/dom_storage_types.h" | 21 #include "content/common/dom_storage/dom_storage_types.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
19 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 23 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
20 #include "third_party/leveldatabase/src/include/leveldb/iterator.h" | 24 #include "third_party/leveldatabase/src/include/leveldb/iterator.h" |
21 #include "third_party/leveldatabase/src/include/leveldb/options.h" | 25 #include "third_party/leveldatabase/src/include/leveldb/options.h" |
22 #include "url/gurl.h" | 26 #include "url/gurl.h" |
23 | 27 |
24 namespace content { | 28 namespace content { |
25 | 29 |
26 class SessionStorageDatabaseTest : public testing::Test { | 30 class SessionStorageDatabaseTest : public testing::Test { |
27 public: | 31 public: |
28 SessionStorageDatabaseTest(); | 32 SessionStorageDatabaseTest(); |
29 ~SessionStorageDatabaseTest() override; | 33 ~SessionStorageDatabaseTest() override; |
30 void SetUp() override; | 34 void SetUp() override; |
31 | 35 |
32 protected: | 36 protected: |
33 typedef std::map<std::string, std::string> DataMap; | 37 typedef std::map<std::string, std::string> DataMap; |
34 | 38 |
35 // Helpers. | 39 // Helpers. |
36 static bool IsNamespaceKey(const std::string& key, | 40 static bool IsNamespaceKey(const std::string& key, |
37 std::string* namespace_id); | 41 std::string* namespace_id); |
38 static bool IsNamespaceOriginKey(const std::string& key, | 42 static bool IsNamespaceOriginKey(const std::string& key, |
39 std::string* namespace_id); | 43 std::string* namespace_id); |
40 static bool IsMapRefCountKey(const std::string& key, | 44 static bool IsMapRefCountKey(const std::string& key, int64_t* map_id); |
41 int64* map_id); | 45 static bool IsMapValueKey(const std::string& key, int64_t* map_id); |
42 static bool IsMapValueKey(const std::string& key, | |
43 int64* map_id); | |
44 void ResetDatabase(); | 46 void ResetDatabase(); |
45 void ReadData(DataMap* data) const; | 47 void ReadData(DataMap* data) const; |
46 void CheckDatabaseConsistency() const; | 48 void CheckDatabaseConsistency() const; |
47 void CheckEmptyDatabase() const; | 49 void CheckEmptyDatabase() const; |
48 void DumpData() const; | 50 void DumpData() const; |
49 void CheckAreaData(const std::string& namespace_id, | 51 void CheckAreaData(const std::string& namespace_id, |
50 const GURL& origin, | 52 const GURL& origin, |
51 const DOMStorageValuesMap& reference) const; | 53 const DOMStorageValuesMap& reference) const; |
52 void CompareValuesMaps(const DOMStorageValuesMap& map1, | 54 void CompareValuesMaps(const DOMStorageValuesMap& map1, |
53 const DOMStorageValuesMap& map2) const; | 55 const DOMStorageValuesMap& map2) const; |
54 void CheckNamespaceIds( | 56 void CheckNamespaceIds( |
55 const std::set<std::string>& expected_namespace_ids) const; | 57 const std::set<std::string>& expected_namespace_ids) const; |
56 void CheckOrigins( | 58 void CheckOrigins( |
57 const std::string& namespace_id, | 59 const std::string& namespace_id, |
58 const std::set<GURL>& expected_origins) const; | 60 const std::set<GURL>& expected_origins) const; |
59 std::string GetMapForArea(const std::string& namespace_id, | 61 std::string GetMapForArea(const std::string& namespace_id, |
60 const GURL& origin) const; | 62 const GURL& origin) const; |
61 int64 GetMapRefCount(const std::string& map_id) const; | 63 int64_t GetMapRefCount(const std::string& map_id) const; |
62 | 64 |
63 base::ScopedTempDir temp_dir_; | 65 base::ScopedTempDir temp_dir_; |
64 scoped_refptr<SessionStorageDatabase> db_; | 66 scoped_refptr<SessionStorageDatabase> db_; |
65 | 67 |
66 // Test data. | 68 // Test data. |
67 const GURL kOrigin1; | 69 const GURL kOrigin1; |
68 const GURL kOrigin2; | 70 const GURL kOrigin2; |
69 const std::string kNamespace1; | 71 const std::string kNamespace1; |
70 const std::string kNamespace2; | 72 const std::string kNamespace2; |
71 const std::string kNamespaceClone; | 73 const std::string kNamespaceClone; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 // Key is of the form "namespace-<namespaceid>-<origin>", and the value | 143 // Key is of the form "namespace-<namespaceid>-<origin>", and the value |
142 // is the map id. | 144 // is the map id. |
143 *namespace_id = key.substr( | 145 *namespace_id = key.substr( |
144 namespace_prefix.length(), | 146 namespace_prefix.length(), |
145 second_dash - namespace_prefix.length()); | 147 second_dash - namespace_prefix.length()); |
146 return true; | 148 return true; |
147 } | 149 } |
148 | 150 |
149 // static | 151 // static |
150 bool SessionStorageDatabaseTest::IsMapRefCountKey(const std::string& key, | 152 bool SessionStorageDatabaseTest::IsMapRefCountKey(const std::string& key, |
151 int64* map_id) { | 153 int64_t* map_id) { |
152 std::string map_prefix = "map-"; | 154 std::string map_prefix = "map-"; |
153 if (key.find(map_prefix) != 0) | 155 if (key.find(map_prefix) != 0) |
154 return false; | 156 return false; |
155 size_t second_dash = key.find('-', map_prefix.length()); | 157 size_t second_dash = key.find('-', map_prefix.length()); |
156 if (second_dash != key.length() - 1) | 158 if (second_dash != key.length() - 1) |
157 return false; | 159 return false; |
158 // Key is of the form "map-<mapid>-" and the value is the ref count. | 160 // Key is of the form "map-<mapid>-" and the value is the ref count. |
159 std::string map_id_str = key.substr(map_prefix.length(), | 161 std::string map_id_str = key.substr(map_prefix.length(), |
160 second_dash - map_prefix.length()); | 162 second_dash - map_prefix.length()); |
161 bool conversion_ok = base::StringToInt64(map_id_str, map_id); | 163 bool conversion_ok = base::StringToInt64(map_id_str, map_id); |
162 EXPECT_TRUE(conversion_ok); | 164 EXPECT_TRUE(conversion_ok); |
163 return true; | 165 return true; |
164 } | 166 } |
165 | 167 |
166 // static | 168 // static |
167 bool SessionStorageDatabaseTest::IsMapValueKey(const std::string& key, | 169 bool SessionStorageDatabaseTest::IsMapValueKey(const std::string& key, |
168 int64* map_id) { | 170 int64_t* map_id) { |
169 std::string map_prefix = "map-"; | 171 std::string map_prefix = "map-"; |
170 if (key.find(map_prefix) != 0) | 172 if (key.find(map_prefix) != 0) |
171 return false; | 173 return false; |
172 size_t second_dash = key.find('-', map_prefix.length()); | 174 size_t second_dash = key.find('-', map_prefix.length()); |
173 if (second_dash == std::string::npos || second_dash == key.length() - 1) | 175 if (second_dash == std::string::npos || second_dash == key.length() - 1) |
174 return false; | 176 return false; |
175 // Key is of the form "map-<mapid>-key". | 177 // Key is of the form "map-<mapid>-key". |
176 std::string map_id_str = key.substr(map_prefix.length(), | 178 std::string map_id_str = key.substr(map_prefix.length(), |
177 second_dash - map_prefix.length()); | 179 second_dash - map_prefix.length()); |
178 bool conversion_ok = base::StringToInt64(map_id_str, map_id); | 180 bool conversion_ok = base::StringToInt64(map_id_str, map_id); |
(...skipping 28 matching lines...) Expand all Loading... |
207 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { | 209 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { |
208 ASSERT_TRUE(it->first == next_map_id_key); | 210 ASSERT_TRUE(it->first == next_map_id_key); |
209 } | 211 } |
210 return; | 212 return; |
211 } | 213 } |
212 ++valid_keys; | 214 ++valid_keys; |
213 | 215 |
214 // Iterate the "namespace-" keys. | 216 // Iterate the "namespace-" keys. |
215 std::set<std::string> found_namespace_ids; | 217 std::set<std::string> found_namespace_ids; |
216 std::set<std::string> namespaces_with_areas; | 218 std::set<std::string> namespaces_with_areas; |
217 std::map<int64, int64> expected_map_refcounts; | 219 std::map<int64_t, int64_t> expected_map_refcounts; |
218 int64 max_map_id = -1; | 220 int64_t max_map_id = -1; |
219 | 221 |
220 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { | 222 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { |
221 std::string namespace_id; | 223 std::string namespace_id; |
222 if (IsNamespaceKey(it->first, &namespace_id)) { | 224 if (IsNamespaceKey(it->first, &namespace_id)) { |
223 found_namespace_ids.insert(namespace_id); | 225 found_namespace_ids.insert(namespace_id); |
224 ++valid_keys; | 226 ++valid_keys; |
225 } else if (IsNamespaceOriginKey( | 227 } else if (IsNamespaceOriginKey( |
226 it->first, &namespace_id)) { | 228 it->first, &namespace_id)) { |
227 // Check that the corresponding "namespace-<namespaceid>-" key exists. It | 229 // Check that the corresponding "namespace-<namespaceid>-" key exists. It |
228 // has been read by now, since the keys are stored in order. | 230 // has been read by now, since the keys are stored in order. |
229 ASSERT_TRUE(found_namespace_ids.find(namespace_id) != | 231 ASSERT_TRUE(found_namespace_ids.find(namespace_id) != |
230 found_namespace_ids.end()); | 232 found_namespace_ids.end()); |
231 namespaces_with_areas.insert(namespace_id); | 233 namespaces_with_areas.insert(namespace_id); |
232 int64 map_id; | 234 int64_t map_id; |
233 bool conversion_ok = base::StringToInt64(it->second, &map_id); | 235 bool conversion_ok = base::StringToInt64(it->second, &map_id); |
234 ASSERT_TRUE(conversion_ok); | 236 ASSERT_TRUE(conversion_ok); |
235 ASSERT_GE(map_id, 0); | 237 ASSERT_GE(map_id, 0); |
236 ++expected_map_refcounts[map_id]; | 238 ++expected_map_refcounts[map_id]; |
237 max_map_id = std::max(map_id, max_map_id); | 239 max_map_id = std::max(map_id, max_map_id); |
238 ++valid_keys; | 240 ++valid_keys; |
239 } | 241 } |
240 } | 242 } |
241 // Check that there are no leftover "namespace-namespaceid-" keys without | 243 // Check that there are no leftover "namespace-namespaceid-" keys without |
242 // associated areas. | 244 // associated areas. |
243 ASSERT_EQ(found_namespace_ids.size(), namespaces_with_areas.size()); | 245 ASSERT_EQ(found_namespace_ids.size(), namespaces_with_areas.size()); |
244 | 246 |
245 if (max_map_id != -1) { | 247 if (max_map_id != -1) { |
246 // The database contains maps. | 248 // The database contains maps. |
247 ASSERT_TRUE(data.find(next_map_id_key) != data.end()); | 249 ASSERT_TRUE(data.find(next_map_id_key) != data.end()); |
248 int64 next_map_id; | 250 int64_t next_map_id; |
249 bool conversion_ok = | 251 bool conversion_ok = |
250 base::StringToInt64(data[next_map_id_key], &next_map_id); | 252 base::StringToInt64(data[next_map_id_key], &next_map_id); |
251 ASSERT_TRUE(conversion_ok); | 253 ASSERT_TRUE(conversion_ok); |
252 ASSERT_GT(next_map_id, max_map_id); | 254 ASSERT_GT(next_map_id, max_map_id); |
253 } | 255 } |
254 | 256 |
255 // Iterate the "map-" keys. | 257 // Iterate the "map-" keys. |
256 std::set<int64> found_map_ids; | 258 std::set<int64_t> found_map_ids; |
257 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { | 259 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { |
258 int64 map_id; | 260 int64_t map_id; |
259 if (IsMapRefCountKey(it->first, &map_id)) { | 261 if (IsMapRefCountKey(it->first, &map_id)) { |
260 int64 ref_count; | 262 int64_t ref_count; |
261 bool conversion_ok = base::StringToInt64(it->second, &ref_count); | 263 bool conversion_ok = base::StringToInt64(it->second, &ref_count); |
262 ASSERT_TRUE(conversion_ok); | 264 ASSERT_TRUE(conversion_ok); |
263 // Check that the map is not stale. | 265 // Check that the map is not stale. |
264 ASSERT_GT(ref_count, 0); | 266 ASSERT_GT(ref_count, 0); |
265 ASSERT_TRUE(expected_map_refcounts.find(map_id) != | 267 ASSERT_TRUE(expected_map_refcounts.find(map_id) != |
266 expected_map_refcounts.end()); | 268 expected_map_refcounts.end()); |
267 ASSERT_EQ(expected_map_refcounts[map_id], ref_count); | 269 ASSERT_EQ(expected_map_refcounts[map_id], ref_count); |
268 // Mark the map as existing. | 270 // Mark the map as existing. |
269 expected_map_refcounts.erase(map_id); | 271 expected_map_refcounts.erase(map_id); |
270 found_map_ids.insert(map_id); | 272 found_map_ids.insert(map_id); |
(...skipping 21 matching lines...) Expand all Loading... |
292 if (data.find(SessionStorageDatabase::NextMapIdKey()) != data.end()) | 294 if (data.find(SessionStorageDatabase::NextMapIdKey()) != data.end()) |
293 ++valid_keys; | 295 ++valid_keys; |
294 EXPECT_EQ(valid_keys, data.size()); | 296 EXPECT_EQ(valid_keys, data.size()); |
295 } | 297 } |
296 | 298 |
297 void SessionStorageDatabaseTest::DumpData() const { | 299 void SessionStorageDatabaseTest::DumpData() const { |
298 LOG(WARNING) << "---- Session storage contents"; | 300 LOG(WARNING) << "---- Session storage contents"; |
299 scoped_ptr<leveldb::Iterator> it( | 301 scoped_ptr<leveldb::Iterator> it( |
300 db_->db_->NewIterator(leveldb::ReadOptions())); | 302 db_->db_->NewIterator(leveldb::ReadOptions())); |
301 for (it->SeekToFirst(); it->Valid(); it->Next()) { | 303 for (it->SeekToFirst(); it->Valid(); it->Next()) { |
302 int64 dummy_map_id; | 304 int64_t dummy_map_id; |
303 if (IsMapValueKey(it->key().ToString(), &dummy_map_id)) { | 305 if (IsMapValueKey(it->key().ToString(), &dummy_map_id)) { |
304 // Convert the value back to base::string16. | 306 // Convert the value back to base::string16. |
305 base::string16 value; | 307 base::string16 value; |
306 size_t len = it->value().size() / sizeof(base::char16); | 308 size_t len = it->value().size() / sizeof(base::char16); |
307 value.resize(len); | 309 value.resize(len); |
308 value.assign( | 310 value.assign( |
309 reinterpret_cast<const base::char16*>(it->value().data()), len); | 311 reinterpret_cast<const base::char16*>(it->value().data()), len); |
310 LOG(WARNING) << it->key().ToString() << ": " << value; | 312 LOG(WARNING) << it->key().ToString() << ": " << value; |
311 } else { | 313 } else { |
312 LOG(WARNING) << it->key().ToString() << ": " << it->value().ToString(); | 314 LOG(WARNING) << it->key().ToString() << ": " << it->value().ToString(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 std::string SessionStorageDatabaseTest::GetMapForArea( | 369 std::string SessionStorageDatabaseTest::GetMapForArea( |
368 const std::string& namespace_id, const GURL& origin) const { | 370 const std::string& namespace_id, const GURL& origin) const { |
369 bool exists; | 371 bool exists; |
370 std::string map_id; | 372 std::string map_id; |
371 EXPECT_TRUE(db_->GetMapForArea(namespace_id, origin.spec(), | 373 EXPECT_TRUE(db_->GetMapForArea(namespace_id, origin.spec(), |
372 leveldb::ReadOptions(), &exists, &map_id)); | 374 leveldb::ReadOptions(), &exists, &map_id)); |
373 EXPECT_TRUE(exists); | 375 EXPECT_TRUE(exists); |
374 return map_id; | 376 return map_id; |
375 } | 377 } |
376 | 378 |
377 int64 SessionStorageDatabaseTest::GetMapRefCount( | 379 int64_t SessionStorageDatabaseTest::GetMapRefCount( |
378 const std::string& map_id) const { | 380 const std::string& map_id) const { |
379 int64 ref_count; | 381 int64_t ref_count; |
380 EXPECT_TRUE(db_->GetMapRefCount(map_id, &ref_count)); | 382 EXPECT_TRUE(db_->GetMapRefCount(map_id, &ref_count)); |
381 return ref_count; | 383 return ref_count; |
382 } | 384 } |
383 | 385 |
384 TEST_F(SessionStorageDatabaseTest, EmptyDatabaseSanityCheck) { | 386 TEST_F(SessionStorageDatabaseTest, EmptyDatabaseSanityCheck) { |
385 // An empty database should be valid. | 387 // An empty database should be valid. |
386 CheckDatabaseConsistency(); | 388 CheckDatabaseConsistency(); |
387 } | 389 } |
388 | 390 |
389 TEST_F(SessionStorageDatabaseTest, WriteDataForOneOrigin) { | 391 TEST_F(SessionStorageDatabaseTest, WriteDataForOneOrigin) { |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2)); | 792 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2)); |
791 | 793 |
792 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin1)); | 794 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin1)); |
793 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin2)); | 795 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin2)); |
794 // Check that also the namespace start key was deleted. | 796 // Check that also the namespace start key was deleted. |
795 CheckDatabaseConsistency(); | 797 CheckDatabaseConsistency(); |
796 } | 798 } |
797 | 799 |
798 | 800 |
799 } // namespace content | 801 } // namespace content |
OLD | NEW |