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

Side by Side Diff: content/browser/indexed_db/indexed_db_backing_store_unittest.cc

Issue 15564008: Migrate the IndexedDB backend from Blink to Chromium (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Accessor naming, use LevelDBSlice ctor explicitly Created 7 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) 2013 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 "content/browser/indexed_db/indexed_db_backing_store.h"
6
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "base/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
12 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
16
17 using namespace content;
18 using IndexedDBLevelDBCoding::KeyPrefix;
19 using WebKit::WebSecurityOrigin;
20 using WebKit::WebIDBKey;
21
22 namespace {
23
24 class IndexedDBBackingStoreTest : public testing::Test {
25 public:
26 IndexedDBBackingStoreTest() {}
27 virtual void SetUp() {
28 string16 file_identifier;
29 backing_store_ = IndexedDBBackingStore::OpenInMemory(file_identifier);
30
31 // useful keys and values during tests
32 const char raw_value1[] = "value1";
33
34 const char raw_value2[] = "value2";
35 const char raw_value3[] = "value3";
36 m_value1.insert(
37 m_value1.end(), &raw_value1[0], &raw_value1[0] + sizeof(raw_value1));
38 m_value2.insert(
39 m_value2.end(), &raw_value2[0], &raw_value2[0] + sizeof(raw_value2));
40 m_value3.insert(
41 m_value3.end(), &raw_value3[0], &raw_value3[0] + sizeof(raw_value3));
42 m_key1 = IndexedDBKey(99, WebIDBKey::NumberType);
43 m_key2 = IndexedDBKey(ASCIIToUTF16("key2"));
44 m_key3 = IndexedDBKey(ASCIIToUTF16("key3"));
45 }
46
47 protected:
48 scoped_refptr<IndexedDBBackingStore> backing_store_;
49
50 // Sample keys and values that are consistent.
51 IndexedDBKey m_key1;
52 IndexedDBKey m_key2;
53 IndexedDBKey m_key3;
54 std::vector<char> m_value1;
55 std::vector<char> m_value2;
56 std::vector<char> m_value3;
57 };
58
59 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
60 {
61 IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
62 transaction1.begin();
63 IndexedDBBackingStore::RecordIdentifier record;
64 bool ok = backing_store_->PutRecord(
65 &transaction1, 1, 1, m_key1, m_value1, &record);
66 EXPECT_TRUE(ok);
67 transaction1.Commit();
68 }
69
70 {
71 IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
72 transaction2.begin();
73 std::vector<char> result_value;
74 bool ok =
75 backing_store_->GetRecord(&transaction2, 1, 1, m_key1, result_value);
76 transaction2.Commit();
77 EXPECT_TRUE(ok);
78 EXPECT_EQ(m_value1, result_value);
79 }
80 }
81
82 // Make sure that using very high ( more than 32 bit ) values for database_id
83 // and object_store_id still work.
84 TEST_F(IndexedDBBackingStoreTest, HighIds) {
85 const int64_t high_database_id = 1ULL << 35;
86 const int64_t high_object_store_id = 1ULL << 39;
87 // index_ids are capped at 32 bits for storage purposes.
88 const int64_t high_index_id = 1ULL << 29;
89
90 const int64_t invalid_high_index_id = 1ULL << 37;
91
92 const IndexedDBKey& index_key = m_key2;
93 std::vector<char> index_key_raw =
94 IndexedDBLevelDBCoding::EncodeIDBKey(index_key);
95 {
96 IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
97 transaction1.begin();
98 IndexedDBBackingStore::RecordIdentifier record;
99 bool ok = backing_store_->PutRecord(&transaction1,
100 high_database_id,
101 high_object_store_id,
102 m_key1,
103 m_value1,
104 &record);
105 EXPECT_TRUE(ok);
106
107 ok = backing_store_->PutIndexDataForRecord(&transaction1,
108 high_database_id,
109 high_object_store_id,
110 invalid_high_index_id,
111 index_key,
112 record);
113 EXPECT_FALSE(ok);
114
115 ok = backing_store_->PutIndexDataForRecord(&transaction1,
116 high_database_id,
117 high_object_store_id,
118 high_index_id,
119 index_key,
120 record);
121 EXPECT_TRUE(ok);
122
123 ok = transaction1.Commit();
124 EXPECT_TRUE(ok);
125 }
126
127 {
128 IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
129 transaction2.begin();
130 std::vector<char> result_value;
131 bool ok = backing_store_->GetRecord(&transaction2,
132 high_database_id,
133 high_object_store_id,
134 m_key1,
135 result_value);
136 EXPECT_TRUE(ok);
137 EXPECT_EQ(m_value1, result_value);
138
139 scoped_ptr<IndexedDBKey> new_primary_key;
140 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
141 high_database_id,
142 high_object_store_id,
143 invalid_high_index_id,
144 index_key,
145 &new_primary_key);
146 EXPECT_FALSE(ok);
147
148 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
149 high_database_id,
150 high_object_store_id,
151 high_index_id,
152 index_key,
153 &new_primary_key);
154 EXPECT_TRUE(ok);
155 EXPECT_TRUE(new_primary_key->IsEqual(m_key1));
156
157 ok = transaction2.Commit();
158 EXPECT_TRUE(ok);
159 }
160 }
161
162 // Make sure that other invalid ids do not crash.
163 TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
164 // valid ids for use when testing invalid ids
165 const int64_t database_id = 1;
166 const int64_t object_store_id = 1;
167 const int64_t index_id = IndexedDBLevelDBCoding::MinimumIndexId;
168 const int64_t invalid_low_index_id =
169 19; // index_ids must be > IndexedDBLevelDBCoding::MinimumIndexId
170
171 std::vector<char> result_value;
172
173 IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
174 transaction1.begin();
175
176 IndexedDBBackingStore::RecordIdentifier record;
177 bool ok = backing_store_->PutRecord(&transaction1,
178 database_id,
179 KeyPrefix::InvalidId,
180 m_key1,
181 m_value1,
182 &record);
183 EXPECT_FALSE(ok);
184 ok = backing_store_->PutRecord(
185 &transaction1, database_id, 0, m_key1, m_value1, &record);
186 EXPECT_FALSE(ok);
187 ok = backing_store_->PutRecord(&transaction1,
188 KeyPrefix::InvalidId,
189 object_store_id,
190 m_key1,
191 m_value1,
192 &record);
193 EXPECT_FALSE(ok);
194 ok = backing_store_->PutRecord(
195 &transaction1, 0, object_store_id, m_key1, m_value1, &record);
196 EXPECT_FALSE(ok);
197
198 ok = backing_store_->GetRecord(
199 &transaction1, database_id, KeyPrefix::InvalidId, m_key1, result_value);
200 EXPECT_FALSE(ok);
201 ok = backing_store_->GetRecord(
202 &transaction1, database_id, 0, m_key1, result_value);
203 EXPECT_FALSE(ok);
204 ok = backing_store_->GetRecord(&transaction1,
205 KeyPrefix::InvalidId,
206 object_store_id,
207 m_key1,
208 result_value);
209 EXPECT_FALSE(ok);
210 ok = backing_store_->GetRecord(
211 &transaction1, 0, object_store_id, m_key1, result_value);
212 EXPECT_FALSE(ok);
213
214 scoped_ptr<IndexedDBKey> new_primary_key;
215 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
216 database_id,
217 object_store_id,
218 KeyPrefix::InvalidId,
219 m_key1,
220 &new_primary_key);
221 EXPECT_FALSE(ok);
222 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
223 database_id,
224 object_store_id,
225 invalid_low_index_id,
226 m_key1,
227 &new_primary_key);
228 EXPECT_FALSE(ok);
229 ok = backing_store_->GetPrimaryKeyViaIndex(
230 &transaction1, database_id, object_store_id, 0, m_key1, &new_primary_key);
231 EXPECT_FALSE(ok);
232
233 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
234 KeyPrefix::InvalidId,
235 object_store_id,
236 index_id,
237 m_key1,
238 &new_primary_key);
239 EXPECT_FALSE(ok);
240 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
241 database_id,
242 KeyPrefix::InvalidId,
243 index_id,
244 m_key1,
245 &new_primary_key);
246 EXPECT_FALSE(ok);
247 }
248
249 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
250 const string16 database_name(ASCIIToUTF16("db1"));
251 int64_t database_id;
252 const string16 version(ASCIIToUTF16("old_string_version"));
253 const int64_t int_version = 9;
254
255 const int64_t object_store_id = 99;
256 const string16 object_store_name(ASCIIToUTF16("object_store1"));
257 const bool auto_increment = true;
258 const IndexedDBKeyPath object_store_key_path(
259 ASCIIToUTF16("object_store_key"));
260
261 const int64_t index_id = 999;
262 const string16 index_name(ASCIIToUTF16("index1"));
263 const bool unique = true;
264 const bool multi_entry = true;
265 const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key"));
266
267 {
268 bool ok = backing_store_->CreateIDBDatabaseMetaData(
269 database_name, version, int_version, database_id);
270 EXPECT_TRUE(ok);
271 EXPECT_GT(database_id, 0);
272
273 IndexedDBBackingStore::Transaction transaction(backing_store_.get());
274 transaction.begin();
275
276 ok = backing_store_->CreateObjectStore(&transaction,
277 database_id,
278 object_store_id,
279 object_store_name,
280 object_store_key_path,
281 auto_increment);
282 EXPECT_TRUE(ok);
283
284 ok = backing_store_->CreateIndex(&transaction,
285 database_id,
286 object_store_id,
287 index_id,
288 index_name,
289 index_key_path,
290 unique,
291 multi_entry);
292 EXPECT_TRUE(ok);
293
294 ok = transaction.Commit();
295 EXPECT_TRUE(ok);
296 }
297
298 {
299 IndexedDBDatabaseMetadata database;
300 bool found;
301 bool ok =
302 backing_store_->GetIDBDatabaseMetaData(database_name, &database, found);
303 EXPECT_TRUE(ok);
304 EXPECT_TRUE(found);
305
306 // database.name is not filled in by the implementation.
307 EXPECT_EQ(version, database.version);
308 EXPECT_EQ(int_version, database.int_version);
309 EXPECT_EQ(database_id, database.id);
310
311 ok = backing_store_->GetObjectStores(database.id, &database.object_stores);
312 EXPECT_TRUE(ok);
313
314 EXPECT_EQ(1UL, database.object_stores.size());
315 IndexedDBObjectStoreMetadata object_store =
316 database.object_stores[object_store_id];
317 EXPECT_EQ(object_store_name, object_store.name);
318 EXPECT_EQ(object_store_key_path, object_store.key_path);
319 EXPECT_EQ(auto_increment, object_store.auto_increment);
320
321 EXPECT_EQ(1UL, object_store.indexes.size());
322 IndexedDBIndexMetadata index = object_store.indexes[index_id];
323 EXPECT_EQ(index_name, index.name);
324 EXPECT_EQ(index_key_path, index.key_path);
325 EXPECT_EQ(unique, index.unique);
326 EXPECT_EQ(multi_entry, index.multi_entry);
327 }
328 }
329
330 class MockIDBFactory : public IndexedDBFactoryImpl {
331 public:
332 static scoped_refptr<MockIDBFactory> Create() {
333 return make_scoped_refptr(new MockIDBFactory());
334 }
335
336 scoped_refptr<IndexedDBBackingStore> TestOpenBackingStore(
337 const WebSecurityOrigin& origin,
338 const base::FilePath& data_directory) {
339 string16 path = UTF8ToUTF16(data_directory.AsUTF8Unsafe());
340 return OpenBackingStore(origin.databaseIdentifier(), path);
341 }
342
343 private:
344 virtual ~MockIDBFactory() {}
345 };
346
347 TEST(IndexedDBFactoryTest, BackingStoreLifetime) {
348 WebSecurityOrigin origin1 =
349 WebSecurityOrigin::createFromString("http://localhost:81");
350 WebSecurityOrigin origin2 =
351 WebSecurityOrigin::createFromString("http://localhost:82");
352
353 scoped_refptr<MockIDBFactory> factory = MockIDBFactory::Create();
354
355 base::ScopedTempDir temp_directory;
356 DCHECK(temp_directory.CreateUniqueTempDir());
357 scoped_refptr<IndexedDBBackingStore> disk_store1 =
358 factory->TestOpenBackingStore(origin1, temp_directory.path());
359 EXPECT_TRUE(disk_store1->HasOneRef());
360
361 scoped_refptr<IndexedDBBackingStore> disk_store2 =
362 factory->TestOpenBackingStore(origin1, temp_directory.path());
363 EXPECT_EQ(disk_store1.get(), disk_store2.get());
364 // XXX
365 //EXPECT_EQ(2, disk_store2->RefCount());
366
367 scoped_refptr<IndexedDBBackingStore> disk_store3 =
368 factory->TestOpenBackingStore(origin2, temp_directory.path());
369 EXPECT_TRUE(disk_store3->HasOneRef());
370 // XXX
371 // EXPECT_EQ(2, disk_store1->RefCount());
372 }
373
374 TEST(IndexedDBFactoryTest, MemoryBackingStoreLifetime) {
375 WebSecurityOrigin origin1 =
376 WebSecurityOrigin::createFromString("http://localhost:81");
377 WebSecurityOrigin origin2 =
378 WebSecurityOrigin::createFromString("http://localhost:82");
379
380 scoped_refptr<MockIDBFactory> factory = MockIDBFactory::Create();
381 scoped_refptr<IndexedDBBackingStore> mem_store1 =
382 factory->TestOpenBackingStore(origin1, base::FilePath());
383 // XXX
384 // EXPECT_EQ(2, mem_store1->RefCount());
385 scoped_refptr<IndexedDBBackingStore> mem_store2 =
386 factory->TestOpenBackingStore(origin1, base::FilePath());
387 EXPECT_EQ(mem_store1.get(), mem_store2.get());
388 // XXX
389 // EXPECT_EQ(3, mem_store2->RefCount());
390
391 scoped_refptr<IndexedDBBackingStore> mem_store3 =
392 factory->TestOpenBackingStore(origin2, base::FilePath());
393 // XXX
394 //EXPECT_EQ(2, mem_store3->RefCount());
395 //EXPECT_EQ(3, mem_store1->RefCount());
396
397 factory = NULL;
398 // XXX
399 // EXPECT_EQ(2, mem_store1->RefCount());
400 // EXPECT_EQ(1, mem_store3->RefCount());
401 }
402
403 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698