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

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

Powered by Google App Engine
This is Rietveld 408576698