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

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

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

Powered by Google App Engine
This is Rietveld 408576698