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

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

Issue 2930183002: Let IndexedDBContextImpl create its own task runner (Closed)
Patch Set: Actually compile Created 3 years, 5 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
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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h" 13 #include "base/files/scoped_temp_dir.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/sequenced_task_runner.h" 17 #include "base/sequenced_task_runner.h"
18 #include "base/strings/string16.h" 18 #include "base/strings/string16.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/test/test_simple_task_runner.h"
21 #include "content/browser/indexed_db/indexed_db_context_impl.h" 20 #include "content/browser/indexed_db/indexed_db_context_impl.h"
22 #include "content/browser/indexed_db/indexed_db_factory_impl.h" 21 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
23 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 22 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
24 #include "content/browser/indexed_db/indexed_db_value.h" 23 #include "content/browser/indexed_db/indexed_db_value.h"
25 #include "content/browser/indexed_db/leveldb/leveldb_factory.h" 24 #include "content/browser/indexed_db/leveldb/leveldb_factory.h"
26 #include "content/public/test/test_browser_thread_bundle.h" 25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/public/test/test_utils.h"
27 #include "net/url_request/url_request_test_util.h" 27 #include "net/url_request/url_request_test_util.h"
28 #include "storage/browser/blob/blob_data_handle.h" 28 #include "storage/browser/blob/blob_data_handle.h"
29 #include "storage/browser/quota/special_storage_policy.h" 29 #include "storage/browser/quota/special_storage_policy.h"
30 #include "storage/browser/test/mock_quota_manager_proxy.h" 30 #include "storage/browser/test/mock_quota_manager_proxy.h"
31 #include "storage/browser/test/mock_special_storage_policy.h" 31 #include "storage/browser/test/mock_special_storage_policy.h"
32 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" 33 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
34 34
35 using base::ASCIIToUTF16; 35 using base::ASCIIToUTF16;
36 using url::Origin; 36 using url::Origin;
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 this, origin, data_directory, request_context_getter, &leveldb_factory, 225 this, origin, data_directory, request_context_getter, &leveldb_factory,
226 context()->TaskRunner(), status); 226 context()->TaskRunner(), status);
227 } 227 }
228 228
229 private: 229 private:
230 DISALLOW_COPY_AND_ASSIGN(TestIDBFactory); 230 DISALLOW_COPY_AND_ASSIGN(TestIDBFactory);
231 }; 231 };
232 232
233 class IndexedDBBackingStoreTest : public testing::Test { 233 class IndexedDBBackingStoreTest : public testing::Test {
234 public: 234 public:
235 IndexedDBBackingStoreTest() {} 235 IndexedDBBackingStoreTest()
236 : url_request_context_getter_(
237 base::MakeRefCounted<net::TestURLRequestContextGetter>(
238 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))),
239 special_storage_policy_(
240 base::MakeRefCounted<MockSpecialStoragePolicy>()),
241 quota_manager_proxy_(
242 base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {}
243
236 void SetUp() override { 244 void SetUp() override {
237 const Origin origin(GURL("http://localhost:81"));
238 task_runner_ = new base::TestSimpleTaskRunner();
239 url_request_context_getter_ =
240 new net::TestURLRequestContextGetter(task_runner_);
241 special_storage_policy_ = new MockSpecialStoragePolicy();
242 quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr);
243 special_storage_policy_->SetAllUnlimited(true); 245 special_storage_policy_->SetAllUnlimited(true);
244 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 246 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
245 idb_context_ = new IndexedDBContextImpl( 247 idb_context_ = base::MakeRefCounted<IndexedDBContextImpl>(
246 temp_dir_.GetPath(), special_storage_policy_.get(), 248 temp_dir_.GetPath(), special_storage_policy_, quota_manager_proxy_);
247 quota_manager_proxy_.get(), task_runner_.get()); 249
248 idb_factory_ = new TestIDBFactory(idb_context_.get()); 250 // Factory and backing store must be created on IDB task runner.
249 backing_store_ = idb_factory_->OpenBackingStoreForTest( 251 idb_context_->TaskRunner()->PostTask(
250 origin, url_request_context_getter_); 252 FROM_HERE, base::BindOnce(
253 [](IndexedDBBackingStoreTest* test) {
254 const Origin origin(GURL("http://localhost:81"));
255 test->idb_factory_ =
256 base::MakeRefCounted<TestIDBFactory>(
257 test->idb_context_.get());
258 test->backing_store_ =
259 test->idb_factory_->OpenBackingStoreForTest(
260 origin, test->url_request_context_getter_);
261 },
262 base::Unretained(this)));
263 RunAllBlockingPoolTasksUntilIdle();
251 264
252 // useful keys and values during tests 265 // useful keys and values during tests
253 value1_ = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>()); 266 value1_ = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>());
254 value2_ = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>()); 267 value2_ = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>());
255 268
269 key1_ = IndexedDBKey(99, blink::kWebIDBKeyTypeNumber);
270 key2_ = IndexedDBKey(ASCIIToUTF16("key2"));
271 }
272
273 void TearDown() override {
274 // Factory and backing store must be destroyed on IDB task runner.
275 idb_context_->TaskRunner()->PostTask(
276 FROM_HERE, base::BindOnce(
277 [](IndexedDBBackingStoreTest* test) {
278 test->idb_factory_ = nullptr;
279 test->backing_store_ = nullptr;
280 },
281 base::Unretained(this)));
282 RunAllBlockingPoolTasksUntilIdle();
283
284 quota_manager_proxy_->SimulateQuotaManagerDestroyed();
285 }
286
287 TestableIndexedDBBackingStore* backing_store() const {
288 return backing_store_.get();
289 }
290
291 // Sample keys and values that are consistent. Public so that posted lambdas
292 // passed |this| can access them.
293 IndexedDBKey key1_;
294 IndexedDBKey key2_;
295 IndexedDBValue value1_;
296 IndexedDBValue value2_;
297
298 protected:
299 // Must be initialized before url_request_context_getter_
300 TestBrowserThreadBundle thread_bundle_;
301
302 base::ScopedTempDir temp_dir_;
303 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
304 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
305 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
306 scoped_refptr<IndexedDBContextImpl> idb_context_;
307 scoped_refptr<TestIDBFactory> idb_factory_;
308
309 scoped_refptr<TestableIndexedDBBackingStore> backing_store_;
310
311 private:
312 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
313 };
314
315 class IndexedDBBackingStoreTestWithBlobs : public IndexedDBBackingStoreTest {
316 public:
317 IndexedDBBackingStoreTestWithBlobs() {}
318
319 void SetUp() override {
320 IndexedDBBackingStoreTest::SetUp();
321
322 // useful keys and values during tests
256 blob_info_.push_back( 323 blob_info_.push_back(
257 IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("blob type"), 1)); 324 IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("blob type"), 1));
258 blob_info_.push_back(IndexedDBBlobInfo( 325 blob_info_.push_back(IndexedDBBlobInfo(
259 "uuid 4", base::FilePath(FILE_PATH_LITERAL("path/to/file")), 326 "uuid 4", base::FilePath(FILE_PATH_LITERAL("path/to/file")),
260 base::UTF8ToUTF16("file name"), base::UTF8ToUTF16("file type"))); 327 base::UTF8ToUTF16("file name"), base::UTF8ToUTF16("file type")));
261 blob_info_.push_back(IndexedDBBlobInfo("uuid 5", base::FilePath(), 328 blob_info_.push_back(IndexedDBBlobInfo("uuid 5", base::FilePath(),
262 base::UTF8ToUTF16("file name"), 329 base::UTF8ToUTF16("file name"),
263 base::UTF8ToUTF16("file type"))); 330 base::UTF8ToUTF16("file type")));
264 value3_ = IndexedDBValue("value3", blob_info_); 331 value3_ = IndexedDBValue("value3", blob_info_);
265 332
266 key1_ = IndexedDBKey(99, blink::kWebIDBKeyTypeNumber);
267 key2_ = IndexedDBKey(ASCIIToUTF16("key2"));
268 key3_ = IndexedDBKey(ASCIIToUTF16("key3")); 333 key3_ = IndexedDBKey(ASCIIToUTF16("key3"));
269 } 334 }
270 335
271 void TearDown() override {
272 quota_manager_proxy_->SimulateQuotaManagerDestroyed();
273 }
274
275 // This just checks the data that survive getting stored and recalled, e.g. 336 // This just checks the data that survive getting stored and recalled, e.g.
276 // the file path and UUID will change and thus aren't verified. 337 // the file path and UUID will change and thus aren't verified.
277 bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const { 338 bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const {
339 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
340
278 if (blob_info_.size() != reads.size()) 341 if (blob_info_.size() != reads.size())
279 return false; 342 return false;
280 for (size_t i = 0; i < blob_info_.size(); ++i) { 343 for (size_t i = 0; i < blob_info_.size(); ++i) {
281 const IndexedDBBlobInfo& a = blob_info_[i]; 344 const IndexedDBBlobInfo& a = blob_info_[i];
282 const IndexedDBBlobInfo& b = reads[i]; 345 const IndexedDBBlobInfo& b = reads[i];
283 if (a.is_file() != b.is_file()) 346 if (a.is_file() != b.is_file())
284 return false; 347 return false;
285 if (a.type() != b.type()) 348 if (a.type() != b.type())
286 return false; 349 return false;
287 if (a.is_file()) { 350 if (a.is_file()) {
288 if (a.file_name() != b.file_name()) 351 if (a.file_name() != b.file_name())
289 return false; 352 return false;
290 } else { 353 } else {
291 if (a.size() != b.size()) 354 if (a.size() != b.size())
292 return false; 355 return false;
293 } 356 }
294 } 357 }
295 return true; 358 return true;
296 } 359 }
297 360
298 bool CheckBlobReadsMatchWrites( 361 bool CheckBlobReadsMatchWrites(
299 const std::vector<IndexedDBBlobInfo>& reads) const { 362 const std::vector<IndexedDBBlobInfo>& reads) const {
363 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
364
300 if (backing_store_->writes().size() != reads.size()) 365 if (backing_store_->writes().size() != reads.size())
301 return false; 366 return false;
302 std::set<int64_t> ids; 367 std::set<int64_t> ids;
303 for (const auto& write : backing_store_->writes()) 368 for (const auto& write : backing_store_->writes())
304 ids.insert(write.key()); 369 ids.insert(write.key());
305 if (ids.size() != backing_store_->writes().size()) 370 if (ids.size() != backing_store_->writes().size())
306 return false; 371 return false;
307 for (const auto& read : reads) { 372 for (const auto& read : reads) {
308 if (ids.count(read.key()) != 1) 373 if (ids.count(read.key()) != 1)
309 return false; 374 return false;
310 } 375 }
311 return true; 376 return true;
312 } 377 }
313 378
314 bool CheckBlobWrites() const { 379 bool CheckBlobWrites() const {
380 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
381
315 if (backing_store_->writes().size() != blob_info_.size()) 382 if (backing_store_->writes().size() != blob_info_.size())
316 return false; 383 return false;
317 for (size_t i = 0; i < backing_store_->writes().size(); ++i) { 384 for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
318 const IndexedDBBackingStore::Transaction::WriteDescriptor& desc = 385 const IndexedDBBackingStore::Transaction::WriteDescriptor& desc =
319 backing_store_->writes()[i]; 386 backing_store_->writes()[i];
320 const IndexedDBBlobInfo& info = blob_info_[i]; 387 const IndexedDBBlobInfo& info = blob_info_[i];
321 if (desc.is_file() != info.is_file()) { 388 if (desc.is_file() != info.is_file()) {
322 if (!info.is_file() || !info.file_path().empty()) 389 if (!info.is_file() || !info.file_path().empty())
323 return false; 390 return false;
324 } else if (desc.is_file()) { 391 } else if (desc.is_file()) {
325 if (desc.file_path() != info.file_path()) 392 if (desc.file_path() != info.file_path())
326 return false; 393 return false;
327 } else { 394 } else {
328 if (desc.url() != GURL("blob:uuid/" + info.uuid())) 395 if (desc.url() != GURL("blob:uuid/" + info.uuid()))
329 return false; 396 return false;
330 } 397 }
331 } 398 }
332 return true; 399 return true;
333 } 400 }
334 401
335 bool CheckBlobRemovals() const { 402 bool CheckBlobRemovals() const {
403 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
404
336 if (backing_store_->removals().size() != backing_store_->writes().size()) 405 if (backing_store_->removals().size() != backing_store_->writes().size())
337 return false; 406 return false;
338 for (size_t i = 0; i < backing_store_->writes().size(); ++i) { 407 for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
339 if (backing_store_->writes()[i].key() != backing_store_->removals()[i]) 408 if (backing_store_->writes()[i].key() != backing_store_->removals()[i])
340 return false; 409 return false;
341 } 410 }
342 return true; 411 return true;
343 } 412 }
344 413
345 protected: 414 // Sample keys and values that are consistent. Public so that posted lambdas
346 // Must be initialized before url_request_context_getter_ 415 // passed |this| can access them.
347 TestBrowserThreadBundle thread_bundle_; 416 IndexedDBKey key3_;
417 IndexedDBValue value3_;
348 418
349 base::ScopedTempDir temp_dir_; 419 private:
350 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 420 // Blob details referenced by |value3_|. The various CheckBlob*() methods
351 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_; 421 // can be used to verify the state as a test progresses.
352 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
353 scoped_refptr<IndexedDBContextImpl> idb_context_;
354 scoped_refptr<TestIDBFactory> idb_factory_;
355 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
356
357 scoped_refptr<TestableIndexedDBBackingStore> backing_store_;
358
359 // Sample keys and values that are consistent.
360 IndexedDBKey key1_;
361 IndexedDBKey key2_;
362 IndexedDBKey key3_;
363 IndexedDBValue value1_;
364 IndexedDBValue value2_;
365 IndexedDBValue value3_;
366 std::vector<IndexedDBBlobInfo> blob_info_; 422 std::vector<IndexedDBBlobInfo> blob_info_;
367 423
368 private: 424 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTestWithBlobs);
369 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
370 }; 425 };
371 426
372 class TestCallback : public IndexedDBBackingStore::BlobWriteCallback { 427 class TestCallback : public IndexedDBBackingStore::BlobWriteCallback {
373 public: 428 public:
374 TestCallback() : called(false), succeeded(false) {} 429 TestCallback() : called(false), succeeded(false) {}
375 leveldb::Status Run(IndexedDBBackingStore::BlobWriteResult result) override { 430 leveldb::Status Run(IndexedDBBackingStore::BlobWriteResult result) override {
376 called = true; 431 called = true;
377 switch (result) { 432 switch (result) {
378 case IndexedDBBackingStore::BlobWriteResult::FAILURE_ASYNC: 433 case IndexedDBBackingStore::BlobWriteResult::FAILURE_ASYNC:
379 succeeded = false; 434 succeeded = false;
380 break; 435 break;
381 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC: 436 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC:
382 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_SYNC: 437 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_SYNC:
383 succeeded = true; 438 succeeded = true;
384 break; 439 break;
385 } 440 }
386 return leveldb::Status::OK(); 441 return leveldb::Status::OK();
387 } 442 }
388 bool called; 443 bool called;
389 bool succeeded; 444 bool succeeded;
390 445
391 protected: 446 protected:
392 ~TestCallback() override {} 447 ~TestCallback() override {}
393 448
394 private: 449 private:
395 DISALLOW_COPY_AND_ASSIGN(TestCallback); 450 DISALLOW_COPY_AND_ASSIGN(TestCallback);
396 }; 451 };
397 452
398 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { 453 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
399 { 454 idb_context_->TaskRunner()->PostTask(
400 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); 455 FROM_HERE,
401 transaction1.Begin(); 456 base::BindOnce(
402 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 457 [](IndexedDBBackingStore* backing_store, IndexedDBKey key,
403 IndexedDBBackingStore::RecordIdentifier record; 458 IndexedDBValue value) {
404 leveldb::Status s = backing_store_->PutRecord(&transaction1, 1, 1, key1_, 459 {
405 &value1_, &handles, &record); 460 IndexedDBBackingStore::Transaction transaction1(backing_store);
406 EXPECT_TRUE(s.ok()); 461 transaction1.Begin();
407 scoped_refptr<TestCallback> callback(new TestCallback()); 462 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
408 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); 463 IndexedDBBackingStore::RecordIdentifier record;
409 EXPECT_TRUE(callback->called); 464 leveldb::Status s = backing_store->PutRecord(
410 EXPECT_TRUE(callback->succeeded); 465 &transaction1, 1, 1, key, &value, &handles, &record);
411 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); 466 EXPECT_TRUE(s.ok());
467 scoped_refptr<TestCallback> callback(
468 base::MakeRefCounted<TestCallback>());
469 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
470 EXPECT_TRUE(callback->called);
471 EXPECT_TRUE(callback->succeeded);
472 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
473 }
474
475 {
476 IndexedDBBackingStore::Transaction transaction2(backing_store);
477 transaction2.Begin();
478 IndexedDBValue result_value;
479 EXPECT_TRUE(
480 backing_store
481 ->GetRecord(&transaction2, 1, 1, key, &result_value)
482 .ok());
483 scoped_refptr<TestCallback> callback(
484 base::MakeRefCounted<TestCallback>());
485 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
486 EXPECT_TRUE(callback->called);
487 EXPECT_TRUE(callback->succeeded);
488 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
489 EXPECT_EQ(value.bits, result_value.bits);
490 }
491 },
492 base::Unretained(backing_store()), key1_, value1_));
493 RunAllBlockingPoolTasksUntilIdle();
494 }
495
496 TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
497 struct TestState {
dmurph 2017/07/07 18:28:59 I like this approach.
498 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
499 scoped_refptr<TestCallback> callback1;
500 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3;
501 scoped_refptr<TestCallback> callback3;
502 } state;
503
504 idb_context_->TaskRunner()->PostTask(
505 FROM_HERE,
506 base::BindOnce(
507 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
508 // Initiate transaction1 - writing blobs.
509 state->transaction1 =
510 base::MakeUnique<IndexedDBBackingStore::Transaction>(
511 test->backing_store());
512 state->transaction1->Begin();
513 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
514 IndexedDBBackingStore::RecordIdentifier record;
515 EXPECT_TRUE(test->backing_store()
516 ->PutRecord(state->transaction1.get(), 1, 1,
517 test->key3_, &test->value3_, &handles,
518 &record)
519 .ok());
520 state->callback1 = base::MakeRefCounted<TestCallback>();
521 EXPECT_TRUE(
522 state->transaction1->CommitPhaseOne(state->callback1).ok());
523 },
524 base::Unretained(this), base::Unretained(&state)));
525 RunAllBlockingPoolTasksUntilIdle();
526
527 idb_context_->TaskRunner()->PostTask(
528 FROM_HERE,
529 base::BindOnce(
530 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
531 // Finish up transaction1, verifying blob writes.
532 EXPECT_TRUE(state->callback1->called);
533 EXPECT_TRUE(state->callback1->succeeded);
534 EXPECT_TRUE(test->CheckBlobWrites());
535 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
536
537 // Initiate transaction2, reading blobs.
538 IndexedDBBackingStore::Transaction transaction2(
539 test->backing_store());
540 transaction2.Begin();
541 IndexedDBValue result_value;
542 EXPECT_TRUE(
543 test->backing_store()
544 ->GetRecord(&transaction2, 1, 1, test->key3_, &result_value)
545 .ok());
546
547 // Finish up transaction2, verifying blob reads.
548 scoped_refptr<TestCallback> callback(
549 base::MakeRefCounted<TestCallback>());
550 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
551 EXPECT_TRUE(callback->called);
552 EXPECT_TRUE(callback->succeeded);
553 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
554 EXPECT_EQ(test->value3_.bits, result_value.bits);
555 EXPECT_TRUE(test->CheckBlobInfoMatches(result_value.blob_info));
556 EXPECT_TRUE(
557 test->CheckBlobReadsMatchWrites(result_value.blob_info));
558
559 // Initiate transaction3, deleting blobs.
560 state->transaction3 =
561 base::MakeUnique<IndexedDBBackingStore::Transaction>(
562 test->backing_store());
563 state->transaction3->Begin();
564 EXPECT_TRUE(test->backing_store()
565 ->DeleteRange(state->transaction3.get(), 1, 1,
566 IndexedDBKeyRange(test->key3_))
567 .ok());
568 state->callback3 = base::MakeRefCounted<TestCallback>();
569 EXPECT_TRUE(
570 state->transaction3->CommitPhaseOne(state->callback3).ok());
571
572 },
573 base::Unretained(this), base::Unretained(&state)));
574 RunAllBlockingPoolTasksUntilIdle();
575
576 idb_context_->TaskRunner()->PostTask(
577 FROM_HERE,
578 base::BindOnce(
579 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
580 // Finish up transaction 3, verifying blob deletes.
581 EXPECT_TRUE(state->transaction3->CommitPhaseTwo().ok());
582 EXPECT_TRUE(test->CheckBlobRemovals());
583 },
584 base::Unretained(this), base::Unretained(&state)));
585 RunAllBlockingPoolTasksUntilIdle();
586 }
587
588 TEST_F(IndexedDBBackingStoreTest, DeleteRange) {
589 const std::vector<IndexedDBKey> keys = {
590 IndexedDBKey(ASCIIToUTF16("key0")), IndexedDBKey(ASCIIToUTF16("key1")),
591 IndexedDBKey(ASCIIToUTF16("key2")), IndexedDBKey(ASCIIToUTF16("key3"))};
592 const IndexedDBKeyRange ranges[] = {
593 IndexedDBKeyRange(keys[1], keys[2], false, false),
594 IndexedDBKeyRange(keys[1], keys[2], false, false),
595 IndexedDBKeyRange(keys[0], keys[2], true, false),
596 IndexedDBKeyRange(keys[1], keys[3], false, true),
597 IndexedDBKeyRange(keys[0], keys[3], true, true)};
598
599 for (size_t i = 0; i < arraysize(ranges); ++i) {
600 const int64_t database_id = 1;
601 const int64_t object_store_id = i + 1;
602 const IndexedDBKeyRange& range = ranges[i];
603
604 struct TestState {
605 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
606 scoped_refptr<TestCallback> callback1;
607 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2;
608 scoped_refptr<TestCallback> callback2;
609 } state;
610
611 idb_context_->TaskRunner()->PostTask(
612 FROM_HERE,
613 base::BindOnce(
614 [](TestableIndexedDBBackingStore* backing_store, TestState* state,
615 const std::vector<IndexedDBKey>& keys, int64_t database_id,
616 int64_t object_store_id) {
617 // Reset from previous iteration.
618 backing_store->ClearWrites();
619 backing_store->ClearRemovals();
620
621 std::vector<IndexedDBValue> values = {
622 IndexedDBValue(
623 "value0", {IndexedDBBlobInfo(
624 "uuid 0", base::UTF8ToUTF16("type 0"), 1)}),
625 IndexedDBValue(
626 "value1", {IndexedDBBlobInfo(
627 "uuid 1", base::UTF8ToUTF16("type 1"), 1)}),
628 IndexedDBValue(
629 "value2", {IndexedDBBlobInfo(
630 "uuid 2", base::UTF8ToUTF16("type 2"), 1)}),
631 IndexedDBValue(
632 "value3",
633 {IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("type 3"),
634 1)})};
635 ASSERT_GE(keys.size(), values.size());
636
637 // Initiate transaction1 - write records.
638 state->transaction1 =
639 base::MakeUnique<IndexedDBBackingStore::Transaction>(
640 backing_store);
641 state->transaction1->Begin();
642 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
643 IndexedDBBackingStore::RecordIdentifier record;
644 for (size_t i = 0; i < values.size(); ++i) {
645 EXPECT_TRUE(backing_store
646 ->PutRecord(state->transaction1.get(),
647 database_id, object_store_id,
648 keys[i], &values[i], &handles,
649 &record)
650 .ok());
651 }
652
653 // Start committing transaction1.
654 state->callback1 = base::MakeRefCounted<TestCallback>();
655 EXPECT_TRUE(
656 state->transaction1->CommitPhaseOne(state->callback1).ok());
657 },
658 base::Unretained(backing_store()), base::Unretained(&state),
659 base::ConstRef(keys), database_id, object_store_id));
660 RunAllBlockingPoolTasksUntilIdle();
661
662 idb_context_->TaskRunner()->PostTask(
663 FROM_HERE,
664 base::BindOnce(
665 [](TestableIndexedDBBackingStore* backing_store, TestState* state,
666 IndexedDBKeyRange range, int64_t database_id,
667 int64_t object_store_id) {
668 // Finish committing transaction1.
669 EXPECT_TRUE(state->callback1->called);
670 EXPECT_TRUE(state->callback1->succeeded);
671 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
672
673 // Initiate transaction 2 - delete range.
674 state->transaction2 =
675 base::MakeUnique<IndexedDBBackingStore::Transaction>(
676 backing_store);
677 state->transaction2->Begin();
678 IndexedDBValue result_value;
679 EXPECT_TRUE(backing_store
680 ->DeleteRange(state->transaction2.get(),
681 database_id, object_store_id, range)
682 .ok());
683
684 // Start committing transaction2.
685 state->callback2 = base::MakeRefCounted<TestCallback>();
686 EXPECT_TRUE(
687 state->transaction2->CommitPhaseOne(state->callback2).ok());
688 },
689 base::Unretained(backing_store()), base::Unretained(&state), range,
690 database_id, object_store_id));
691 RunAllBlockingPoolTasksUntilIdle();
692
693 idb_context_->TaskRunner()->PostTask(
694 FROM_HERE,
695 base::BindOnce(
696 [](TestableIndexedDBBackingStore* backing_store, TestState* state) {
697 // Finish committing transaction2.
698 EXPECT_TRUE(state->callback2->called);
699 EXPECT_TRUE(state->callback2->succeeded);
700 EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok());
701
702 // Verify blob removals.
703 ASSERT_EQ(2UL, backing_store->removals().size());
704 EXPECT_EQ(backing_store->writes()[1].key(),
705 backing_store->removals()[0]);
706 EXPECT_EQ(backing_store->writes()[2].key(),
707 backing_store->removals()[1]);
708 },
709 base::Unretained(backing_store()), base::Unretained(&state)));
710 RunAllBlockingPoolTasksUntilIdle();
412 } 711 }
413 712 }
414 { 713
415 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); 714 TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) {
416 transaction2.Begin(); 715 const std::vector<IndexedDBKey> keys = {
417 IndexedDBValue result_value; 716 IndexedDBKey(ASCIIToUTF16("key0")), IndexedDBKey(ASCIIToUTF16("key1")),
418 EXPECT_TRUE( 717 IndexedDBKey(ASCIIToUTF16("key2")), IndexedDBKey(ASCIIToUTF16("key3")),
419 backing_store_->GetRecord(&transaction2, 1, 1, key1_, &result_value) 718 IndexedDBKey(ASCIIToUTF16("key4"))};
420 .ok()); 719 const IndexedDBKeyRange ranges[] = {
421 scoped_refptr<TestCallback> callback(new TestCallback()); 720 IndexedDBKeyRange(keys[3], keys[4], true, false),
422 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); 721 IndexedDBKeyRange(keys[2], keys[1], false, false),
423 EXPECT_TRUE(callback->called); 722 IndexedDBKeyRange(keys[2], keys[1], true, true)};
424 EXPECT_TRUE(callback->succeeded); 723
425 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); 724 for (size_t i = 0; i < arraysize(ranges); ++i) {
426 EXPECT_EQ(value1_.bits, result_value.bits); 725 const int64_t database_id = 1;
726 const int64_t object_store_id = i + 1;
727 const IndexedDBKeyRange& range = ranges[i];
728
729 struct TestState {
730 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
731 scoped_refptr<TestCallback> callback1;
732 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2;
733 scoped_refptr<TestCallback> callback2;
734 } state;
735
736 idb_context_->TaskRunner()->PostTask(
737 FROM_HERE,
738 base::BindOnce(
739 [](TestableIndexedDBBackingStore* backing_store, TestState* state,
740 const std::vector<IndexedDBKey>& keys, int64_t database_id,
741 int64_t object_store_id) {
742 // Reset from previous iteration.
743 backing_store->ClearWrites();
744 backing_store->ClearRemovals();
745
746 std::vector<IndexedDBValue> values = {
747 IndexedDBValue(
748 "value0", {IndexedDBBlobInfo(
749 "uuid 0", base::UTF8ToUTF16("type 0"), 1)}),
750 IndexedDBValue(
751 "value1", {IndexedDBBlobInfo(
752 "uuid 1", base::UTF8ToUTF16("type 1"), 1)}),
753 IndexedDBValue(
754 "value2", {IndexedDBBlobInfo(
755 "uuid 2", base::UTF8ToUTF16("type 2"), 1)}),
756 IndexedDBValue(
757 "value3",
758 {IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("type 3"),
759 1)})};
760 ASSERT_GE(keys.size(), values.size());
761
762 // Initiate transaction1 - write records.
763 state->transaction1 =
764 base::MakeUnique<IndexedDBBackingStore::Transaction>(
765 backing_store);
766 state->transaction1->Begin();
767
768 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
769 IndexedDBBackingStore::RecordIdentifier record;
770 for (size_t i = 0; i < values.size(); ++i) {
771 EXPECT_TRUE(backing_store
772 ->PutRecord(state->transaction1.get(),
773 database_id, object_store_id,
774 keys[i], &values[i], &handles,
775 &record)
776 .ok());
777 }
778 // Start committing transaction1.
779 state->callback1 = base::MakeRefCounted<TestCallback>();
780 EXPECT_TRUE(
781 state->transaction1->CommitPhaseOne(state->callback1).ok());
782 },
783 base::Unretained(backing_store()), base::Unretained(&state),
784 base::ConstRef(keys), database_id, object_store_id));
785 RunAllBlockingPoolTasksUntilIdle();
786
787 idb_context_->TaskRunner()->PostTask(
788 FROM_HERE,
789 base::BindOnce(
790 [](TestableIndexedDBBackingStore* backing_store, TestState* state,
791 IndexedDBKeyRange range, int64_t database_id,
792 int64_t object_store_id) {
793 // Finish committing transaction1.
794 EXPECT_TRUE(state->callback1->called);
795 EXPECT_TRUE(state->callback1->succeeded);
796 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
797
798 // Initiate transaction 2 - delete range.
799 state->transaction2 =
800 base::MakeUnique<IndexedDBBackingStore::Transaction>(
801 backing_store);
802 state->transaction2->Begin();
803 IndexedDBValue result_value;
804 EXPECT_TRUE(backing_store
805 ->DeleteRange(state->transaction2.get(),
806 database_id, object_store_id, range)
807 .ok());
808
809 // Start committing transaction2.
810 state->callback2 = base::MakeRefCounted<TestCallback>();
811 EXPECT_TRUE(
812 state->transaction2->CommitPhaseOne(state->callback2).ok());
813 },
814 base::Unretained(backing_store()), base::Unretained(&state), range,
815 database_id, object_store_id));
816 RunAllBlockingPoolTasksUntilIdle();
817
818 idb_context_->TaskRunner()->PostTask(
819 FROM_HERE,
820 base::BindOnce(
821 [](TestableIndexedDBBackingStore* backing_store, TestState* state) {
822 // Finish committing transaction2.
823 EXPECT_TRUE(state->callback2->called);
824 EXPECT_TRUE(state->callback2->succeeded);
825 EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok());
826
827 // Verify blob removals.
828 EXPECT_EQ(0UL, backing_store->removals().size());
829 },
830 base::Unretained(backing_store()), base::Unretained(&state)));
831 RunAllBlockingPoolTasksUntilIdle();
427 } 832 }
428 } 833 }
429 834
430 TEST_F(IndexedDBBackingStoreTest, PutGetConsistencyWithBlobs) { 835 TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) {
431 { 836 struct TestState {
432 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); 837 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
433 transaction1.Begin(); 838 scoped_refptr<TestCallback> callback1;
434 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 839 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2;
435 IndexedDBBackingStore::RecordIdentifier record; 840 scoped_refptr<TestCallback> callback2;
436 EXPECT_TRUE( 841 } state;
437 backing_store_ 842
438 ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles, &record) 843 idb_context_->TaskRunner()->PostTask(
439 .ok()); 844 FROM_HERE,
440 scoped_refptr<TestCallback> callback(new TestCallback()); 845 base::BindOnce(
441 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); 846 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
442 task_runner_->RunUntilIdle(); 847 // Initiate transaction1.
443 EXPECT_TRUE(CheckBlobWrites()); 848 state->transaction1 =
444 EXPECT_TRUE(callback->called); 849 base::MakeUnique<IndexedDBBackingStore::Transaction>(
445 EXPECT_TRUE(callback->succeeded); 850 test->backing_store());
446 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); 851 state->transaction1->Begin();
447 } 852 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1;
448 853 IndexedDBBackingStore::RecordIdentifier record1;
449 { 854 EXPECT_TRUE(test->backing_store()
450 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); 855 ->PutRecord(state->transaction1.get(), 1, 1,
451 transaction2.Begin(); 856 test->key3_, &test->value3_, &handles1,
452 IndexedDBValue result_value; 857 &record1)
453 EXPECT_TRUE( 858 .ok());
454 backing_store_->GetRecord(&transaction2, 1, 1, key3_, &result_value) 859 state->callback1 = base::MakeRefCounted<TestCallback>();
455 .ok()); 860 EXPECT_TRUE(
456 scoped_refptr<TestCallback> callback(new TestCallback()); 861 state->transaction1->CommitPhaseOne(state->callback1).ok());
457 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); 862 },
458 EXPECT_TRUE(callback->called); 863 base::Unretained(this), base::Unretained(&state)));
459 EXPECT_TRUE(callback->succeeded); 864 RunAllBlockingPoolTasksUntilIdle();
460 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); 865
461 EXPECT_EQ(value3_.bits, result_value.bits); 866 idb_context_->TaskRunner()->PostTask(
462 EXPECT_TRUE(CheckBlobInfoMatches(result_value.blob_info)); 867 FROM_HERE,
463 EXPECT_TRUE(CheckBlobReadsMatchWrites(result_value.blob_info)); 868 base::BindOnce(
464 } 869 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
465 870 // Verify transaction1 phase one completed.
466 { 871 EXPECT_TRUE(state->callback1->called);
467 IndexedDBBackingStore::Transaction transaction3(backing_store_.get()); 872 EXPECT_TRUE(state->callback1->succeeded);
468 transaction3.Begin(); 873 EXPECT_TRUE(test->CheckBlobWrites());
469 IndexedDBValue result_value; 874 EXPECT_EQ(0U, test->backing_store()->removals().size());
470 EXPECT_TRUE(backing_store_ 875
471 ->DeleteRange(&transaction3, 1, 1, IndexedDBKeyRange(key3_)) 876 // Initiate transaction2.
472 .ok()); 877 state->transaction2 =
473 scoped_refptr<TestCallback> callback(new TestCallback()); 878 base::MakeUnique<IndexedDBBackingStore::Transaction>(
474 EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok()); 879 test->backing_store());
475 task_runner_->RunUntilIdle(); 880 state->transaction2->Begin();
476 EXPECT_TRUE(callback->called); 881 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2;
477 EXPECT_TRUE(callback->succeeded); 882 IndexedDBBackingStore::RecordIdentifier record2;
478 EXPECT_TRUE(transaction3.CommitPhaseTwo().ok()); 883 EXPECT_TRUE(test->backing_store()
479 EXPECT_TRUE(CheckBlobRemovals()); 884 ->PutRecord(state->transaction2.get(), 1, 1,
480 } 885 test->key1_, &test->value1_, &handles2,
481 } 886 &record2)
482 887 .ok());
483 TEST_F(IndexedDBBackingStoreTest, DeleteRange) { 888 state->callback2 = base::MakeRefCounted<TestCallback>();
484 IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0")); 889 EXPECT_TRUE(
485 IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1")); 890 state->transaction2->CommitPhaseOne(state->callback2).ok());
486 IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2")); 891 },
487 IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3")); 892 base::Unretained(this), base::Unretained(&state)));
488 IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1); 893 RunAllBlockingPoolTasksUntilIdle();
489 IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1); 894
490 IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1); 895 idb_context_->TaskRunner()->PostTask(
491 IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1); 896 FROM_HERE,
492 IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key1, key2, false, false), 897 base::BindOnce(
493 IndexedDBKeyRange(key1, key2, false, false), 898 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
494 IndexedDBKeyRange(key0, key2, true, false), 899 // Verify transaction2 phase one completed.
495 IndexedDBKeyRange(key1, key3, false, true), 900 EXPECT_TRUE(state->callback2->called);
496 IndexedDBKeyRange(key0, key3, true, true)}; 901 EXPECT_TRUE(state->callback2->succeeded);
497 902 EXPECT_TRUE(test->CheckBlobWrites());
498 for (unsigned i = 0; i < sizeof(ranges) / sizeof(IndexedDBKeyRange); ++i) { 903 EXPECT_EQ(0U, test->backing_store()->removals().size());
499 backing_store_->ClearWrites(); 904
500 backing_store_->ClearRemovals(); 905 // Finalize both transactions.
501 906 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
502 { 907 EXPECT_EQ(0U, test->backing_store()->removals().size());
503 std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2, 908
504 blob_info3; 909 EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok());
505 blob_info0.push_back(blob0); 910 EXPECT_EQ(0U, test->backing_store()->removals().size());
506 blob_info1.push_back(blob1); 911 },
507 blob_info2.push_back(blob2); 912 base::Unretained(this), base::Unretained(&state)));
508 blob_info3.push_back(blob3); 913 RunAllBlockingPoolTasksUntilIdle();
509 IndexedDBValue value0 = IndexedDBValue("value0", blob_info0); 914 }
510 IndexedDBValue value1 = IndexedDBValue("value1", blob_info1); 915
511 IndexedDBValue value2 = IndexedDBValue("value2", blob_info2); 916 TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
512 IndexedDBValue value3 = IndexedDBValue("value3", blob_info3); 917 struct TestState {
513 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); 918 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
514 transaction1.Begin(); 919 scoped_refptr<TestCallback> callback1;
515 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 920 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3;
516 IndexedDBBackingStore::RecordIdentifier record; 921 scoped_refptr<TestCallback> callback3;
517 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, 922 IndexedDBValue read_result_value;
518 1, 923 } state;
519 i + 1, 924
520 key0, 925 idb_context_->TaskRunner()->PostTask(
521 &value0, 926 FROM_HERE,
522 &handles, 927 base::BindOnce(
523 &record).ok()); 928 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
524 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, 929 state->transaction1 =
525 1, 930 base::MakeUnique<IndexedDBBackingStore::Transaction>(
526 i + 1, 931 test->backing_store());
527 key1, 932 state->transaction1->Begin();
528 &value1, 933 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
529 &handles, 934 IndexedDBBackingStore::RecordIdentifier record;
530 &record).ok()); 935 EXPECT_TRUE(test->backing_store()
531 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, 936 ->PutRecord(state->transaction1.get(), 1, 1,
532 1, 937 test->key3_, &test->value3_, &handles,
533 i + 1, 938 &record)
534 key2, 939 .ok());
535 &value2, 940 state->callback1 = base::MakeRefCounted<TestCallback>();
536 &handles, 941 EXPECT_TRUE(
537 &record).ok()); 942 state->transaction1->CommitPhaseOne(state->callback1).ok());
538 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, 943 },
539 1, 944 base::Unretained(this), base::Unretained(&state)));
540 i + 1, 945 RunAllBlockingPoolTasksUntilIdle();
541 key3, 946
542 &value3, 947 idb_context_->TaskRunner()->PostTask(
543 &handles, 948 FROM_HERE,
544 &record).ok()); 949 base::BindOnce(
545 scoped_refptr<TestCallback> callback(new TestCallback()); 950 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
546 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); 951 EXPECT_TRUE(state->callback1->called);
547 task_runner_->RunUntilIdle(); 952 EXPECT_TRUE(state->callback1->succeeded);
548 EXPECT_TRUE(callback->called); 953 EXPECT_TRUE(test->CheckBlobWrites());
549 EXPECT_TRUE(callback->succeeded); 954 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
550 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); 955
551 } 956 IndexedDBBackingStore::Transaction transaction2(
552 957 test->backing_store());
553 { 958 transaction2.Begin();
554 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); 959 EXPECT_TRUE(test->backing_store()
555 transaction2.Begin(); 960 ->GetRecord(&transaction2, 1, 1, test->key3_,
556 IndexedDBValue result_value; 961 &state->read_result_value)
557 EXPECT_TRUE( 962 .ok());
558 backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok()); 963 scoped_refptr<TestCallback> callback(
559 scoped_refptr<TestCallback> callback(new TestCallback()); 964 base::MakeRefCounted<TestCallback>());
560 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); 965 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
561 task_runner_->RunUntilIdle(); 966 EXPECT_TRUE(callback->called);
562 EXPECT_TRUE(callback->called); 967 EXPECT_TRUE(callback->succeeded);
563 EXPECT_TRUE(callback->succeeded); 968 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
564 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); 969 EXPECT_EQ(test->value3_.bits, state->read_result_value.bits);
565 ASSERT_EQ(2UL, backing_store_->removals().size()); 970 EXPECT_TRUE(
566 EXPECT_EQ(backing_store_->writes()[1].key(), 971 test->CheckBlobInfoMatches(state->read_result_value.blob_info));
567 backing_store_->removals()[0]); 972 EXPECT_TRUE(test->CheckBlobReadsMatchWrites(
568 EXPECT_EQ(backing_store_->writes()[2].key(), 973 state->read_result_value.blob_info));
569 backing_store_->removals()[1]); 974 for (size_t i = 0; i < state->read_result_value.blob_info.size();
570 } 975 ++i) {
571 } 976 state->read_result_value.blob_info[i].mark_used_callback().Run();
572 } 977 }
573 978
574 TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) { 979 state->transaction3 =
575 IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0")); 980 base::MakeUnique<IndexedDBBackingStore::Transaction>(
576 IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1")); 981 test->backing_store());
577 IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2")); 982 state->transaction3->Begin();
578 IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3")); 983 EXPECT_TRUE(test->backing_store()
579 IndexedDBKey key4 = IndexedDBKey(ASCIIToUTF16("key4")); 984 ->DeleteRange(state->transaction3.get(), 1, 1,
580 IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1); 985 IndexedDBKeyRange(test->key3_))
581 IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1); 986 .ok());
582 IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1); 987 state->callback3 = base::MakeRefCounted<TestCallback>();
583 IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1); 988 EXPECT_TRUE(
584 IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key3, key4, true, false), 989 state->transaction3->CommitPhaseOne(state->callback3).ok());
585 IndexedDBKeyRange(key2, key1, false, false), 990 },
586 IndexedDBKeyRange(key2, key1, true, true)}; 991 base::Unretained(this), base::Unretained(&state)));
587 992 RunAllBlockingPoolTasksUntilIdle();
588 for (unsigned i = 0; i < arraysize(ranges); ++i) { 993
589 backing_store_->ClearWrites(); 994 idb_context_->TaskRunner()->PostTask(
590 backing_store_->ClearRemovals(); 995 FROM_HERE,
591 996 base::BindOnce(
592 { 997 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
593 std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2, 998 EXPECT_TRUE(state->callback3->called);
594 blob_info3; 999 EXPECT_TRUE(state->callback3->succeeded);
595 blob_info0.push_back(blob0); 1000 EXPECT_TRUE(state->transaction3->CommitPhaseTwo().ok());
596 blob_info1.push_back(blob1); 1001 EXPECT_EQ(0U, test->backing_store()->removals().size());
597 blob_info2.push_back(blob2); 1002 for (size_t i = 0; i < state->read_result_value.blob_info.size();
598 blob_info3.push_back(blob3); 1003 ++i) {
599 IndexedDBValue value0 = IndexedDBValue("value0", blob_info0); 1004 state->read_result_value.blob_info[i].release_callback().Run(
600 IndexedDBValue value1 = IndexedDBValue("value1", blob_info1); 1005 state->read_result_value.blob_info[i].file_path());
601 IndexedDBValue value2 = IndexedDBValue("value2", blob_info2); 1006 }
602 IndexedDBValue value3 = IndexedDBValue("value3", blob_info3); 1007 },
603 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); 1008 base::Unretained(this), base::Unretained(&state)));
604 transaction1.Begin(); 1009 RunAllBlockingPoolTasksUntilIdle();
605 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 1010
606 IndexedDBBackingStore::RecordIdentifier record; 1011 idb_context_->TaskRunner()->PostTask(
607 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, 1012 FROM_HERE, base::BindOnce(
608 1, 1013 [](IndexedDBBackingStoreTestWithBlobs* test) {
609 i + 1, 1014 EXPECT_NE(0U, test->backing_store()->removals().size());
610 key0, 1015 EXPECT_TRUE(test->CheckBlobRemovals());
611 &value0, 1016 },
612 &handles, 1017 base::Unretained(this)));
613 &record).ok()); 1018 RunAllBlockingPoolTasksUntilIdle();
614 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
615 1,
616 i + 1,
617 key1,
618 &value1,
619 &handles,
620 &record).ok());
621 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
622 1,
623 i + 1,
624 key2,
625 &value2,
626 &handles,
627 &record).ok());
628 EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
629 1,
630 i + 1,
631 key3,
632 &value3,
633 &handles,
634 &record).ok());
635 scoped_refptr<TestCallback> callback(new TestCallback());
636 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
637 task_runner_->RunUntilIdle();
638 EXPECT_TRUE(callback->called);
639 EXPECT_TRUE(callback->succeeded);
640 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
641 }
642
643 {
644 IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
645 transaction2.Begin();
646 IndexedDBValue result_value;
647 EXPECT_TRUE(
648 backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok());
649 scoped_refptr<TestCallback> callback(new TestCallback());
650 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
651 task_runner_->RunUntilIdle();
652 EXPECT_TRUE(callback->called);
653 EXPECT_TRUE(callback->succeeded);
654 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
655 EXPECT_EQ(0UL, backing_store_->removals().size());
656 }
657 }
658 }
659
660 TEST_F(IndexedDBBackingStoreTest, BlobJournalInterleavedTransactions) {
661 IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
662 transaction1.Begin();
663 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1;
664 IndexedDBBackingStore::RecordIdentifier record1;
665 EXPECT_TRUE(
666 backing_store_
667 ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles1, &record1)
668 .ok());
669 scoped_refptr<TestCallback> callback1(new TestCallback());
670 EXPECT_TRUE(transaction1.CommitPhaseOne(callback1).ok());
671 task_runner_->RunUntilIdle();
672 EXPECT_TRUE(CheckBlobWrites());
673 EXPECT_TRUE(callback1->called);
674 EXPECT_TRUE(callback1->succeeded);
675 EXPECT_EQ(0U, backing_store_->removals().size());
676
677 IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
678 transaction2.Begin();
679 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2;
680 IndexedDBBackingStore::RecordIdentifier record2;
681 EXPECT_TRUE(
682 backing_store_
683 ->PutRecord(&transaction2, 1, 1, key1_, &value1_, &handles2, &record2)
684 .ok());
685 scoped_refptr<TestCallback> callback2(new TestCallback());
686 EXPECT_TRUE(transaction2.CommitPhaseOne(callback2).ok());
687 task_runner_->RunUntilIdle();
688 EXPECT_TRUE(CheckBlobWrites());
689 EXPECT_TRUE(callback2->called);
690 EXPECT_TRUE(callback2->succeeded);
691 EXPECT_EQ(0U, backing_store_->removals().size());
692
693 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
694 EXPECT_EQ(0U, backing_store_->removals().size());
695
696 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
697 EXPECT_EQ(0U, backing_store_->removals().size());
698 }
699
700 TEST_F(IndexedDBBackingStoreTest, LiveBlobJournal) {
701 {
702 IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
703 transaction1.Begin();
704 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
705 IndexedDBBackingStore::RecordIdentifier record;
706 EXPECT_TRUE(
707 backing_store_
708 ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles, &record)
709 .ok());
710 scoped_refptr<TestCallback> callback(new TestCallback());
711 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
712 task_runner_->RunUntilIdle();
713 EXPECT_TRUE(CheckBlobWrites());
714 EXPECT_TRUE(callback->called);
715 EXPECT_TRUE(callback->succeeded);
716 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
717 }
718
719 IndexedDBValue read_result_value;
720 {
721 IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
722 transaction2.Begin();
723 EXPECT_TRUE(backing_store_
724 ->GetRecord(&transaction2, 1, 1, key3_, &read_result_value)
725 .ok());
726 scoped_refptr<TestCallback> callback(new TestCallback());
727 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
728 EXPECT_TRUE(callback->called);
729 EXPECT_TRUE(callback->succeeded);
730 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
731 EXPECT_EQ(value3_.bits, read_result_value.bits);
732 EXPECT_TRUE(CheckBlobInfoMatches(read_result_value.blob_info));
733 EXPECT_TRUE(CheckBlobReadsMatchWrites(read_result_value.blob_info));
734 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
735 read_result_value.blob_info[i].mark_used_callback().Run();
736 }
737 }
738
739 {
740 IndexedDBBackingStore::Transaction transaction3(backing_store_.get());
741 transaction3.Begin();
742 EXPECT_TRUE(backing_store_
743 ->DeleteRange(&transaction3, 1, 1, IndexedDBKeyRange(key3_))
744 .ok());
745 scoped_refptr<TestCallback> callback(new TestCallback());
746 EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok());
747 task_runner_->RunUntilIdle();
748 EXPECT_TRUE(callback->called);
749 EXPECT_TRUE(callback->succeeded);
750 EXPECT_TRUE(transaction3.CommitPhaseTwo().ok());
751 EXPECT_EQ(0U, backing_store_->removals().size());
752 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
753 read_result_value.blob_info[i].release_callback().Run(
754 read_result_value.blob_info[i].file_path());
755 }
756 task_runner_->RunUntilIdle();
757 EXPECT_NE(0U, backing_store_->removals().size());
758 EXPECT_TRUE(CheckBlobRemovals());
759 }
760 } 1019 }
761 1020
762 // Make sure that using very high ( more than 32 bit ) values for database_id 1021 // Make sure that using very high ( more than 32 bit ) values for database_id
763 // and object_store_id still work. 1022 // and object_store_id still work.
764 TEST_F(IndexedDBBackingStoreTest, HighIds) { 1023 TEST_F(IndexedDBBackingStoreTest, HighIds) {
765 const int64_t high_database_id = 1ULL << 35; 1024 idb_context_->TaskRunner()->PostTask(
766 const int64_t high_object_store_id = 1ULL << 39; 1025 FROM_HERE,
767 // index_ids are capped at 32 bits for storage purposes. 1026 base::BindOnce(
768 const int64_t high_index_id = 1ULL << 29; 1027 [](IndexedDBBackingStore* backing_store, IndexedDBKey key1,
769 1028 IndexedDBKey key2, IndexedDBValue value1) {
770 const int64_t invalid_high_index_id = 1ULL << 37; 1029 const int64_t high_database_id = 1ULL << 35;
771 1030 const int64_t high_object_store_id = 1ULL << 39;
772 const IndexedDBKey& index_key = key2_; 1031 // index_ids are capped at 32 bits for storage purposes.
773 std::string index_key_raw; 1032 const int64_t high_index_id = 1ULL << 29;
774 EncodeIDBKey(index_key, &index_key_raw); 1033
775 { 1034 const int64_t invalid_high_index_id = 1ULL << 37;
776 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); 1035
777 transaction1.Begin(); 1036 const IndexedDBKey& index_key = key2;
778 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 1037 std::string index_key_raw;
779 IndexedDBBackingStore::RecordIdentifier record; 1038 EncodeIDBKey(index_key, &index_key_raw);
780 leveldb::Status s = backing_store_->PutRecord( 1039 {
781 &transaction1, high_database_id, high_object_store_id, key1_, &value1_, 1040 IndexedDBBackingStore::Transaction transaction1(backing_store);
782 &handles, &record); 1041 transaction1.Begin();
783 EXPECT_TRUE(s.ok()); 1042 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
784 1043 IndexedDBBackingStore::RecordIdentifier record;
785 s = backing_store_->PutIndexDataForRecord(&transaction1, 1044 leveldb::Status s = backing_store->PutRecord(
786 high_database_id, 1045 &transaction1, high_database_id, high_object_store_id, key1,
787 high_object_store_id, 1046 &value1, &handles, &record);
788 invalid_high_index_id, 1047 EXPECT_TRUE(s.ok());
789 index_key, 1048
790 record); 1049 s = backing_store->PutIndexDataForRecord(
791 EXPECT_FALSE(s.ok()); 1050 &transaction1, high_database_id, high_object_store_id,
792 1051 invalid_high_index_id, index_key, record);
793 s = backing_store_->PutIndexDataForRecord(&transaction1, 1052 EXPECT_FALSE(s.ok());
794 high_database_id, 1053
795 high_object_store_id, 1054 s = backing_store->PutIndexDataForRecord(
796 high_index_id, 1055 &transaction1, high_database_id, high_object_store_id,
797 index_key, 1056 high_index_id, index_key, record);
798 record); 1057 EXPECT_TRUE(s.ok());
799 EXPECT_TRUE(s.ok()); 1058
800 1059 scoped_refptr<TestCallback> callback(
801 scoped_refptr<TestCallback> callback(new TestCallback()); 1060 base::MakeRefCounted<TestCallback>());
802 s = transaction1.CommitPhaseOne(callback); 1061 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
803 EXPECT_TRUE(s.ok()); 1062 EXPECT_TRUE(callback->called);
804 EXPECT_TRUE(callback->called); 1063 EXPECT_TRUE(callback->succeeded);
805 EXPECT_TRUE(callback->succeeded); 1064 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
806 s = transaction1.CommitPhaseTwo(); 1065 }
807 EXPECT_TRUE(s.ok()); 1066
808 } 1067 {
809 1068 IndexedDBBackingStore::Transaction transaction2(backing_store);
810 { 1069 transaction2.Begin();
811 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); 1070 IndexedDBValue result_value;
812 transaction2.Begin(); 1071 leveldb::Status s = backing_store->GetRecord(
813 IndexedDBValue result_value; 1072 &transaction2, high_database_id, high_object_store_id, key1,
814 leveldb::Status s = 1073 &result_value);
815 backing_store_->GetRecord(&transaction2, high_database_id, 1074 EXPECT_TRUE(s.ok());
816 high_object_store_id, key1_, &result_value); 1075 EXPECT_EQ(value1.bits, result_value.bits);
817 EXPECT_TRUE(s.ok()); 1076
818 EXPECT_EQ(value1_.bits, result_value.bits); 1077 std::unique_ptr<IndexedDBKey> new_primary_key;
819 1078 s = backing_store->GetPrimaryKeyViaIndex(
820 std::unique_ptr<IndexedDBKey> new_primary_key; 1079 &transaction2, high_database_id, high_object_store_id,
821 s = backing_store_->GetPrimaryKeyViaIndex(&transaction2, 1080 invalid_high_index_id, index_key, &new_primary_key);
822 high_database_id, 1081 EXPECT_FALSE(s.ok());
823 high_object_store_id, 1082
824 invalid_high_index_id, 1083 s = backing_store->GetPrimaryKeyViaIndex(
825 index_key, 1084 &transaction2, high_database_id, high_object_store_id,
826 &new_primary_key); 1085 high_index_id, index_key, &new_primary_key);
827 EXPECT_FALSE(s.ok()); 1086 EXPECT_TRUE(s.ok());
828 1087 EXPECT_TRUE(new_primary_key->Equals(key1));
829 s = backing_store_->GetPrimaryKeyViaIndex(&transaction2, 1088
830 high_database_id, 1089 scoped_refptr<TestCallback> callback(
831 high_object_store_id, 1090 base::MakeRefCounted<TestCallback>());
832 high_index_id, 1091 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
833 index_key, 1092 EXPECT_TRUE(callback->called);
834 &new_primary_key); 1093 EXPECT_TRUE(callback->succeeded);
835 EXPECT_TRUE(s.ok()); 1094 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
836 EXPECT_TRUE(new_primary_key->Equals(key1_)); 1095 }
837 1096 },
838 scoped_refptr<TestCallback> callback(new TestCallback()); 1097 base::Unretained(backing_store()), key1_, key2_, value1_));
839 s = transaction2.CommitPhaseOne(callback); 1098 RunAllBlockingPoolTasksUntilIdle();
840 EXPECT_TRUE(s.ok());
841 EXPECT_TRUE(callback->called);
842 EXPECT_TRUE(callback->succeeded);
843 s = transaction2.CommitPhaseTwo();
844 EXPECT_TRUE(s.ok());
845 }
846 } 1099 }
847 1100
848 // Make sure that other invalid ids do not crash. 1101 // Make sure that other invalid ids do not crash.
849 TEST_F(IndexedDBBackingStoreTest, InvalidIds) { 1102 TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
850 // valid ids for use when testing invalid ids 1103 idb_context_->TaskRunner()->PostTask(
851 const int64_t database_id = 1; 1104 FROM_HERE,
852 const int64_t object_store_id = 1; 1105 base::BindOnce(
853 const int64_t index_id = kMinimumIndexId; 1106 [](IndexedDBBackingStore* backing_store, IndexedDBKey key,
854 const int64_t invalid_low_index_id = 1107 IndexedDBValue value) {
855 19; // index_ids must be > kMinimumIndexId 1108 // valid ids for use when testing invalid ids
856 1109 const int64_t database_id = 1;
857 IndexedDBValue result_value; 1110 const int64_t object_store_id = 1;
858 1111 const int64_t index_id = kMinimumIndexId;
859 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); 1112 // index_ids must be > kMinimumIndexId
860 transaction1.Begin(); 1113 const int64_t invalid_low_index_id = 19;
861 1114 IndexedDBValue result_value;
862 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 1115
863 IndexedDBBackingStore::RecordIdentifier record; 1116 IndexedDBBackingStore::Transaction transaction1(backing_store);
864 leveldb::Status s = backing_store_->PutRecord(&transaction1, database_id, 1117 transaction1.Begin();
865 KeyPrefix::kInvalidId, key1_, 1118
866 &value1_, &handles, &record); 1119 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
867 EXPECT_FALSE(s.ok()); 1120 IndexedDBBackingStore::RecordIdentifier record;
868 s = backing_store_->PutRecord(&transaction1, database_id, 0, key1_, &value1_, 1121 leveldb::Status s = backing_store->PutRecord(
869 &handles, &record); 1122 &transaction1, database_id, KeyPrefix::kInvalidId, key, &value,
870 EXPECT_FALSE(s.ok()); 1123 &handles, &record);
871 s = backing_store_->PutRecord(&transaction1, KeyPrefix::kInvalidId, 1124 EXPECT_FALSE(s.ok());
872 object_store_id, key1_, &value1_, &handles, 1125 s = backing_store->PutRecord(&transaction1, database_id, 0, key,
873 &record); 1126 &value, &handles, &record);
874 EXPECT_FALSE(s.ok()); 1127 EXPECT_FALSE(s.ok());
875 s = backing_store_->PutRecord(&transaction1, 0, object_store_id, key1_, 1128 s = backing_store->PutRecord(&transaction1, KeyPrefix::kInvalidId,
876 &value1_, &handles, &record); 1129 object_store_id, key, &value, &handles,
877 EXPECT_FALSE(s.ok()); 1130 &record);
878 1131 EXPECT_FALSE(s.ok());
879 s = backing_store_->GetRecord(&transaction1, database_id, 1132 s = backing_store->PutRecord(&transaction1, 0, object_store_id, key,
880 KeyPrefix::kInvalidId, key1_, &result_value); 1133 &value, &handles, &record);
881 EXPECT_FALSE(s.ok()); 1134 EXPECT_FALSE(s.ok());
882 s = backing_store_->GetRecord(&transaction1, database_id, 0, key1_, 1135
883 &result_value); 1136 s = backing_store->GetRecord(&transaction1, database_id,
884 EXPECT_FALSE(s.ok()); 1137 KeyPrefix::kInvalidId, key,
885 s = backing_store_->GetRecord(&transaction1, KeyPrefix::kInvalidId, 1138 &result_value);
886 object_store_id, key1_, &result_value); 1139 EXPECT_FALSE(s.ok());
887 EXPECT_FALSE(s.ok()); 1140 s = backing_store->GetRecord(&transaction1, database_id, 0, key,
888 s = backing_store_->GetRecord(&transaction1, 0, object_store_id, key1_, 1141 &result_value);
889 &result_value); 1142 EXPECT_FALSE(s.ok());
890 EXPECT_FALSE(s.ok()); 1143 s = backing_store->GetRecord(&transaction1, KeyPrefix::kInvalidId,
891 1144 object_store_id, key, &result_value);
892 std::unique_ptr<IndexedDBKey> new_primary_key; 1145 EXPECT_FALSE(s.ok());
893 s = backing_store_->GetPrimaryKeyViaIndex( 1146 s = backing_store->GetRecord(&transaction1, 0, object_store_id, key,
894 &transaction1, database_id, object_store_id, KeyPrefix::kInvalidId, key1_, 1147 &result_value);
895 &new_primary_key); 1148 EXPECT_FALSE(s.ok());
896 EXPECT_FALSE(s.ok()); 1149
897 s = backing_store_->GetPrimaryKeyViaIndex( 1150 std::unique_ptr<IndexedDBKey> new_primary_key;
898 &transaction1, database_id, object_store_id, invalid_low_index_id, key1_, 1151 s = backing_store->GetPrimaryKeyViaIndex(
899 &new_primary_key); 1152 &transaction1, database_id, object_store_id,
900 EXPECT_FALSE(s.ok()); 1153 KeyPrefix::kInvalidId, key, &new_primary_key);
901 s = backing_store_->GetPrimaryKeyViaIndex( 1154 EXPECT_FALSE(s.ok());
902 &transaction1, database_id, object_store_id, 0, key1_, &new_primary_key); 1155 s = backing_store->GetPrimaryKeyViaIndex(
903 EXPECT_FALSE(s.ok()); 1156 &transaction1, database_id, object_store_id,
904 1157 invalid_low_index_id, key, &new_primary_key);
905 s = backing_store_->GetPrimaryKeyViaIndex( 1158 EXPECT_FALSE(s.ok());
906 &transaction1, KeyPrefix::kInvalidId, object_store_id, index_id, key1_, 1159 s = backing_store->GetPrimaryKeyViaIndex(&transaction1, database_id,
907 &new_primary_key); 1160 object_store_id, 0, key,
908 EXPECT_FALSE(s.ok()); 1161 &new_primary_key);
909 s = backing_store_->GetPrimaryKeyViaIndex(&transaction1, database_id, 1162 EXPECT_FALSE(s.ok());
910 KeyPrefix::kInvalidId, index_id, 1163
911 key1_, &new_primary_key); 1164 s = backing_store->GetPrimaryKeyViaIndex(
912 EXPECT_FALSE(s.ok()); 1165 &transaction1, KeyPrefix::kInvalidId, object_store_id, index_id,
1166 key, &new_primary_key);
1167 EXPECT_FALSE(s.ok());
1168 s = backing_store->GetPrimaryKeyViaIndex(
1169 &transaction1, database_id, KeyPrefix::kInvalidId, index_id,
1170 key, &new_primary_key);
1171 EXPECT_FALSE(s.ok());
1172 },
1173 base::Unretained(backing_store()), key1_, value1_));
1174 RunAllBlockingPoolTasksUntilIdle();
913 } 1175 }
914 1176
915 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) { 1177 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
916 const base::string16 database_name(ASCIIToUTF16("db1")); 1178 idb_context_->TaskRunner()->PostTask(
917 int64_t database_id; 1179 FROM_HERE,
918 const int64_t version = 9; 1180 base::BindOnce(
919 1181 [](IndexedDBBackingStore* backing_store) {
920 const int64_t object_store_id = 99; 1182 const base::string16 database_name(ASCIIToUTF16("db1"));
921 const base::string16 object_store_name(ASCIIToUTF16("object_store1")); 1183 int64_t database_id;
922 const bool auto_increment = true; 1184 const int64_t version = 9;
923 const IndexedDBKeyPath object_store_key_path( 1185
924 ASCIIToUTF16("object_store_key")); 1186 const int64_t object_store_id = 99;
925 1187 const base::string16 object_store_name(
926 const int64_t index_id = 999; 1188 ASCIIToUTF16("object_store1"));
927 const base::string16 index_name(ASCIIToUTF16("index1")); 1189 const bool auto_increment = true;
928 const bool unique = true; 1190 const IndexedDBKeyPath object_store_key_path(
929 const bool multi_entry = true; 1191 ASCIIToUTF16("object_store_key"));
930 const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key")); 1192
931 1193 const int64_t index_id = 999;
932 { 1194 const base::string16 index_name(ASCIIToUTF16("index1"));
933 leveldb::Status s = backing_store_->CreateIDBDatabaseMetaData( 1195 const bool unique = true;
934 database_name, version, &database_id); 1196 const bool multi_entry = true;
935 EXPECT_TRUE(s.ok()); 1197 const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key"));
936 EXPECT_GT(database_id, 0); 1198
937 1199 {
938 IndexedDBBackingStore::Transaction transaction(backing_store_.get()); 1200 leveldb::Status s = backing_store->CreateIDBDatabaseMetaData(
939 transaction.Begin(); 1201 database_name, version, &database_id);
940 1202 EXPECT_TRUE(s.ok());
941 s = backing_store_->CreateObjectStore(&transaction, 1203 EXPECT_GT(database_id, 0);
942 database_id, 1204
943 object_store_id, 1205 IndexedDBBackingStore::Transaction transaction(backing_store);
944 object_store_name, 1206 transaction.Begin();
945 object_store_key_path, 1207
946 auto_increment); 1208 s = backing_store->CreateObjectStore(
947 EXPECT_TRUE(s.ok()); 1209 &transaction, database_id, object_store_id, object_store_name,
948 1210 object_store_key_path, auto_increment);
949 s = backing_store_->CreateIndex(&transaction, 1211 EXPECT_TRUE(s.ok());
950 database_id, 1212
951 object_store_id, 1213 s = backing_store->CreateIndex(
952 index_id, 1214 &transaction, database_id, object_store_id, index_id,
953 index_name, 1215 index_name, index_key_path, unique, multi_entry);
954 index_key_path, 1216 EXPECT_TRUE(s.ok());
955 unique, 1217
956 multi_entry); 1218 scoped_refptr<TestCallback> callback(
957 EXPECT_TRUE(s.ok()); 1219 base::MakeRefCounted<TestCallback>());
958 1220 EXPECT_TRUE(transaction.CommitPhaseOne(callback).ok());
959 scoped_refptr<TestCallback> callback(new TestCallback()); 1221 EXPECT_TRUE(callback->called);
960 s = transaction.CommitPhaseOne(callback); 1222 EXPECT_TRUE(callback->succeeded);
961 EXPECT_TRUE(s.ok()); 1223 EXPECT_TRUE(transaction.CommitPhaseTwo().ok());
962 EXPECT_TRUE(callback->called); 1224 }
963 EXPECT_TRUE(callback->succeeded); 1225
964 s = transaction.CommitPhaseTwo(); 1226 {
965 EXPECT_TRUE(s.ok()); 1227 IndexedDBDatabaseMetadata database;
966 } 1228 bool found;
967 1229 leveldb::Status s = backing_store->GetIDBDatabaseMetaData(
968 { 1230 database_name, &database, &found);
969 IndexedDBDatabaseMetadata database; 1231 EXPECT_TRUE(s.ok());
970 bool found; 1232 EXPECT_TRUE(found);
971 leveldb::Status s = backing_store_->GetIDBDatabaseMetaData( 1233
972 database_name, &database, &found); 1234 // database.name is not filled in by the implementation.
973 EXPECT_TRUE(s.ok()); 1235 EXPECT_EQ(version, database.version);
974 EXPECT_TRUE(found); 1236 EXPECT_EQ(database_id, database.id);
975 1237
976 // database.name is not filled in by the implementation. 1238 s = backing_store->GetObjectStores(database.id,
977 EXPECT_EQ(version, database.version); 1239 &database.object_stores);
978 EXPECT_EQ(database_id, database.id); 1240 EXPECT_TRUE(s.ok());
979 1241
980 s = backing_store_->GetObjectStores(database.id, &database.object_stores); 1242 EXPECT_EQ(1UL, database.object_stores.size());
981 EXPECT_TRUE(s.ok()); 1243 IndexedDBObjectStoreMetadata object_store =
982 1244 database.object_stores[object_store_id];
983 EXPECT_EQ(1UL, database.object_stores.size()); 1245 EXPECT_EQ(object_store_name, object_store.name);
984 IndexedDBObjectStoreMetadata object_store = 1246 EXPECT_EQ(object_store_key_path, object_store.key_path);
985 database.object_stores[object_store_id]; 1247 EXPECT_EQ(auto_increment, object_store.auto_increment);
986 EXPECT_EQ(object_store_name, object_store.name); 1248
987 EXPECT_EQ(object_store_key_path, object_store.key_path); 1249 EXPECT_EQ(1UL, object_store.indexes.size());
988 EXPECT_EQ(auto_increment, object_store.auto_increment); 1250 IndexedDBIndexMetadata index = object_store.indexes[index_id];
989 1251 EXPECT_EQ(index_name, index.name);
990 EXPECT_EQ(1UL, object_store.indexes.size()); 1252 EXPECT_EQ(index_key_path, index.key_path);
991 IndexedDBIndexMetadata index = object_store.indexes[index_id]; 1253 EXPECT_EQ(unique, index.unique);
992 EXPECT_EQ(index_name, index.name); 1254 EXPECT_EQ(multi_entry, index.multi_entry);
993 EXPECT_EQ(index_key_path, index.key_path); 1255 }
994 EXPECT_EQ(unique, index.unique); 1256 },
995 EXPECT_EQ(multi_entry, index.multi_entry); 1257 base::Unretained(backing_store())));
996 } 1258 RunAllBlockingPoolTasksUntilIdle();
997 } 1259 }
998 1260
999 TEST_F(IndexedDBBackingStoreTest, GetDatabaseNames) { 1261 TEST_F(IndexedDBBackingStoreTest, GetDatabaseNames) {
1000 const base::string16 db1_name(ASCIIToUTF16("db1")); 1262 idb_context_->TaskRunner()->PostTask(
1001 const int64_t db1_version = 1LL; 1263 FROM_HERE, base::BindOnce(
1002 int64_t db1_id; 1264 [](IndexedDBBackingStore* backing_store) {
1003 1265 const base::string16 db1_name(ASCIIToUTF16("db1"));
1004 // Database records with DEFAULT_VERSION represent stale data, 1266 const int64_t db1_version = 1LL;
1005 // and should not be enumerated. 1267 int64_t db1_id;
1006 const base::string16 db2_name(ASCIIToUTF16("db2")); 1268
1007 const int64_t db2_version = IndexedDBDatabaseMetadata::DEFAULT_VERSION; 1269 // Database records with DEFAULT_VERSION represent
1008 int64_t db2_id; 1270 // stale data, and should not be enumerated.
1009 1271 const base::string16 db2_name(ASCIIToUTF16("db2"));
1010 leveldb::Status s = 1272 const int64_t db2_version =
1011 backing_store_->CreateIDBDatabaseMetaData(db1_name, db1_version, &db1_id); 1273 IndexedDBDatabaseMetadata::DEFAULT_VERSION;
1012 EXPECT_TRUE(s.ok()); 1274 int64_t db2_id;
1013 EXPECT_GT(db1_id, 0LL); 1275
1014 1276 leveldb::Status s =
1015 s = backing_store_->CreateIDBDatabaseMetaData(db2_name, db2_version, &db2_id); 1277 backing_store->CreateIDBDatabaseMetaData(
1016 EXPECT_TRUE(s.ok()); 1278 db1_name, db1_version, &db1_id);
1017 EXPECT_GT(db2_id, db1_id); 1279 EXPECT_TRUE(s.ok());
1018 1280 EXPECT_GT(db1_id, 0LL);
1019 std::vector<base::string16> names = backing_store_->GetDatabaseNames(&s); 1281
1020 EXPECT_TRUE(s.ok()); 1282 s = backing_store->CreateIDBDatabaseMetaData(
1021 ASSERT_EQ(1U, names.size()); 1283 db2_name, db2_version, &db2_id);
1022 EXPECT_EQ(db1_name, names[0]); 1284 EXPECT_TRUE(s.ok());
1285 EXPECT_GT(db2_id, db1_id);
1286
1287 std::vector<base::string16> names =
1288 backing_store->GetDatabaseNames(&s);
1289 EXPECT_TRUE(s.ok());
1290 ASSERT_EQ(1U, names.size());
1291 EXPECT_EQ(db1_name, names[0]);
1292 },
1293 base::Unretained(backing_store())));
1294 RunAllBlockingPoolTasksUntilIdle();
1023 } 1295 }
1024 1296
1025 } // namespace 1297 } // namespace
1026 1298
1027 // Not in the anonymous namespace to friend IndexedDBBackingStore. 1299 // Not in the anonymous namespace to friend IndexedDBBackingStore.
1028 TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) { 1300 TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) {
1029 // No |path_base|. 1301 // No |path_base|.
1030 std::string message; 1302 std::string message;
1031 EXPECT_FALSE(IndexedDBBackingStore::ReadCorruptionInfo(base::FilePath(), 1303 EXPECT_FALSE(IndexedDBBackingStore::ReadCorruptionInfo(base::FilePath(),
1032 Origin(), &message)); 1304 Origin(), &message));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 1381
1110 // Dictionary, message key and more. 1382 // Dictionary, message key and more.
1111 ASSERT_TRUE(WriteFile(info_path, "{\"message\":\"foo\",\"bar\":5}")); 1383 ASSERT_TRUE(WriteFile(info_path, "{\"message\":\"foo\",\"bar\":5}"));
1112 EXPECT_TRUE( 1384 EXPECT_TRUE(
1113 IndexedDBBackingStore::ReadCorruptionInfo(path_base, origin, &message)); 1385 IndexedDBBackingStore::ReadCorruptionInfo(path_base, origin, &message));
1114 EXPECT_FALSE(PathExists(info_path)); 1386 EXPECT_FALSE(PathExists(info_path));
1115 EXPECT_EQ("foo", message); 1387 EXPECT_EQ("foo", message);
1116 } 1388 }
1117 1389
1118 } // namespace content 1390 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698