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

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

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged out--bot failed due to staleness. Created 6 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/indexed_db_backing_store.h" 5 #include "content/browser/indexed_db/indexed_db_backing_store.h"
6 6
7 #include "base/callback.h"
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
7 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h"
8 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "base/task_runner.h"
15 #include "base/test/test_simple_task_runner.h"
16 #include "content/browser/indexed_db/indexed_db_context_impl.h"
10 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 17 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
11 #include "content/browser/indexed_db/indexed_db_value.h" 18 #include "content/browser/indexed_db/indexed_db_value.h"
19 #include "content/public/test/mock_special_storage_policy.h"
20 #include "net/url_request/url_request_test_util.h"
12 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/platform/WebIDBTypes.h" 22 #include "third_party/WebKit/public/platform/WebIDBTypes.h"
23 #include "webkit/browser/blob/blob_data_handle.h"
24 #include "webkit/browser/quota/special_storage_policy.h"
14 25
15 using base::ASCIIToUTF16; 26 using base::ASCIIToUTF16;
16 27
17 namespace content { 28 namespace content {
18 29
19 namespace { 30 namespace {
20 31
32 class Comparator : public LevelDBComparator {
33 public:
34 virtual int Compare(const base::StringPiece& a,
35 const base::StringPiece& b) const OVERRIDE {
36 return content::Compare(a, b, false /*index_keys*/);
37 }
38 virtual const char* Name() const OVERRIDE { return "idb_cmp1"; }
39 };
40
41 class DefaultLevelDBFactory : public LevelDBFactory {
42 public:
43 virtual leveldb::Status OpenLevelDB(const base::FilePath& file_name,
44 const LevelDBComparator* comparator,
45 scoped_ptr<LevelDBDatabase>* db,
46 bool* is_disk_full) OVERRIDE {
47 return LevelDBDatabase::Open(file_name, comparator, db, is_disk_full);
48 }
49 virtual leveldb::Status DestroyLevelDB(
50 const base::FilePath& file_name) OVERRIDE {
51 return LevelDBDatabase::Destroy(file_name);
52 }
53 };
54
55 class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
56 public:
57 static scoped_refptr<TestableIndexedDBBackingStore> Open(
58 IndexedDBFactory* indexed_db_factory,
59 const GURL& origin_url,
60 const base::FilePath& path_base,
61 net::URLRequestContext* request_context,
62 LevelDBFactory* leveldb_factory,
63 base::TaskRunner* task_runner) {
64 DCHECK(!path_base.empty());
65
66 scoped_ptr<LevelDBComparator> comparator(new Comparator());
67
68 if (!base::CreateDirectory(path_base))
69 return scoped_refptr<TestableIndexedDBBackingStore>();
70
71 const base::FilePath file_path = path_base.AppendASCII("test_db_path");
72 const base::FilePath blob_path = path_base.AppendASCII("test_blob_path");
73
74 scoped_ptr<LevelDBDatabase> db;
75 bool is_disk_full = false;
76 leveldb::Status status = leveldb_factory->OpenLevelDB(
77 file_path, comparator.get(), &db, &is_disk_full);
78
79 if (!db || !status.ok())
80 return scoped_refptr<TestableIndexedDBBackingStore>();
81
82 scoped_refptr<TestableIndexedDBBackingStore> backing_store(
83 new TestableIndexedDBBackingStore(indexed_db_factory,
84 origin_url,
85 blob_path,
86 request_context,
87 db.Pass(),
88 comparator.Pass(),
89 task_runner));
90
91 if (!backing_store->SetUpMetadata())
92 return scoped_refptr<TestableIndexedDBBackingStore>();
93
94 return backing_store;
95 }
96
97 const std::vector<IndexedDBBackingStore::Transaction::WriteDescriptor>&
98 writes() const {
99 return writes_;
100 }
101 void ClearWrites() { writes_.clear(); }
102 const std::vector<int64>& removals() const { return removals_; }
103 void ClearRemovals() { removals_.clear(); }
104
105 protected:
106 virtual ~TestableIndexedDBBackingStore() {}
107
108 virtual bool WriteBlobFile(
109 int64 database_id,
110 const Transaction::WriteDescriptor& descriptor,
111 Transaction::ChainedBlobWriter* chained_blob_writer) OVERRIDE {
112 if (KeyPrefix::IsValidDatabaseId(database_id_)) {
113 if (database_id_ != database_id) {
114 return false;
115 }
116 } else {
117 database_id_ = database_id;
118 }
119 writes_.push_back(descriptor);
120 task_runner()->PostTask(
121 FROM_HERE,
122 base::Bind(&Transaction::ChainedBlobWriter::ReportWriteCompletion,
123 chained_blob_writer,
124 true,
125 1));
126 return true;
127 }
128
129 virtual bool RemoveBlobFile(int64 database_id, int64 key) OVERRIDE {
130 if (database_id_ != database_id ||
131 !KeyPrefix::IsValidDatabaseId(database_id)) {
132 return false;
133 }
134 removals_.push_back(key);
135 return true;
136 }
137
138 // Timers don't play nicely with unit tests.
139 virtual void StartJournalCleaningTimer() OVERRIDE {
140 CleanPrimaryJournalIgnoreReturn();
141 }
142
143 private:
144 TestableIndexedDBBackingStore(IndexedDBFactory* indexed_db_factory,
145 const GURL& origin_url,
146 const base::FilePath& blob_path,
147 net::URLRequestContext* request_context,
148 scoped_ptr<LevelDBDatabase> db,
149 scoped_ptr<LevelDBComparator> comparator,
150 base::TaskRunner* task_runner)
151 : IndexedDBBackingStore(indexed_db_factory,
152 origin_url,
153 blob_path,
154 request_context,
155 db.Pass(),
156 comparator.Pass(),
157 task_runner),
158 database_id_(0) {}
159
160 int64 database_id_;
161 std::vector<Transaction::WriteDescriptor> writes_;
162 std::vector<int64> removals_;
163 };
164
165 class TestIDBFactory : public IndexedDBFactory {
166 public:
167 TestIDBFactory(IndexedDBContextImpl* idb_context)
168 : IndexedDBFactory(idb_context) {}
169
170 scoped_refptr<TestableIndexedDBBackingStore> OpenBackingStoreForTest(
171 const GURL& origin,
172 net::URLRequestContext* url_request_context) {
173 blink::WebIDBDataLoss data_loss;
174 std::string data_loss_reason;
175 bool disk_full;
176 scoped_refptr<IndexedDBBackingStore> backing_store =
177 OpenBackingStore(origin,
178 context()->data_path(),
179 url_request_context,
180 &data_loss,
181 &data_loss_reason,
182 &disk_full);
183 scoped_refptr<TestableIndexedDBBackingStore> testable_store =
184 static_cast<TestableIndexedDBBackingStore*>(backing_store.get());
185 return testable_store;
186 }
187
188 protected:
189 virtual ~TestIDBFactory() {}
190
191 virtual scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper(
192 const GURL& origin_url,
193 const base::FilePath& data_directory,
194 net::URLRequestContext* request_context,
195 blink::WebIDBDataLoss* data_loss,
196 std::string* data_loss_message,
197 bool* disk_full,
198 bool first_time) OVERRIDE {
199 DefaultLevelDBFactory leveldb_factory;
200 return TestableIndexedDBBackingStore::Open(this,
201 origin_url,
202 data_directory,
203 request_context,
204 &leveldb_factory,
205 context()->TaskRunner());
206 }
207 };
208
21 class IndexedDBBackingStoreTest : public testing::Test { 209 class IndexedDBBackingStoreTest : public testing::Test {
22 public: 210 public:
23 IndexedDBBackingStoreTest() {} 211 IndexedDBBackingStoreTest() {}
24 virtual void SetUp() { 212 virtual void SetUp() {
25 const GURL origin("http://localhost:81"); 213 const GURL origin("http://localhost:81");
214 task_runner_ = new base::TestSimpleTaskRunner();
215 special_storage_policy_ = new MockSpecialStoragePolicy();
216 special_storage_policy_->SetAllUnlimited(true);
217 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
218 idb_context_ = new IndexedDBContextImpl(
219 temp_dir_.path(), special_storage_policy_, NULL, task_runner_);
220 idb_factory_ = new TestIDBFactory(idb_context_);
26 backing_store_ = 221 backing_store_ =
27 IndexedDBBackingStore::OpenInMemory(origin, NULL /* task_runner */); 222 idb_factory_->OpenBackingStoreForTest(origin, &url_request_context_);
28 223
29 // useful keys and values during tests 224 // useful keys and values during tests
30 m_value1 = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>()); 225 m_value1 = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>());
31 m_value2 = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>()); 226 m_value2 = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>());
32 227
228 m_blob_info.push_back(
229 IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("blob type"), 1));
230 m_blob_info.push_back(
231 IndexedDBBlobInfo("uuid 4",
232 base::FilePath(FILE_PATH_LITERAL("path/to/file")),
233 base::UTF8ToUTF16("file name"),
234 base::UTF8ToUTF16("file type")));
235 m_value3 = IndexedDBValue("value3", m_blob_info);
236
33 m_key1 = IndexedDBKey(99, blink::WebIDBKeyTypeNumber); 237 m_key1 = IndexedDBKey(99, blink::WebIDBKeyTypeNumber);
34 m_key2 = IndexedDBKey(ASCIIToUTF16("key2")); 238 m_key2 = IndexedDBKey(ASCIIToUTF16("key2"));
239 m_key3 = IndexedDBKey(ASCIIToUTF16("key3"));
240 }
241
242 // This just checks the data that survive getting stored and recalled, e.g.
243 // the file path and UUID will change and thus aren't verified.
244 bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const {
245 if (m_blob_info.size() != reads.size())
246 return false;
247 for (size_t i = 0; i < m_blob_info.size(); ++i) {
248 const IndexedDBBlobInfo& a = m_blob_info[i];
249 const IndexedDBBlobInfo& b = reads[i];
250 if (a.is_file() != b.is_file())
251 return false;
252 if (a.type() != b.type())
253 return false;
254 if (a.is_file()) {
255 if (a.file_name() != b.file_name())
256 return false;
257 } else {
258 if (a.size() != b.size())
259 return false;
260 }
261 }
262 return true;
263 }
264
265 bool CheckBlobReadsMatchWrites(
266 const std::vector<IndexedDBBlobInfo>& reads) const {
267 if (backing_store_->writes().size() != reads.size())
268 return false;
269 std::set<int64> ids;
270 for (size_t i = 0; i < backing_store_->writes().size(); ++i)
271 ids.insert(backing_store_->writes()[i].key());
272 if (ids.size() != backing_store_->writes().size())
273 return false;
274 for (size_t i = 0; i < reads.size(); ++i) {
275 if (ids.count(reads[i].key()) != 1)
276 return false;
277 }
278 return true;
279 }
280
281 bool CheckBlobWrites() const {
282 if (backing_store_->writes().size() != m_blob_info.size())
283 return false;
284 for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
285 const IndexedDBBackingStore::Transaction::WriteDescriptor& desc =
286 backing_store_->writes()[i];
287 const IndexedDBBlobInfo& info = m_blob_info[i];
288 if (desc.is_file() != info.is_file())
289 return false;
290 if (desc.is_file()) {
291 if (desc.file_path() != info.file_path())
292 return false;
293 } else {
294 if (desc.url() != GURL("blob:uuid/" + info.uuid()))
295 return false;
296 }
297 }
298 return true;
299 }
300
301 bool CheckBlobRemovals() const {
302 if (backing_store_->removals().size() != backing_store_->writes().size())
303 return false;
304 for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
305 if (backing_store_->writes()[i].key() != backing_store_->removals()[i])
306 return false;
307 }
308 return true;
35 } 309 }
36 310
37 protected: 311 protected:
38 scoped_refptr<IndexedDBBackingStore> backing_store_; 312 base::ScopedTempDir temp_dir_;
313 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
314 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
315 scoped_refptr<IndexedDBContextImpl> idb_context_;
316 scoped_refptr<TestIDBFactory> idb_factory_;
317 net::TestURLRequestContext url_request_context_;
318
319 scoped_refptr<TestableIndexedDBBackingStore> backing_store_;
39 320
40 // Sample keys and values that are consistent. 321 // Sample keys and values that are consistent.
41 IndexedDBKey m_key1; 322 IndexedDBKey m_key1;
42 IndexedDBKey m_key2; 323 IndexedDBKey m_key2;
324 IndexedDBKey m_key3;
43 IndexedDBValue m_value1; 325 IndexedDBValue m_value1;
44 IndexedDBValue m_value2; 326 IndexedDBValue m_value2;
327 IndexedDBValue m_value3;
328 std::vector<IndexedDBBlobInfo> m_blob_info;
45 329
46 private: 330 private:
47 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest); 331 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
48 }; 332 };
49 333
334 class TestCallback : public IndexedDBBackingStore::BlobWriteCallback {
335 public:
336 TestCallback() : called(false), succeeded(false) {}
337 virtual void Run(bool succeeded_in) OVERRIDE {
338 called = true;
339 succeeded = succeeded_in;
340 }
341 bool called;
342 bool succeeded;
343
344 protected:
345 virtual ~TestCallback() {}
346 };
347
50 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { 348 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
51 { 349 {
52 IndexedDBBackingStore::Transaction transaction1(backing_store_); 350 IndexedDBBackingStore::Transaction transaction1(backing_store_);
53 transaction1.Begin(); 351 transaction1.Begin();
54 ScopedVector<webkit_blob::BlobDataHandle> handles; 352 ScopedVector<webkit_blob::BlobDataHandle> handles;
55 IndexedDBBackingStore::RecordIdentifier record; 353 IndexedDBBackingStore::RecordIdentifier record;
56 leveldb::Status s = backing_store_->PutRecord( 354 leveldb::Status s = backing_store_->PutRecord(
57 &transaction1, 1, 1, m_key1, m_value1, &handles, &record); 355 &transaction1, 1, 1, m_key1, m_value1, &handles, &record);
58 EXPECT_TRUE(s.ok()); 356 EXPECT_TRUE(s.ok());
59 transaction1.Commit(); 357 scoped_refptr<TestCallback> callback(new TestCallback());
358 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
359 EXPECT_TRUE(callback->called);
360 EXPECT_TRUE(callback->succeeded);
361 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
60 } 362 }
61 363
62 { 364 {
63 IndexedDBBackingStore::Transaction transaction2(backing_store_); 365 IndexedDBBackingStore::Transaction transaction2(backing_store_);
64 transaction2.Begin(); 366 transaction2.Begin();
65 IndexedDBValue result_value; 367 IndexedDBValue result_value;
66 leveldb::Status s = 368 EXPECT_TRUE(
67 backing_store_->GetRecord(&transaction2, 1, 1, m_key1, &result_value); 369 backing_store_->GetRecord(&transaction2, 1, 1, m_key1, &result_value)
68 transaction2.Commit(); 370 .ok());
69 EXPECT_TRUE(s.ok()); 371 scoped_refptr<TestCallback> callback(new TestCallback());
372 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
373 EXPECT_TRUE(callback->called);
374 EXPECT_TRUE(callback->succeeded);
375 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
70 EXPECT_EQ(m_value1.bits, result_value.bits); 376 EXPECT_EQ(m_value1.bits, result_value.bits);
71 } 377 }
72 } 378 }
73 379
380 TEST_F(IndexedDBBackingStoreTest, PutGetConsistencyWithBlobs) {
381 {
382 IndexedDBBackingStore::Transaction transaction1(backing_store_);
383 transaction1.Begin();
384 ScopedVector<webkit_blob::BlobDataHandle> handles;
385 IndexedDBBackingStore::RecordIdentifier record;
386 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
387 1,
388 1,
389 m_key3,
390 m_value3,
391 &handles,
392 &record).ok());
393 scoped_refptr<TestCallback> callback(new TestCallback());
394 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
395 task_runner_->RunUntilIdle();
396 EXPECT_TRUE(CheckBlobWrites());
397 EXPECT_TRUE(callback->called);
398 EXPECT_TRUE(callback->succeeded);
399 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
400 }
401
402 {
403 IndexedDBBackingStore::Transaction transaction2(backing_store_);
404 transaction2.Begin();
405 IndexedDBValue result_value;
406 EXPECT_TRUE(
407 backing_store_->GetRecord(&transaction2, 1, 1, m_key3, &result_value)
408 .ok());
409 scoped_refptr<TestCallback> callback(new TestCallback());
410 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
411 EXPECT_TRUE(callback->called);
412 EXPECT_TRUE(callback->succeeded);
413 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
414 EXPECT_EQ(m_value3.bits, result_value.bits);
415 EXPECT_TRUE(CheckBlobInfoMatches(result_value.blob_info));
416 EXPECT_TRUE(CheckBlobReadsMatchWrites(result_value.blob_info));
417 }
418
419 {
420 IndexedDBBackingStore::Transaction transaction3(backing_store_);
421 transaction3.Begin();
422 IndexedDBValue result_value;
423 EXPECT_TRUE(backing_store_->DeleteRange(&transaction3,
424 1,
425 1,
426 IndexedDBKeyRange(m_key3)).ok());
427 scoped_refptr<TestCallback> callback(new TestCallback());
428 EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok());
429 task_runner_->RunUntilIdle();
430 EXPECT_TRUE(callback->called);
431 EXPECT_TRUE(callback->succeeded);
432 EXPECT_TRUE(transaction3.CommitPhaseTwo().ok());
433 EXPECT_TRUE(CheckBlobRemovals());
434 }
435 }
436
437 TEST_F(IndexedDBBackingStoreTest, DeleteRange) {
438 IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0"));
439 IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1"));
440 IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2"));
441 IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3"));
442 IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1);
443 IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1);
444 IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1);
445 IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1);
446 IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key1, key2, false, false),
447 IndexedDBKeyRange(key1, key2, false, false),
448 IndexedDBKeyRange(key0, key2, true, false),
449 IndexedDBKeyRange(key1, key3, false, true),
450 IndexedDBKeyRange(key0, key3, true, true)};
451
452 for (unsigned i = 0; i < sizeof(ranges) / sizeof(IndexedDBKeyRange); ++i) {
453 backing_store_->ClearWrites();
454 backing_store_->ClearRemovals();
455
456 {
457 std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2,
458 blob_info3;
459 blob_info0.push_back(blob0);
460 blob_info1.push_back(blob1);
461 blob_info2.push_back(blob2);
462 blob_info3.push_back(blob3);
463 IndexedDBValue value0 = IndexedDBValue("value0", blob_info0);
464 IndexedDBValue value1 = IndexedDBValue("value1", blob_info1);
465 IndexedDBValue value2 = IndexedDBValue("value2", blob_info2);
466 IndexedDBValue value3 = IndexedDBValue("value3", blob_info3);
467 IndexedDBBackingStore::Transaction transaction1(backing_store_);
468 transaction1.Begin();
469 ScopedVector<webkit_blob::BlobDataHandle> handles;
470 IndexedDBBackingStore::RecordIdentifier record;
471 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
472 1,
473 i + 1,
474 key0,
475 value0,
476 &handles,
477 &record).ok());
478 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
479 1,
480 i + 1,
481 key1,
482 value1,
483 &handles,
484 &record).ok());
485 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
486 1,
487 i + 1,
488 key2,
489 value2,
490 &handles,
491 &record).ok());
492 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
493 1,
494 i + 1,
495 key3,
496 value3,
497 &handles,
498 &record).ok());
499 scoped_refptr<TestCallback> callback(new TestCallback());
500 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
501 task_runner_->RunUntilIdle();
502 EXPECT_TRUE(callback->called);
503 EXPECT_TRUE(callback->succeeded);
504 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
505 }
506
507 {
508 IndexedDBBackingStore::Transaction transaction2(backing_store_);
509 transaction2.Begin();
510 IndexedDBValue result_value;
511 EXPECT_TRUE(
512 backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok());
513 scoped_refptr<TestCallback> callback(new TestCallback());
514 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
515 task_runner_->RunUntilIdle();
516 EXPECT_TRUE(callback->called);
517 EXPECT_TRUE(callback->succeeded);
518 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
519 EXPECT_EQ(2UL, backing_store_->removals().size());
520 EXPECT_EQ(backing_store_->writes()[1].key(),
521 backing_store_->removals()[0]);
522 EXPECT_EQ(backing_store_->writes()[2].key(),
523 backing_store_->removals()[1]);
524 }
525 }
526 }
527
528 TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) {
529 IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0"));
530 IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1"));
531 IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2"));
532 IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3"));
533 IndexedDBKey key4 = IndexedDBKey(ASCIIToUTF16("key4"));
534 IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1);
535 IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1);
536 IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1);
537 IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1);
538 IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key3, key4, true, false),
539 IndexedDBKeyRange(key2, key1, false, false),
540 IndexedDBKeyRange(key2, key1, true, true)};
541
542 for (unsigned i = 0; i < arraysize(ranges); ++i) {
543 backing_store_->ClearWrites();
544 backing_store_->ClearRemovals();
545
546 {
547 std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2,
548 blob_info3;
549 blob_info0.push_back(blob0);
550 blob_info1.push_back(blob1);
551 blob_info2.push_back(blob2);
552 blob_info3.push_back(blob3);
553 IndexedDBValue value0 = IndexedDBValue("value0", blob_info0);
554 IndexedDBValue value1 = IndexedDBValue("value1", blob_info1);
555 IndexedDBValue value2 = IndexedDBValue("value2", blob_info2);
556 IndexedDBValue value3 = IndexedDBValue("value3", blob_info3);
557 IndexedDBBackingStore::Transaction transaction1(backing_store_);
558 transaction1.Begin();
559 ScopedVector<webkit_blob::BlobDataHandle> handles;
560 IndexedDBBackingStore::RecordIdentifier record;
561 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
562 1,
563 i + 1,
564 key0,
565 value0,
566 &handles,
567 &record).ok());
568 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
569 1,
570 i + 1,
571 key1,
572 value1,
573 &handles,
574 &record).ok());
575 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
576 1,
577 i + 1,
578 key2,
579 value2,
580 &handles,
581 &record).ok());
582 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
583 1,
584 i + 1,
585 key3,
586 value3,
587 &handles,
588 &record).ok());
589 scoped_refptr<TestCallback> callback(new TestCallback());
590 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
591 task_runner_->RunUntilIdle();
592 EXPECT_TRUE(callback->called);
593 EXPECT_TRUE(callback->succeeded);
594 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
595 }
596
597 {
598 IndexedDBBackingStore::Transaction transaction2(backing_store_);
599 transaction2.Begin();
600 IndexedDBValue result_value;
601 EXPECT_TRUE(
602 backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok());
603 scoped_refptr<TestCallback> callback(new TestCallback());
604 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
605 task_runner_->RunUntilIdle();
606 EXPECT_TRUE(callback->called);
607 EXPECT_TRUE(callback->succeeded);
608 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
609 EXPECT_EQ(0UL, backing_store_->removals().size());
610 }
611 }
612 }
613
614 TEST_F(IndexedDBBackingStoreTest, LiveBlobJournal) {
615 {
616 IndexedDBBackingStore::Transaction transaction1(backing_store_);
617 transaction1.Begin();
618 ScopedVector<webkit_blob::BlobDataHandle> handles;
619 IndexedDBBackingStore::RecordIdentifier record;
620 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
621 1,
622 1,
623 m_key3,
624 m_value3,
625 &handles,
626 &record).ok());
627 scoped_refptr<TestCallback> callback(new TestCallback());
628 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
629 task_runner_->RunUntilIdle();
630 EXPECT_TRUE(CheckBlobWrites());
631 EXPECT_TRUE(callback->called);
632 EXPECT_TRUE(callback->succeeded);
633 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
634 }
635
636 IndexedDBValue read_result_value;
637 {
638 IndexedDBBackingStore::Transaction transaction2(backing_store_);
639 transaction2.Begin();
640 EXPECT_TRUE(
641 backing_store_->GetRecord(
642 &transaction2, 1, 1, m_key3, &read_result_value)
643 .ok());
644 scoped_refptr<TestCallback> callback(new TestCallback());
645 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
646 EXPECT_TRUE(callback->called);
647 EXPECT_TRUE(callback->succeeded);
648 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
649 EXPECT_EQ(m_value3.bits, read_result_value.bits);
650 EXPECT_TRUE(CheckBlobInfoMatches(read_result_value.blob_info));
651 EXPECT_TRUE(CheckBlobReadsMatchWrites(read_result_value.blob_info));
652 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
653 read_result_value.blob_info[i].mark_used_callback().Run();
654 }
655 }
656
657 {
658 IndexedDBBackingStore::Transaction transaction3(backing_store_);
659 transaction3.Begin();
660 EXPECT_TRUE(backing_store_->DeleteRange(&transaction3,
661 1,
662 1,
663 IndexedDBKeyRange(m_key3)).ok());
664 scoped_refptr<TestCallback> callback(new TestCallback());
665 EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok());
666 task_runner_->RunUntilIdle();
667 EXPECT_TRUE(callback->called);
668 EXPECT_TRUE(callback->succeeded);
669 EXPECT_TRUE(transaction3.CommitPhaseTwo().ok());
670 EXPECT_EQ(0U, backing_store_->removals().size());
671 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
672 read_result_value.blob_info[i].release_callback().Run(
673 read_result_value.blob_info[i].file_path());
674 }
675 task_runner_->RunUntilIdle();
676 EXPECT_NE(0U, backing_store_->removals().size());
677 EXPECT_TRUE(CheckBlobRemovals());
678 }
679 }
680
74 // Make sure that using very high ( more than 32 bit ) values for database_id 681 // Make sure that using very high ( more than 32 bit ) values for database_id
75 // and object_store_id still work. 682 // and object_store_id still work.
76 TEST_F(IndexedDBBackingStoreTest, HighIds) { 683 TEST_F(IndexedDBBackingStoreTest, HighIds) {
77 const int64 high_database_id = 1ULL << 35; 684 const int64 high_database_id = 1ULL << 35;
78 const int64 high_object_store_id = 1ULL << 39; 685 const int64 high_object_store_id = 1ULL << 39;
79 // index_ids are capped at 32 bits for storage purposes. 686 // index_ids are capped at 32 bits for storage purposes.
80 const int64 high_index_id = 1ULL << 29; 687 const int64 high_index_id = 1ULL << 29;
81 688
82 const int64 invalid_high_index_id = 1ULL << 37; 689 const int64 invalid_high_index_id = 1ULL << 37;
83 690
(...skipping 23 matching lines...) Expand all
107 EXPECT_FALSE(s.ok()); 714 EXPECT_FALSE(s.ok());
108 715
109 s = backing_store_->PutIndexDataForRecord(&transaction1, 716 s = backing_store_->PutIndexDataForRecord(&transaction1,
110 high_database_id, 717 high_database_id,
111 high_object_store_id, 718 high_object_store_id,
112 high_index_id, 719 high_index_id,
113 index_key, 720 index_key,
114 record); 721 record);
115 EXPECT_TRUE(s.ok()); 722 EXPECT_TRUE(s.ok());
116 723
117 s = transaction1.Commit(); 724 scoped_refptr<TestCallback> callback(new TestCallback());
725 s = transaction1.CommitPhaseOne(callback);
726 EXPECT_TRUE(s.ok());
727 EXPECT_TRUE(callback->called);
728 EXPECT_TRUE(callback->succeeded);
729 s = transaction1.CommitPhaseTwo();
118 EXPECT_TRUE(s.ok()); 730 EXPECT_TRUE(s.ok());
119 } 731 }
120 732
121 { 733 {
122 IndexedDBBackingStore::Transaction transaction2(backing_store_); 734 IndexedDBBackingStore::Transaction transaction2(backing_store_);
123 transaction2.Begin(); 735 transaction2.Begin();
124 IndexedDBValue result_value; 736 IndexedDBValue result_value;
125 leveldb::Status s = backing_store_->GetRecord(&transaction2, 737 leveldb::Status s = backing_store_->GetRecord(&transaction2,
126 high_database_id, 738 high_database_id,
127 high_object_store_id, 739 high_object_store_id,
(...skipping 13 matching lines...) Expand all
141 753
142 s = backing_store_->GetPrimaryKeyViaIndex(&transaction2, 754 s = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
143 high_database_id, 755 high_database_id,
144 high_object_store_id, 756 high_object_store_id,
145 high_index_id, 757 high_index_id,
146 index_key, 758 index_key,
147 &new_primary_key); 759 &new_primary_key);
148 EXPECT_TRUE(s.ok()); 760 EXPECT_TRUE(s.ok());
149 EXPECT_TRUE(new_primary_key->Equals(m_key1)); 761 EXPECT_TRUE(new_primary_key->Equals(m_key1));
150 762
151 s = transaction2.Commit(); 763 scoped_refptr<TestCallback> callback(new TestCallback());
764 s = transaction2.CommitPhaseOne(callback);
765 EXPECT_TRUE(s.ok());
766 EXPECT_TRUE(callback->called);
767 EXPECT_TRUE(callback->succeeded);
768 s = transaction2.CommitPhaseTwo();
152 EXPECT_TRUE(s.ok()); 769 EXPECT_TRUE(s.ok());
153 } 770 }
154 } 771 }
155 772
156 // Make sure that other invalid ids do not crash. 773 // Make sure that other invalid ids do not crash.
157 TEST_F(IndexedDBBackingStoreTest, InvalidIds) { 774 TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
158 // valid ids for use when testing invalid ids 775 // valid ids for use when testing invalid ids
159 const int64 database_id = 1; 776 const int64 database_id = 1;
160 const int64 object_store_id = 1; 777 const int64 object_store_id = 1;
161 const int64 index_id = kMinimumIndexId; 778 const int64 index_id = kMinimumIndexId;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 s = backing_store_->CreateIndex(&transaction, 897 s = backing_store_->CreateIndex(&transaction,
281 database_id, 898 database_id,
282 object_store_id, 899 object_store_id,
283 index_id, 900 index_id,
284 index_name, 901 index_name,
285 index_key_path, 902 index_key_path,
286 unique, 903 unique,
287 multi_entry); 904 multi_entry);
288 EXPECT_TRUE(s.ok()); 905 EXPECT_TRUE(s.ok());
289 906
290 s = transaction.Commit(); 907 scoped_refptr<TestCallback> callback(new TestCallback());
908 s = transaction.CommitPhaseOne(callback);
909 EXPECT_TRUE(s.ok());
910 EXPECT_TRUE(callback->called);
911 EXPECT_TRUE(callback->succeeded);
912 s = transaction.CommitPhaseTwo();
291 EXPECT_TRUE(s.ok()); 913 EXPECT_TRUE(s.ok());
292 } 914 }
293 915
294 { 916 {
295 IndexedDBDatabaseMetadata database; 917 IndexedDBDatabaseMetadata database;
296 bool found; 918 bool found;
297 leveldb::Status s = backing_store_->GetIDBDatabaseMetaData( 919 leveldb::Status s = backing_store_->GetIDBDatabaseMetaData(
298 database_name, &database, &found); 920 database_name, &database, &found);
299 EXPECT_TRUE(s.ok()); 921 EXPECT_TRUE(s.ok());
300 EXPECT_TRUE(found); 922 EXPECT_TRUE(found);
(...skipping 18 matching lines...) Expand all
319 EXPECT_EQ(index_name, index.name); 941 EXPECT_EQ(index_name, index.name);
320 EXPECT_EQ(index_key_path, index.key_path); 942 EXPECT_EQ(index_key_path, index.key_path);
321 EXPECT_EQ(unique, index.unique); 943 EXPECT_EQ(unique, index.unique);
322 EXPECT_EQ(multi_entry, index.multi_entry); 944 EXPECT_EQ(multi_entry, index.multi_entry);
323 } 945 }
324 } 946 }
325 947
326 } // namespace 948 } // namespace
327 949
328 } // namespace content 950 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_backing_store.cc ('k') | content/browser/indexed_db/indexed_db_context_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698