Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: webkit/dom_storage/session_storage_database_unittest.cc

Issue 15990007: Move dom_storage to new locations. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
6 #include "webkit/dom_storage/session_storage_database.h"
7
8 #include <algorithm>
9 #include <map>
10 #include <string>
11
12 #include "base/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/logging.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/utf_string_conversions.h"
17 #include "googleurl/src/gurl.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/leveldatabase/src/include/leveldb/db.h"
20 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
21 #include "third_party/leveldatabase/src/include/leveldb/options.h"
22 #include "webkit/dom_storage/dom_storage_types.h"
23
24 namespace dom_storage {
25
26 class SessionStorageDatabaseTest : public testing::Test {
27 public:
28 SessionStorageDatabaseTest();
29 virtual ~SessionStorageDatabaseTest();
30 virtual void SetUp() OVERRIDE;
31
32 protected:
33 typedef std::map<std::string, std::string> DataMap;
34
35 // Helpers.
36 static bool IsNamespaceKey(const std::string& key,
37 std::string* namespace_id);
38 static bool IsNamespaceOriginKey(const std::string& key,
39 std::string* namespace_id);
40 static bool IsMapRefCountKey(const std::string& key,
41 int64* map_id);
42 static bool IsMapValueKey(const std::string& key,
43 int64* map_id);
44 void ResetDatabase();
45 void ReadData(DataMap* data) const;
46 void CheckDatabaseConsistency() const;
47 void CheckEmptyDatabase() const;
48 void DumpData() const;
49 void CheckAreaData(const std::string& namespace_id,
50 const GURL& origin,
51 const ValuesMap& reference) const;
52 void CompareValuesMaps(const ValuesMap& map1, const ValuesMap& map2) const;
53 void CheckNamespaceIds(
54 const std::set<std::string>& expected_namespace_ids) const;
55 void CheckOrigins(
56 const std::string& namespace_id,
57 const std::set<GURL>& expected_origins) const;
58 std::string GetMapForArea(const std::string& namespace_id,
59 const GURL& origin) const;
60 int64 GetMapRefCount(const std::string& map_id) const;
61
62 base::ScopedTempDir temp_dir_;
63 scoped_refptr<SessionStorageDatabase> db_;
64
65 // Test data.
66 const GURL kOrigin1;
67 const GURL kOrigin2;
68 const std::string kNamespace1;
69 const std::string kNamespace2;
70 const std::string kNamespaceClone;
71 const base::string16 kKey1;
72 const base::string16 kKey2;
73 const base::string16 kKey3;
74 const NullableString16 kValue1;
75 const NullableString16 kValue2;
76 const NullableString16 kValue3;
77 const NullableString16 kValue4;
78 const NullableString16 kValueNull;
79
80 DISALLOW_COPY_AND_ASSIGN(SessionStorageDatabaseTest);
81 };
82
83 SessionStorageDatabaseTest::SessionStorageDatabaseTest()
84 : kOrigin1("http://www.origin1.com"),
85 kOrigin2("http://www.origin2.com"),
86 kNamespace1("namespace1"),
87 kNamespace2("namespace2"),
88 kNamespaceClone("wascloned"),
89 kKey1(ASCIIToUTF16("key1")),
90 kKey2(ASCIIToUTF16("key2")),
91 kKey3(ASCIIToUTF16("key3")),
92 kValue1(NullableString16(ASCIIToUTF16("value1"), false)),
93 kValue2(NullableString16(ASCIIToUTF16("value2"), false)),
94 kValue3(NullableString16(ASCIIToUTF16("value3"), false)),
95 kValue4(NullableString16(ASCIIToUTF16("value4"), false)),
96 kValueNull(NullableString16(true)) { }
97
98 SessionStorageDatabaseTest::~SessionStorageDatabaseTest() { }
99
100 void SessionStorageDatabaseTest::SetUp() {
101 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
102 ResetDatabase();
103 }
104
105 void SessionStorageDatabaseTest::ResetDatabase() {
106 db_ = new SessionStorageDatabase(temp_dir_.path());
107 ASSERT_TRUE(db_->LazyOpen(true));
108 }
109
110 // static
111 bool SessionStorageDatabaseTest::IsNamespaceKey(const std::string& key,
112 std::string* namespace_id) {
113 std::string namespace_prefix = SessionStorageDatabase::NamespacePrefix();
114 if (key.find(namespace_prefix) != 0)
115 return false;
116 if (key == namespace_prefix)
117 return false;
118
119 size_t second_dash = key.find('-', namespace_prefix.length());
120 if (second_dash != key.length() - 1)
121 return false;
122
123 // Key is of the form "namespace-<namespaceid>-".
124 *namespace_id = key.substr(
125 namespace_prefix.length(),
126 second_dash - namespace_prefix.length());
127 return true;
128 }
129
130 // static
131 bool SessionStorageDatabaseTest::IsNamespaceOriginKey(
132 const std::string& key,
133 std::string* namespace_id) {
134 std::string namespace_prefix = SessionStorageDatabase::NamespacePrefix();
135 if (key.find(namespace_prefix) != 0)
136 return false;
137 size_t second_dash = key.find('-', namespace_prefix.length());
138 if (second_dash == std::string::npos || second_dash == key.length() - 1)
139 return false;
140
141 // Key is of the form "namespace-<namespaceid>-<origin>", and the value
142 // is the map id.
143 *namespace_id = key.substr(
144 namespace_prefix.length(),
145 second_dash - namespace_prefix.length());
146 return true;
147 }
148
149 // static
150 bool SessionStorageDatabaseTest::IsMapRefCountKey(const std::string& key,
151 int64* map_id) {
152 std::string map_prefix = "map-";
153 if (key.find(map_prefix) != 0)
154 return false;
155 size_t second_dash = key.find('-', map_prefix.length());
156 if (second_dash != key.length() - 1)
157 return false;
158 // 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(),
160 second_dash - map_prefix.length());
161 bool conversion_ok = base::StringToInt64(map_id_str, map_id);
162 EXPECT_TRUE(conversion_ok);
163 return true;
164 }
165
166 // static
167 bool SessionStorageDatabaseTest::IsMapValueKey(const std::string& key,
168 int64* map_id) {
169 std::string map_prefix = "map-";
170 if (key.find(map_prefix) != 0)
171 return false;
172 size_t second_dash = key.find('-', map_prefix.length());
173 if (second_dash == std::string::npos || second_dash == key.length() - 1)
174 return false;
175 // Key is of the form "map-<mapid>-key".
176 std::string map_id_str = key.substr(map_prefix.length(),
177 second_dash - map_prefix.length());
178 bool conversion_ok = base::StringToInt64(map_id_str, map_id);
179 EXPECT_TRUE(conversion_ok);
180 return true;
181 }
182
183 void SessionStorageDatabaseTest::ReadData(DataMap* data) const {
184 leveldb::DB* leveldb = db_->db_.get();
185 scoped_ptr<leveldb::Iterator> it(
186 leveldb->NewIterator(leveldb::ReadOptions()));
187 for (it->SeekToFirst(); it->Valid(); it->Next()) {
188 (*data)[it->key().ToString()] = it->value().ToString();
189 }
190 }
191
192 void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
193 DataMap data;
194 ReadData(&data);
195 // Empty db is ok.
196 if (data.empty())
197 return;
198
199 // For detecting rubbish keys.
200 size_t valid_keys = 0;
201
202 std::string next_map_id_key = SessionStorageDatabase::NextMapIdKey();
203 // Check the namespace start key.
204 if (data.find(SessionStorageDatabase::NamespacePrefix()) == data.end()) {
205 // If there is no namespace start key, the database may contain only counter
206 // keys.
207 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) {
208 ASSERT_TRUE(it->first == next_map_id_key);
209 }
210 return;
211 }
212 ++valid_keys;
213
214 // Iterate the "namespace-" keys.
215 std::set<std::string> found_namespace_ids;
216 std::set<std::string> namespaces_with_areas;
217 std::map<int64, int64> expected_map_refcounts;
218 int64 max_map_id = -1;
219
220 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) {
221 std::string namespace_id;
222 std::string origin;
223 if (IsNamespaceKey(it->first, &namespace_id)) {
224 found_namespace_ids.insert(namespace_id);
225 ++valid_keys;
226 } else if (IsNamespaceOriginKey(
227 it->first, &namespace_id)) {
228 // Check that the corresponding "namespace-<namespaceid>-" key exists. It
229 // has been read by now, since the keys are stored in order.
230 ASSERT_TRUE(found_namespace_ids.find(namespace_id) !=
231 found_namespace_ids.end());
232 namespaces_with_areas.insert(namespace_id);
233 int64 map_id;
234 bool conversion_ok = base::StringToInt64(it->second, &map_id);
235 ASSERT_TRUE(conversion_ok);
236 ASSERT_GE(map_id, 0);
237 ++expected_map_refcounts[map_id];
238 max_map_id = std::max(map_id, max_map_id);
239 ++valid_keys;
240 }
241 }
242 // Check that there are no leftover "namespace-namespaceid-" keys without
243 // associated areas.
244 ASSERT_EQ(found_namespace_ids.size(), namespaces_with_areas.size());
245
246 if (max_map_id != -1) {
247 // The database contains maps.
248 ASSERT_TRUE(data.find(next_map_id_key) != data.end());
249 int64 next_map_id;
250 bool conversion_ok =
251 base::StringToInt64(data[next_map_id_key], &next_map_id);
252 ASSERT_TRUE(conversion_ok);
253 ASSERT_GT(next_map_id, max_map_id);
254 }
255
256 // Iterate the "map-" keys.
257 std::set<int64> found_map_ids;
258 for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) {
259 int64 map_id;
260 if (IsMapRefCountKey(it->first, &map_id)) {
261 int64 ref_count;
262 bool conversion_ok = base::StringToInt64(it->second, &ref_count);
263 ASSERT_TRUE(conversion_ok);
264 // Check that the map is not stale.
265 ASSERT_GT(ref_count, 0);
266 ASSERT_TRUE(expected_map_refcounts.find(map_id) !=
267 expected_map_refcounts.end());
268 ASSERT_EQ(expected_map_refcounts[map_id], ref_count);
269 // Mark the map as existing.
270 expected_map_refcounts.erase(map_id);
271 found_map_ids.insert(map_id);
272 ++valid_keys;
273 } else if (IsMapValueKey(it->first, &map_id)) {
274 ASSERT_TRUE(found_map_ids.find(map_id) != found_map_ids.end());
275 ++valid_keys;
276 }
277 }
278 // Check that all maps referred to exist.
279 ASSERT_TRUE(expected_map_refcounts.empty());
280
281 if (data.find(next_map_id_key) != data.end())
282 ++valid_keys;
283
284 ASSERT_EQ(data.size(), valid_keys);
285 }
286
287 void SessionStorageDatabaseTest::CheckEmptyDatabase() const {
288 DataMap data;
289 ReadData(&data);
290 size_t valid_keys = 0;
291 if (data.find(SessionStorageDatabase::NamespacePrefix()) != data.end())
292 ++valid_keys;
293 if (data.find(SessionStorageDatabase::NextMapIdKey()) != data.end())
294 ++valid_keys;
295 EXPECT_EQ(valid_keys, data.size());
296 }
297
298 void SessionStorageDatabaseTest::DumpData() const {
299 LOG(WARNING) << "---- Session storage contents";
300 scoped_ptr<leveldb::Iterator> it(
301 db_->db_->NewIterator(leveldb::ReadOptions()));
302 for (it->SeekToFirst(); it->Valid(); it->Next()) {
303 int64 dummy_map_id;
304 if (IsMapValueKey(it->key().ToString(), &dummy_map_id)) {
305 // Convert the value back to base::string16.
306 base::string16 value;
307 size_t len = it->value().size() / sizeof(char16);
308 value.resize(len);
309 value.assign(reinterpret_cast<const char16*>(it->value().data()), len);
310 LOG(WARNING) << it->key().ToString() << ": " << value;
311 } else {
312 LOG(WARNING) << it->key().ToString() << ": " << it->value().ToString();
313 }
314 }
315 LOG(WARNING) << "----";
316 }
317
318 void SessionStorageDatabaseTest::CheckAreaData(
319 const std::string& namespace_id, const GURL& origin,
320 const ValuesMap& reference) const {
321 ValuesMap values;
322 db_->ReadAreaValues(namespace_id, origin, &values);
323 CompareValuesMaps(values, reference);
324 }
325
326 void SessionStorageDatabaseTest::CompareValuesMaps(
327 const ValuesMap& map1,
328 const ValuesMap& map2) const {
329 ASSERT_EQ(map2.size(), map1.size());
330 for (ValuesMap::const_iterator it = map1.begin(); it != map1.end(); ++it) {
331 base::string16 key = it->first;
332 ASSERT_TRUE(map2.find(key) != map2.end());
333 NullableString16 val1 = it->second;
334 NullableString16 val2 = map2.find(key)->second;
335 EXPECT_EQ(val2.is_null(), val1.is_null());
336 EXPECT_EQ(val2.string(), val1.string());
337 }
338 }
339
340 void SessionStorageDatabaseTest::CheckNamespaceIds(
341 const std::set<std::string>& expected_namespace_ids) const {
342 std::map<std::string, std::vector<GURL> > namespaces_and_origins;
343 EXPECT_TRUE(db_->ReadNamespacesAndOrigins(&namespaces_and_origins));
344 EXPECT_EQ(expected_namespace_ids.size(), namespaces_and_origins.size());
345 for (std::map<std::string, std::vector<GURL> >::const_iterator it =
346 namespaces_and_origins.begin();
347 it != namespaces_and_origins.end(); ++it) {
348 EXPECT_TRUE(expected_namespace_ids.find(it->first) !=
349 expected_namespace_ids.end());
350 }
351 }
352
353 void SessionStorageDatabaseTest::CheckOrigins(
354 const std::string& namespace_id,
355 const std::set<GURL>& expected_origins) const {
356 std::map<std::string, std::vector<GURL> > namespaces_and_origins;
357 EXPECT_TRUE(db_->ReadNamespacesAndOrigins(&namespaces_and_origins));
358 const std::vector<GURL>& origins = namespaces_and_origins[namespace_id];
359 EXPECT_EQ(expected_origins.size(), origins.size());
360 for (std::vector<GURL>::const_iterator it = origins.begin();
361 it != origins.end(); ++it) {
362 EXPECT_TRUE(expected_origins.find(*it) != expected_origins.end());
363 }
364 }
365
366 std::string SessionStorageDatabaseTest::GetMapForArea(
367 const std::string& namespace_id, const GURL& origin) const {
368 bool exists;
369 std::string map_id;
370 EXPECT_TRUE(db_->GetMapForArea(namespace_id, origin.spec(),
371 leveldb::ReadOptions(), &exists, &map_id));
372 EXPECT_TRUE(exists);
373 return map_id;
374 }
375
376 int64 SessionStorageDatabaseTest::GetMapRefCount(
377 const std::string& map_id) const {
378 int64 ref_count;
379 EXPECT_TRUE(db_->GetMapRefCount(map_id, &ref_count));
380 return ref_count;
381 }
382
383 TEST_F(SessionStorageDatabaseTest, EmptyDatabaseSanityCheck) {
384 // An empty database should be valid.
385 CheckDatabaseConsistency();
386 }
387
388 TEST_F(SessionStorageDatabaseTest, WriteDataForOneOrigin) {
389 // Keep track on what the values should look like.
390 ValuesMap reference;
391 // Write data.
392 {
393 ValuesMap changes;
394 changes[kKey1] = kValue1;
395 changes[kKey2] = kValue2;
396 changes[kKey3] = kValue3;
397 reference[kKey1] = kValue1;
398 reference[kKey2] = kValue2;
399 reference[kKey3] = kValue3;
400 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, changes));
401 }
402 CheckDatabaseConsistency();
403 CheckAreaData(kNamespace1, kOrigin1, reference);
404
405 // Overwrite and delete values.
406 {
407 ValuesMap changes;
408 changes[kKey1] = kValue4;
409 changes[kKey3] = kValueNull;
410 reference[kKey1] = kValue4;
411 reference.erase(kKey3);
412 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, changes));
413 }
414 CheckDatabaseConsistency();
415 CheckAreaData(kNamespace1, kOrigin1, reference);
416
417 // Clear data before writing.
418 {
419 ValuesMap changes;
420 changes[kKey2] = kValue2;
421 reference.erase(kKey1);
422 reference[kKey2] = kValue2;
423 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, true, changes));
424 }
425 CheckDatabaseConsistency();
426 CheckAreaData(kNamespace1, kOrigin1, reference);
427 }
428
429 TEST_F(SessionStorageDatabaseTest, WriteDataForTwoOrigins) {
430 // Write data.
431 ValuesMap data1;
432 data1[kKey1] = kValue1;
433 data1[kKey2] = kValue2;
434 data1[kKey3] = kValue3;
435 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
436
437 ValuesMap data2;
438 data2[kKey1] = kValue4;
439 data2[kKey2] = kValue1;
440 data2[kKey3] = kValue2;
441 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
442
443 CheckDatabaseConsistency();
444 CheckAreaData(kNamespace1, kOrigin1, data1);
445 CheckAreaData(kNamespace1, kOrigin2, data2);
446 }
447
448 TEST_F(SessionStorageDatabaseTest, WriteDataForTwoNamespaces) {
449 // Write data.
450 ValuesMap data11;
451 data11[kKey1] = kValue1;
452 data11[kKey2] = kValue2;
453 data11[kKey3] = kValue3;
454 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data11));
455 ValuesMap data12;
456 data12[kKey2] = kValue4;
457 data12[kKey3] = kValue3;
458 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data12));
459 ValuesMap data21;
460 data21[kKey1] = kValue2;
461 data21[kKey2] = kValue4;
462 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace2, kOrigin1, false, data21));
463 ValuesMap data22;
464 data22[kKey2] = kValue1;
465 data22[kKey3] = kValue2;
466 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace2, kOrigin2, false, data22));
467 CheckDatabaseConsistency();
468 CheckAreaData(kNamespace1, kOrigin1, data11);
469 CheckAreaData(kNamespace1, kOrigin2, data12);
470 CheckAreaData(kNamespace2, kOrigin1, data21);
471 CheckAreaData(kNamespace2, kOrigin2, data22);
472 }
473
474 TEST_F(SessionStorageDatabaseTest, ShallowCopy) {
475 // Write data for a namespace, for 2 origins.
476 ValuesMap data1;
477 data1[kKey1] = kValue1;
478 data1[kKey2] = kValue2;
479 data1[kKey3] = kValue3;
480 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
481 ValuesMap data2;
482 data2[kKey1] = kValue2;
483 data2[kKey3] = kValue1;
484 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
485 // Make a shallow copy.
486 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
487 // Now both namespaces should have the same data.
488 CheckDatabaseConsistency();
489 CheckAreaData(kNamespace1, kOrigin1, data1);
490 CheckAreaData(kNamespace1, kOrigin2, data2);
491 CheckAreaData(kNamespaceClone, kOrigin1, data1);
492 CheckAreaData(kNamespaceClone, kOrigin2, data2);
493 // Both the namespaces refer to the same maps.
494 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin1),
495 GetMapForArea(kNamespaceClone, kOrigin1));
496 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin2),
497 GetMapForArea(kNamespaceClone, kOrigin2));
498 EXPECT_EQ(2, GetMapRefCount(GetMapForArea(kNamespace1, kOrigin1)));
499 EXPECT_EQ(2, GetMapRefCount(GetMapForArea(kNamespace1, kOrigin2)));
500 }
501
502 TEST_F(SessionStorageDatabaseTest, WriteIntoShallowCopy) {
503 ValuesMap data1;
504 data1[kKey1] = kValue1;
505 data1[kKey2] = kValue2;
506 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
507 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
508
509 // Write data into a shallow copy.
510 ValuesMap changes;
511 ValuesMap reference;
512 changes[kKey1] = kValueNull;
513 changes[kKey2] = kValue4;
514 changes[kKey3] = kValue4;
515 reference[kKey2] = kValue4;
516 reference[kKey3] = kValue4;
517 EXPECT_TRUE(db_->CommitAreaChanges(kNamespaceClone, kOrigin1, false,
518 changes));
519
520 // Values in the original namespace were not changed.
521 CheckAreaData(kNamespace1, kOrigin1, data1);
522 // But values in the copy were.
523 CheckAreaData(kNamespaceClone, kOrigin1, reference);
524
525 // The namespaces no longer refer to the same map.
526 EXPECT_NE(GetMapForArea(kNamespace1, kOrigin1),
527 GetMapForArea(kNamespaceClone, kOrigin1));
528 EXPECT_EQ(1, GetMapRefCount(GetMapForArea(kNamespace1, kOrigin1)));
529 EXPECT_EQ(1, GetMapRefCount(GetMapForArea(kNamespaceClone, kOrigin1)));
530 }
531
532 TEST_F(SessionStorageDatabaseTest, ManyShallowCopies) {
533 // Write data for a namespace, for 2 origins.
534 ValuesMap data1;
535 data1[kKey1] = kValue1;
536 data1[kKey2] = kValue2;
537 data1[kKey3] = kValue3;
538 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
539 ValuesMap data2;
540 data2[kKey1] = kValue2;
541 data2[kKey3] = kValue1;
542 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
543
544 // Make a two shallow copies.
545 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
546 std::string another_clone("another_cloned");
547 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, another_clone));
548
549 // Make a shallow copy of a shallow copy.
550 std::string clone_of_clone("clone_of_clone");
551 EXPECT_TRUE(db_->CloneNamespace(another_clone, clone_of_clone));
552
553 // Now all namespaces should have the same data.
554 CheckDatabaseConsistency();
555 CheckAreaData(kNamespace1, kOrigin1, data1);
556 CheckAreaData(kNamespaceClone, kOrigin1, data1);
557 CheckAreaData(another_clone, kOrigin1, data1);
558 CheckAreaData(clone_of_clone, kOrigin1, data1);
559 CheckAreaData(kNamespace1, kOrigin2, data2);
560 CheckAreaData(kNamespaceClone, kOrigin2, data2);
561 CheckAreaData(another_clone, kOrigin2, data2);
562 CheckAreaData(clone_of_clone, kOrigin2, data2);
563
564 // All namespaces refer to the same maps.
565 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin1),
566 GetMapForArea(kNamespaceClone, kOrigin1));
567 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin2),
568 GetMapForArea(kNamespaceClone, kOrigin2));
569 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin1),
570 GetMapForArea(another_clone, kOrigin1));
571 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin2),
572 GetMapForArea(another_clone, kOrigin2));
573 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin1),
574 GetMapForArea(clone_of_clone, kOrigin1));
575 EXPECT_EQ(GetMapForArea(kNamespace1, kOrigin2),
576 GetMapForArea(clone_of_clone, kOrigin2));
577
578 // Check the ref counts.
579 EXPECT_EQ(4, GetMapRefCount(GetMapForArea(kNamespace1, kOrigin1)));
580 EXPECT_EQ(4, GetMapRefCount(GetMapForArea(kNamespace1, kOrigin2)));
581 }
582
583 TEST_F(SessionStorageDatabaseTest, DisassociateShallowCopy) {
584 ValuesMap data1;
585 data1[kKey1] = kValue1;
586 data1[kKey2] = kValue2;
587 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
588 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
589
590 // Disassoaciate the shallow copy.
591 EXPECT_TRUE(db_->DeleteArea(kNamespaceClone, kOrigin1));
592 CheckDatabaseConsistency();
593
594 // Now new data can be written to that map.
595 ValuesMap reference;
596 ValuesMap changes;
597 changes[kKey1] = kValueNull;
598 changes[kKey2] = kValue4;
599 changes[kKey3] = kValue4;
600 reference[kKey2] = kValue4;
601 reference[kKey3] = kValue4;
602 EXPECT_TRUE(db_->CommitAreaChanges(kNamespaceClone, kOrigin1, false,
603 changes));
604
605 // Values in the original map were not changed.
606 CheckAreaData(kNamespace1, kOrigin1, data1);
607
608 // But values in the disassociated map were.
609 CheckAreaData(kNamespaceClone, kOrigin1, reference);
610 }
611
612 TEST_F(SessionStorageDatabaseTest, DeleteNamespace) {
613 ValuesMap data1;
614 data1[kKey1] = kValue1;
615 data1[kKey2] = kValue2;
616 data1[kKey3] = kValue3;
617 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
618 ValuesMap data2;
619 data2[kKey2] = kValue4;
620 data2[kKey3] = kValue3;
621 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
622 EXPECT_TRUE(db_->DeleteNamespace(kNamespace1));
623 CheckDatabaseConsistency();
624 CheckEmptyDatabase();
625 }
626
627 TEST_F(SessionStorageDatabaseTest, DeleteNamespaceWithShallowCopy) {
628 // Write data for a namespace, for 2 origins.
629 ValuesMap data1;
630 data1[kKey1] = kValue1;
631 data1[kKey2] = kValue2;
632 data1[kKey3] = kValue3;
633 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
634 ValuesMap data2;
635 data2[kKey1] = kValue2;
636 data2[kKey3] = kValue1;
637 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
638
639 // Make a shallow copy and delete the original namespace.
640 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
641 EXPECT_TRUE(db_->DeleteNamespace(kNamespace1));
642
643 // The original namespace has no data.
644 CheckDatabaseConsistency();
645 CheckAreaData(kNamespace1, kOrigin1, ValuesMap());
646 CheckAreaData(kNamespace1, kOrigin2, ValuesMap());
647 // But the copy persists.
648 CheckAreaData(kNamespaceClone, kOrigin1, data1);
649 CheckAreaData(kNamespaceClone, kOrigin2, data2);
650 }
651
652 TEST_F(SessionStorageDatabaseTest, DeleteArea) {
653 // Write data for a namespace, for 2 origins.
654 ValuesMap data1;
655 data1[kKey1] = kValue1;
656 data1[kKey2] = kValue2;
657 data1[kKey3] = kValue3;
658 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
659 ValuesMap data2;
660 data2[kKey1] = kValue2;
661 data2[kKey3] = kValue1;
662 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
663
664 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin2));
665 CheckDatabaseConsistency();
666 // The data for the non-deleted origin persists.
667 CheckAreaData(kNamespace1, kOrigin1, data1);
668 // The data for the deleted origin is gone.
669 CheckAreaData(kNamespace1, kOrigin2, ValuesMap());
670 }
671
672 TEST_F(SessionStorageDatabaseTest, DeleteAreaWithShallowCopy) {
673 // Write data for a namespace, for 2 origins.
674 ValuesMap data1;
675 data1[kKey1] = kValue1;
676 data1[kKey2] = kValue2;
677 data1[kKey3] = kValue3;
678 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
679 ValuesMap data2;
680 data2[kKey1] = kValue2;
681 data2[kKey3] = kValue1;
682 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
683
684 // Make a shallow copy and delete an origin from the original namespace.
685 EXPECT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
686 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin1));
687 CheckDatabaseConsistency();
688
689 // The original namespace has data for only the non-deleted origin.
690 CheckAreaData(kNamespace1, kOrigin1, ValuesMap());
691 CheckAreaData(kNamespace1, kOrigin2, data2);
692 // But the copy persists.
693 CheckAreaData(kNamespaceClone, kOrigin1, data1);
694 CheckAreaData(kNamespaceClone, kOrigin2, data2);
695 }
696
697 TEST_F(SessionStorageDatabaseTest, WriteRawBytes) {
698 // Write data which is not valid utf8 and contains null bytes.
699 unsigned char raw_data[10] = {255, 0, 0, 0, 1, 2, 3, 4, 5, 0};
700 ValuesMap changes;
701 base::string16 string_with_raw_data;
702 string_with_raw_data.assign(reinterpret_cast<char16*>(raw_data), 5);
703 changes[kKey1] = NullableString16(string_with_raw_data, false);
704 EXPECT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, changes));
705 CheckDatabaseConsistency();
706 ValuesMap values;
707 db_->ReadAreaValues(kNamespace1, kOrigin1, &values);
708 const unsigned char* data =
709 reinterpret_cast<const unsigned char*>(values[kKey1].string().data());
710 for (int i = 0; i < 10; ++i)
711 EXPECT_EQ(raw_data[i], data[i]);
712 }
713
714 TEST_F(SessionStorageDatabaseTest, DeleteNamespaceConfusion) {
715 // Regression test for a bug where a namespace with id 10 prevented deleting
716 // the namespace with id 1.
717
718 ValuesMap data1;
719 data1[kKey1] = kValue1;
720 ASSERT_TRUE(db_->CommitAreaChanges("foobar", kOrigin1, false, data1));
721 ASSERT_TRUE(db_->CommitAreaChanges("foobarbaz", kOrigin1, false, data1));
722
723 // Delete the namespace with ID 1.
724 EXPECT_TRUE(db_->DeleteNamespace("foobar"));
725 }
726
727 TEST_F(SessionStorageDatabaseTest, ReadNamespaceIds) {
728 ValuesMap data1;
729 data1[kKey1] = kValue1;
730 data1[kKey2] = kValue2;
731 data1[kKey3] = kValue3;
732 std::set<std::string> expected_namespace_ids;
733
734 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
735 expected_namespace_ids.insert(kNamespace1);
736 CheckNamespaceIds(expected_namespace_ids);
737
738 ASSERT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
739 expected_namespace_ids.insert(kNamespaceClone);
740 CheckNamespaceIds(expected_namespace_ids);
741
742 ASSERT_TRUE(db_->DeleteNamespace(kNamespace1));
743 expected_namespace_ids.erase(kNamespace1);
744 CheckNamespaceIds(expected_namespace_ids);
745
746 CheckDatabaseConsistency();
747 }
748
749 TEST_F(SessionStorageDatabaseTest, ReadNamespaceIdsInEmptyDatabase) {
750 std::set<std::string> expected_namespace_ids;
751 CheckNamespaceIds(expected_namespace_ids);
752 }
753
754 TEST_F(SessionStorageDatabaseTest, ReadOriginsInNamespace) {
755 ValuesMap data1;
756 data1[kKey1] = kValue1;
757 data1[kKey2] = kValue2;
758 data1[kKey3] = kValue3;
759
760 std::set<GURL> expected_origins1;
761 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
762 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data1));
763 expected_origins1.insert(kOrigin1);
764 expected_origins1.insert(kOrigin2);
765 CheckOrigins(kNamespace1, expected_origins1);
766
767 std::set<GURL> expected_origins2;
768 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace2, kOrigin2, false, data1));
769 expected_origins2.insert(kOrigin2);
770 CheckOrigins(kNamespace2, expected_origins2);
771
772 ASSERT_TRUE(db_->CloneNamespace(kNamespace1, kNamespaceClone));
773 CheckOrigins(kNamespaceClone, expected_origins1);
774
775 ASSERT_TRUE(db_->DeleteArea(kNamespace1, kOrigin2));
776 expected_origins1.erase(kOrigin2);
777 CheckOrigins(kNamespace1, expected_origins1);
778
779 CheckDatabaseConsistency();
780 }
781
782 TEST_F(SessionStorageDatabaseTest, DeleteAllOrigins) {
783 // Write data for a namespace, for 2 origins.
784 ValuesMap data1;
785 data1[kKey1] = kValue1;
786 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
787 ValuesMap data2;
788 data2[kKey1] = kValue2;
789 ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
790
791 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin1));
792 EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin2));
793 // Check that also the namespace start key was deleted.
794 CheckDatabaseConsistency();
795 }
796
797
798 } // namespace dom_storage
OLDNEW
« no previous file with comments | « webkit/dom_storage/session_storage_database_adapter.cc ('k') | webkit/dom_storage/webkit_dom_storage.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698