| Index: content/browser/indexed_db/indexed_db_backing_store_unittest.cc
|
| diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
|
| index 99f1dff55e3482f685b56a6e9fa51fe37ecad20f..d5dc6681ffebc463a35d470546fc49ef43eb0bbb 100644
|
| --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
|
| +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
|
| @@ -17,13 +17,13 @@
|
| #include "base/sequenced_task_runner.h"
|
| #include "base/strings/string16.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| -#include "base/test/test_simple_task_runner.h"
|
| #include "content/browser/indexed_db/indexed_db_context_impl.h"
|
| #include "content/browser/indexed_db/indexed_db_factory_impl.h"
|
| #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
|
| #include "content/browser/indexed_db/indexed_db_value.h"
|
| #include "content/browser/indexed_db/leveldb/leveldb_factory.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "content/public/test/test_utils.h"
|
| #include "net/url_request/url_request_test_util.h"
|
| #include "storage/browser/blob/blob_data_handle.h"
|
| #include "storage/browser/quota/special_storage_policy.h"
|
| @@ -232,27 +232,94 @@ class TestIDBFactory : public IndexedDBFactoryImpl {
|
|
|
| class IndexedDBBackingStoreTest : public testing::Test {
|
| public:
|
| - IndexedDBBackingStoreTest() {}
|
| + IndexedDBBackingStoreTest()
|
| + : url_request_context_getter_(
|
| + base::MakeRefCounted<net::TestURLRequestContextGetter>(
|
| + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))),
|
| + special_storage_policy_(
|
| + base::MakeRefCounted<MockSpecialStoragePolicy>()),
|
| + quota_manager_proxy_(
|
| + base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {}
|
| +
|
| void SetUp() override {
|
| - const Origin origin(GURL("http://localhost:81"));
|
| - task_runner_ = new base::TestSimpleTaskRunner();
|
| - url_request_context_getter_ =
|
| - new net::TestURLRequestContextGetter(task_runner_);
|
| - special_storage_policy_ = new MockSpecialStoragePolicy();
|
| - quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr);
|
| special_storage_policy_->SetAllUnlimited(true);
|
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
| - idb_context_ = new IndexedDBContextImpl(
|
| - temp_dir_.GetPath(), special_storage_policy_.get(),
|
| - quota_manager_proxy_.get(), task_runner_.get());
|
| - idb_factory_ = new TestIDBFactory(idb_context_.get());
|
| - backing_store_ = idb_factory_->OpenBackingStoreForTest(
|
| - origin, url_request_context_getter_);
|
| + idb_context_ = base::MakeRefCounted<IndexedDBContextImpl>(
|
| + temp_dir_.GetPath(), special_storage_policy_, quota_manager_proxy_);
|
| +
|
| + // Factory and backing store must be created on IDB task runner.
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE, base::BindOnce(
|
| + [](IndexedDBBackingStoreTest* test) {
|
| + const Origin origin(GURL("http://localhost:81"));
|
| + test->idb_factory_ =
|
| + base::MakeRefCounted<TestIDBFactory>(
|
| + test->idb_context_.get());
|
| + test->backing_store_ =
|
| + test->idb_factory_->OpenBackingStoreForTest(
|
| + origin, test->url_request_context_getter_);
|
| + },
|
| + base::Unretained(this)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
|
|
| // useful keys and values during tests
|
| value1_ = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>());
|
| value2_ = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>());
|
|
|
| + key1_ = IndexedDBKey(99, blink::kWebIDBKeyTypeNumber);
|
| + key2_ = IndexedDBKey(ASCIIToUTF16("key2"));
|
| + }
|
| +
|
| + void TearDown() override {
|
| + // Factory and backing store must be destroyed on IDB task runner.
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE, base::BindOnce(
|
| + [](IndexedDBBackingStoreTest* test) {
|
| + test->idb_factory_ = nullptr;
|
| + test->backing_store_ = nullptr;
|
| + },
|
| + base::Unretained(this)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + quota_manager_proxy_->SimulateQuotaManagerDestroyed();
|
| + }
|
| +
|
| + TestableIndexedDBBackingStore* backing_store() const {
|
| + return backing_store_.get();
|
| + }
|
| +
|
| + // Sample keys and values that are consistent. Public so that posted lambdas
|
| + // passed |this| can access them.
|
| + IndexedDBKey key1_;
|
| + IndexedDBKey key2_;
|
| + IndexedDBValue value1_;
|
| + IndexedDBValue value2_;
|
| +
|
| + protected:
|
| + // Must be initialized before url_request_context_getter_
|
| + TestBrowserThreadBundle thread_bundle_;
|
| +
|
| + base::ScopedTempDir temp_dir_;
|
| + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
|
| + scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
|
| + scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
|
| + scoped_refptr<IndexedDBContextImpl> idb_context_;
|
| + scoped_refptr<TestIDBFactory> idb_factory_;
|
| +
|
| + scoped_refptr<TestableIndexedDBBackingStore> backing_store_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
|
| +};
|
| +
|
| +class IndexedDBBackingStoreTestWithBlobs : public IndexedDBBackingStoreTest {
|
| + public:
|
| + IndexedDBBackingStoreTestWithBlobs() {}
|
| +
|
| + void SetUp() override {
|
| + IndexedDBBackingStoreTest::SetUp();
|
| +
|
| + // useful keys and values during tests
|
| blob_info_.push_back(
|
| IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("blob type"), 1));
|
| blob_info_.push_back(IndexedDBBlobInfo(
|
| @@ -263,18 +330,14 @@ class IndexedDBBackingStoreTest : public testing::Test {
|
| base::UTF8ToUTF16("file type")));
|
| value3_ = IndexedDBValue("value3", blob_info_);
|
|
|
| - key1_ = IndexedDBKey(99, blink::kWebIDBKeyTypeNumber);
|
| - key2_ = IndexedDBKey(ASCIIToUTF16("key2"));
|
| key3_ = IndexedDBKey(ASCIIToUTF16("key3"));
|
| }
|
|
|
| - void TearDown() override {
|
| - quota_manager_proxy_->SimulateQuotaManagerDestroyed();
|
| - }
|
| -
|
| // This just checks the data that survive getting stored and recalled, e.g.
|
| // the file path and UUID will change and thus aren't verified.
|
| bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const {
|
| + DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
|
| +
|
| if (blob_info_.size() != reads.size())
|
| return false;
|
| for (size_t i = 0; i < blob_info_.size(); ++i) {
|
| @@ -297,6 +360,8 @@ class IndexedDBBackingStoreTest : public testing::Test {
|
|
|
| bool CheckBlobReadsMatchWrites(
|
| const std::vector<IndexedDBBlobInfo>& reads) const {
|
| + DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
|
| +
|
| if (backing_store_->writes().size() != reads.size())
|
| return false;
|
| std::set<int64_t> ids;
|
| @@ -312,6 +377,8 @@ class IndexedDBBackingStoreTest : public testing::Test {
|
| }
|
|
|
| bool CheckBlobWrites() const {
|
| + DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
|
| +
|
| if (backing_store_->writes().size() != blob_info_.size())
|
| return false;
|
| for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
|
| @@ -333,6 +400,8 @@ class IndexedDBBackingStoreTest : public testing::Test {
|
| }
|
|
|
| bool CheckBlobRemovals() const {
|
| + DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence());
|
| +
|
| if (backing_store_->removals().size() != backing_store_->writes().size())
|
| return false;
|
| for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
|
| @@ -342,31 +411,17 @@ class IndexedDBBackingStoreTest : public testing::Test {
|
| return true;
|
| }
|
|
|
| - protected:
|
| - // Must be initialized before url_request_context_getter_
|
| - TestBrowserThreadBundle thread_bundle_;
|
| -
|
| - base::ScopedTempDir temp_dir_;
|
| - scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
|
| - scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
|
| - scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
|
| - scoped_refptr<IndexedDBContextImpl> idb_context_;
|
| - scoped_refptr<TestIDBFactory> idb_factory_;
|
| - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
|
| -
|
| - scoped_refptr<TestableIndexedDBBackingStore> backing_store_;
|
| -
|
| - // Sample keys and values that are consistent.
|
| - IndexedDBKey key1_;
|
| - IndexedDBKey key2_;
|
| + // Sample keys and values that are consistent. Public so that posted lambdas
|
| + // passed |this| can access them.
|
| IndexedDBKey key3_;
|
| - IndexedDBValue value1_;
|
| - IndexedDBValue value2_;
|
| IndexedDBValue value3_;
|
| - std::vector<IndexedDBBlobInfo> blob_info_;
|
|
|
| private:
|
| - DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
|
| + // Blob details referenced by |value3_|. The various CheckBlob*() methods
|
| + // can be used to verify the state as a test progresses.
|
| + std::vector<IndexedDBBlobInfo> blob_info_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTestWithBlobs);
|
| };
|
|
|
| class TestCallback : public IndexedDBBackingStore::BlobWriteCallback {
|
| @@ -396,630 +451,847 @@ class TestCallback : public IndexedDBBackingStore::BlobWriteCallback {
|
| };
|
|
|
| TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - leveldb::Status s = backing_store_->PutRecord(&transaction1, 1, 1, key1_,
|
| - &value1_, &handles, &record);
|
| - EXPECT_TRUE(s.ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - IndexedDBValue result_value;
|
| - EXPECT_TRUE(
|
| - backing_store_->GetRecord(&transaction2, 1, 1, key1_, &result_value)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(value1_.bits, result_value.bits);
|
| - }
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStore* backing_store, IndexedDBKey key,
|
| + IndexedDBValue value) {
|
| + {
|
| + IndexedDBBackingStore::Transaction transaction1(backing_store);
|
| + transaction1.Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + leveldb::Status s = backing_store->PutRecord(
|
| + &transaction1, 1, 1, key, &value, &handles, &record);
|
| + EXPECT_TRUE(s.ok());
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| + }
|
| +
|
| + {
|
| + IndexedDBBackingStore::Transaction transaction2(backing_store);
|
| + transaction2.Begin();
|
| + IndexedDBValue result_value;
|
| + EXPECT_TRUE(
|
| + backing_store
|
| + ->GetRecord(&transaction2, 1, 1, key, &result_value)
|
| + .ok());
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| + EXPECT_EQ(value.bits, result_value.bits);
|
| + }
|
| + },
|
| + base::Unretained(backing_store()), key1_, value1_));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| -TEST_F(IndexedDBBackingStoreTest, PutGetConsistencyWithBlobs) {
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - EXPECT_TRUE(
|
| - backing_store_
|
| - ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles, &record)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(CheckBlobWrites());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - IndexedDBValue result_value;
|
| - EXPECT_TRUE(
|
| - backing_store_->GetRecord(&transaction2, 1, 1, key3_, &result_value)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(value3_.bits, result_value.bits);
|
| - EXPECT_TRUE(CheckBlobInfoMatches(result_value.blob_info));
|
| - EXPECT_TRUE(CheckBlobReadsMatchWrites(result_value.blob_info));
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction3(backing_store_.get());
|
| - transaction3.Begin();
|
| - IndexedDBValue result_value;
|
| - EXPECT_TRUE(backing_store_
|
| - ->DeleteRange(&transaction3, 1, 1, IndexedDBKeyRange(key3_))
|
| +TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
|
| + struct TestState {
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
|
| + scoped_refptr<TestCallback> callback1;
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3;
|
| + scoped_refptr<TestCallback> callback3;
|
| + } state;
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + // Initiate transaction1 - writing blobs.
|
| + state->transaction1 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + test->backing_store());
|
| + state->transaction1->Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->PutRecord(state->transaction1.get(), 1, 1,
|
| + test->key3_, &test->value3_, &handles,
|
| + &record)
|
| + .ok());
|
| + state->callback1 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction1->CommitPhaseOne(state->callback1).ok());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + // Finish up transaction1, verifying blob writes.
|
| + EXPECT_TRUE(state->callback1->called);
|
| + EXPECT_TRUE(state->callback1->succeeded);
|
| + EXPECT_TRUE(test->CheckBlobWrites());
|
| + EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
|
| +
|
| + // Initiate transaction2, reading blobs.
|
| + IndexedDBBackingStore::Transaction transaction2(
|
| + test->backing_store());
|
| + transaction2.Begin();
|
| + IndexedDBValue result_value;
|
| + EXPECT_TRUE(
|
| + test->backing_store()
|
| + ->GetRecord(&transaction2, 1, 1, test->key3_, &result_value)
|
| .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction3.CommitPhaseTwo().ok());
|
| - EXPECT_TRUE(CheckBlobRemovals());
|
| - }
|
| +
|
| + // Finish up transaction2, verifying blob reads.
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| + EXPECT_EQ(test->value3_.bits, result_value.bits);
|
| + EXPECT_TRUE(test->CheckBlobInfoMatches(result_value.blob_info));
|
| + EXPECT_TRUE(
|
| + test->CheckBlobReadsMatchWrites(result_value.blob_info));
|
| +
|
| + // Initiate transaction3, deleting blobs.
|
| + state->transaction3 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + test->backing_store());
|
| + state->transaction3->Begin();
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->DeleteRange(state->transaction3.get(), 1, 1,
|
| + IndexedDBKeyRange(test->key3_))
|
| + .ok());
|
| + state->callback3 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction3->CommitPhaseOne(state->callback3).ok());
|
| +
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + // Finish up transaction 3, verifying blob deletes.
|
| + EXPECT_TRUE(state->transaction3->CommitPhaseTwo().ok());
|
| + EXPECT_TRUE(test->CheckBlobRemovals());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| TEST_F(IndexedDBBackingStoreTest, DeleteRange) {
|
| - IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0"));
|
| - IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1"));
|
| - IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2"));
|
| - IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3"));
|
| - IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1);
|
| - IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1);
|
| - IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1);
|
| - IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1);
|
| - IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key1, key2, false, false),
|
| - IndexedDBKeyRange(key1, key2, false, false),
|
| - IndexedDBKeyRange(key0, key2, true, false),
|
| - IndexedDBKeyRange(key1, key3, false, true),
|
| - IndexedDBKeyRange(key0, key3, true, true)};
|
| -
|
| - for (unsigned i = 0; i < sizeof(ranges) / sizeof(IndexedDBKeyRange); ++i) {
|
| - backing_store_->ClearWrites();
|
| - backing_store_->ClearRemovals();
|
| -
|
| - {
|
| - std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2,
|
| - blob_info3;
|
| - blob_info0.push_back(blob0);
|
| - blob_info1.push_back(blob1);
|
| - blob_info2.push_back(blob2);
|
| - blob_info3.push_back(blob3);
|
| - IndexedDBValue value0 = IndexedDBValue("value0", blob_info0);
|
| - IndexedDBValue value1 = IndexedDBValue("value1", blob_info1);
|
| - IndexedDBValue value2 = IndexedDBValue("value2", blob_info2);
|
| - IndexedDBValue value3 = IndexedDBValue("value3", blob_info3);
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key0,
|
| - &value0,
|
| - &handles,
|
| - &record).ok());
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key1,
|
| - &value1,
|
| - &handles,
|
| - &record).ok());
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key2,
|
| - &value2,
|
| - &handles,
|
| - &record).ok());
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key3,
|
| - &value3,
|
| - &handles,
|
| - &record).ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - IndexedDBValue result_value;
|
| - EXPECT_TRUE(
|
| - backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| - ASSERT_EQ(2UL, backing_store_->removals().size());
|
| - EXPECT_EQ(backing_store_->writes()[1].key(),
|
| - backing_store_->removals()[0]);
|
| - EXPECT_EQ(backing_store_->writes()[2].key(),
|
| - backing_store_->removals()[1]);
|
| - }
|
| + const std::vector<IndexedDBKey> keys = {
|
| + IndexedDBKey(ASCIIToUTF16("key0")), IndexedDBKey(ASCIIToUTF16("key1")),
|
| + IndexedDBKey(ASCIIToUTF16("key2")), IndexedDBKey(ASCIIToUTF16("key3"))};
|
| + const IndexedDBKeyRange ranges[] = {
|
| + IndexedDBKeyRange(keys[1], keys[2], false, false),
|
| + IndexedDBKeyRange(keys[1], keys[2], false, false),
|
| + IndexedDBKeyRange(keys[0], keys[2], true, false),
|
| + IndexedDBKeyRange(keys[1], keys[3], false, true),
|
| + IndexedDBKeyRange(keys[0], keys[3], true, true)};
|
| +
|
| + for (size_t i = 0; i < arraysize(ranges); ++i) {
|
| + const int64_t database_id = 1;
|
| + const int64_t object_store_id = i + 1;
|
| + const IndexedDBKeyRange& range = ranges[i];
|
| +
|
| + struct TestState {
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
|
| + scoped_refptr<TestCallback> callback1;
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2;
|
| + scoped_refptr<TestCallback> callback2;
|
| + } state;
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](TestableIndexedDBBackingStore* backing_store, TestState* state,
|
| + const std::vector<IndexedDBKey>& keys, int64_t database_id,
|
| + int64_t object_store_id) {
|
| + // Reset from previous iteration.
|
| + backing_store->ClearWrites();
|
| + backing_store->ClearRemovals();
|
| +
|
| + std::vector<IndexedDBValue> values = {
|
| + IndexedDBValue(
|
| + "value0", {IndexedDBBlobInfo(
|
| + "uuid 0", base::UTF8ToUTF16("type 0"), 1)}),
|
| + IndexedDBValue(
|
| + "value1", {IndexedDBBlobInfo(
|
| + "uuid 1", base::UTF8ToUTF16("type 1"), 1)}),
|
| + IndexedDBValue(
|
| + "value2", {IndexedDBBlobInfo(
|
| + "uuid 2", base::UTF8ToUTF16("type 2"), 1)}),
|
| + IndexedDBValue(
|
| + "value3",
|
| + {IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("type 3"),
|
| + 1)})};
|
| + ASSERT_GE(keys.size(), values.size());
|
| +
|
| + // Initiate transaction1 - write records.
|
| + state->transaction1 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + backing_store);
|
| + state->transaction1->Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + for (size_t i = 0; i < values.size(); ++i) {
|
| + EXPECT_TRUE(backing_store
|
| + ->PutRecord(state->transaction1.get(),
|
| + database_id, object_store_id,
|
| + keys[i], &values[i], &handles,
|
| + &record)
|
| + .ok());
|
| + }
|
| +
|
| + // Start committing transaction1.
|
| + state->callback1 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction1->CommitPhaseOne(state->callback1).ok());
|
| + },
|
| + base::Unretained(backing_store()), base::Unretained(&state),
|
| + base::ConstRef(keys), database_id, object_store_id));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](TestableIndexedDBBackingStore* backing_store, TestState* state,
|
| + IndexedDBKeyRange range, int64_t database_id,
|
| + int64_t object_store_id) {
|
| + // Finish committing transaction1.
|
| + EXPECT_TRUE(state->callback1->called);
|
| + EXPECT_TRUE(state->callback1->succeeded);
|
| + EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
|
| +
|
| + // Initiate transaction 2 - delete range.
|
| + state->transaction2 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + backing_store);
|
| + state->transaction2->Begin();
|
| + IndexedDBValue result_value;
|
| + EXPECT_TRUE(backing_store
|
| + ->DeleteRange(state->transaction2.get(),
|
| + database_id, object_store_id, range)
|
| + .ok());
|
| +
|
| + // Start committing transaction2.
|
| + state->callback2 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction2->CommitPhaseOne(state->callback2).ok());
|
| + },
|
| + base::Unretained(backing_store()), base::Unretained(&state), range,
|
| + database_id, object_store_id));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](TestableIndexedDBBackingStore* backing_store, TestState* state) {
|
| + // Finish committing transaction2.
|
| + EXPECT_TRUE(state->callback2->called);
|
| + EXPECT_TRUE(state->callback2->succeeded);
|
| + EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok());
|
| +
|
| + // Verify blob removals.
|
| + ASSERT_EQ(2UL, backing_store->removals().size());
|
| + EXPECT_EQ(backing_store->writes()[1].key(),
|
| + backing_store->removals()[0]);
|
| + EXPECT_EQ(backing_store->writes()[2].key(),
|
| + backing_store->removals()[1]);
|
| + },
|
| + base::Unretained(backing_store()), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
| }
|
|
|
| TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) {
|
| - IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0"));
|
| - IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1"));
|
| - IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2"));
|
| - IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3"));
|
| - IndexedDBKey key4 = IndexedDBKey(ASCIIToUTF16("key4"));
|
| - IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1);
|
| - IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1);
|
| - IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1);
|
| - IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1);
|
| - IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key3, key4, true, false),
|
| - IndexedDBKeyRange(key2, key1, false, false),
|
| - IndexedDBKeyRange(key2, key1, true, true)};
|
| -
|
| - for (unsigned i = 0; i < arraysize(ranges); ++i) {
|
| - backing_store_->ClearWrites();
|
| - backing_store_->ClearRemovals();
|
| -
|
| - {
|
| - std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2,
|
| - blob_info3;
|
| - blob_info0.push_back(blob0);
|
| - blob_info1.push_back(blob1);
|
| - blob_info2.push_back(blob2);
|
| - blob_info3.push_back(blob3);
|
| - IndexedDBValue value0 = IndexedDBValue("value0", blob_info0);
|
| - IndexedDBValue value1 = IndexedDBValue("value1", blob_info1);
|
| - IndexedDBValue value2 = IndexedDBValue("value2", blob_info2);
|
| - IndexedDBValue value3 = IndexedDBValue("value3", blob_info3);
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key0,
|
| - &value0,
|
| - &handles,
|
| - &record).ok());
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key1,
|
| - &value1,
|
| - &handles,
|
| - &record).ok());
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key2,
|
| - &value2,
|
| - &handles,
|
| - &record).ok());
|
| - EXPECT_TRUE(backing_store_->PutRecord(&transaction1,
|
| - 1,
|
| - i + 1,
|
| - key3,
|
| - &value3,
|
| - &handles,
|
| - &record).ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - IndexedDBValue result_value;
|
| - EXPECT_TRUE(
|
| - backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(0UL, backing_store_->removals().size());
|
| - }
|
| + const std::vector<IndexedDBKey> keys = {
|
| + IndexedDBKey(ASCIIToUTF16("key0")), IndexedDBKey(ASCIIToUTF16("key1")),
|
| + IndexedDBKey(ASCIIToUTF16("key2")), IndexedDBKey(ASCIIToUTF16("key3")),
|
| + IndexedDBKey(ASCIIToUTF16("key4"))};
|
| + const IndexedDBKeyRange ranges[] = {
|
| + IndexedDBKeyRange(keys[3], keys[4], true, false),
|
| + IndexedDBKeyRange(keys[2], keys[1], false, false),
|
| + IndexedDBKeyRange(keys[2], keys[1], true, true)};
|
| +
|
| + for (size_t i = 0; i < arraysize(ranges); ++i) {
|
| + const int64_t database_id = 1;
|
| + const int64_t object_store_id = i + 1;
|
| + const IndexedDBKeyRange& range = ranges[i];
|
| +
|
| + struct TestState {
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
|
| + scoped_refptr<TestCallback> callback1;
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2;
|
| + scoped_refptr<TestCallback> callback2;
|
| + } state;
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](TestableIndexedDBBackingStore* backing_store, TestState* state,
|
| + const std::vector<IndexedDBKey>& keys, int64_t database_id,
|
| + int64_t object_store_id) {
|
| + // Reset from previous iteration.
|
| + backing_store->ClearWrites();
|
| + backing_store->ClearRemovals();
|
| +
|
| + std::vector<IndexedDBValue> values = {
|
| + IndexedDBValue(
|
| + "value0", {IndexedDBBlobInfo(
|
| + "uuid 0", base::UTF8ToUTF16("type 0"), 1)}),
|
| + IndexedDBValue(
|
| + "value1", {IndexedDBBlobInfo(
|
| + "uuid 1", base::UTF8ToUTF16("type 1"), 1)}),
|
| + IndexedDBValue(
|
| + "value2", {IndexedDBBlobInfo(
|
| + "uuid 2", base::UTF8ToUTF16("type 2"), 1)}),
|
| + IndexedDBValue(
|
| + "value3",
|
| + {IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("type 3"),
|
| + 1)})};
|
| + ASSERT_GE(keys.size(), values.size());
|
| +
|
| + // Initiate transaction1 - write records.
|
| + state->transaction1 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + backing_store);
|
| + state->transaction1->Begin();
|
| +
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + for (size_t i = 0; i < values.size(); ++i) {
|
| + EXPECT_TRUE(backing_store
|
| + ->PutRecord(state->transaction1.get(),
|
| + database_id, object_store_id,
|
| + keys[i], &values[i], &handles,
|
| + &record)
|
| + .ok());
|
| + }
|
| + // Start committing transaction1.
|
| + state->callback1 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction1->CommitPhaseOne(state->callback1).ok());
|
| + },
|
| + base::Unretained(backing_store()), base::Unretained(&state),
|
| + base::ConstRef(keys), database_id, object_store_id));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](TestableIndexedDBBackingStore* backing_store, TestState* state,
|
| + IndexedDBKeyRange range, int64_t database_id,
|
| + int64_t object_store_id) {
|
| + // Finish committing transaction1.
|
| + EXPECT_TRUE(state->callback1->called);
|
| + EXPECT_TRUE(state->callback1->succeeded);
|
| + EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
|
| +
|
| + // Initiate transaction 2 - delete range.
|
| + state->transaction2 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + backing_store);
|
| + state->transaction2->Begin();
|
| + IndexedDBValue result_value;
|
| + EXPECT_TRUE(backing_store
|
| + ->DeleteRange(state->transaction2.get(),
|
| + database_id, object_store_id, range)
|
| + .ok());
|
| +
|
| + // Start committing transaction2.
|
| + state->callback2 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction2->CommitPhaseOne(state->callback2).ok());
|
| + },
|
| + base::Unretained(backing_store()), base::Unretained(&state), range,
|
| + database_id, object_store_id));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](TestableIndexedDBBackingStore* backing_store, TestState* state) {
|
| + // Finish committing transaction2.
|
| + EXPECT_TRUE(state->callback2->called);
|
| + EXPECT_TRUE(state->callback2->succeeded);
|
| + EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok());
|
| +
|
| + // Verify blob removals.
|
| + EXPECT_EQ(0UL, backing_store->removals().size());
|
| + },
|
| + base::Unretained(backing_store()), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
| }
|
|
|
| -TEST_F(IndexedDBBackingStoreTest, BlobJournalInterleavedTransactions) {
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1;
|
| - IndexedDBBackingStore::RecordIdentifier record1;
|
| - EXPECT_TRUE(
|
| - backing_store_
|
| - ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles1, &record1)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback1(new TestCallback());
|
| - EXPECT_TRUE(transaction1.CommitPhaseOne(callback1).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(CheckBlobWrites());
|
| - EXPECT_TRUE(callback1->called);
|
| - EXPECT_TRUE(callback1->succeeded);
|
| - EXPECT_EQ(0U, backing_store_->removals().size());
|
| -
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2;
|
| - IndexedDBBackingStore::RecordIdentifier record2;
|
| - EXPECT_TRUE(
|
| - backing_store_
|
| - ->PutRecord(&transaction2, 1, 1, key1_, &value1_, &handles2, &record2)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback2(new TestCallback());
|
| - EXPECT_TRUE(transaction2.CommitPhaseOne(callback2).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(CheckBlobWrites());
|
| - EXPECT_TRUE(callback2->called);
|
| - EXPECT_TRUE(callback2->succeeded);
|
| - EXPECT_EQ(0U, backing_store_->removals().size());
|
| -
|
| - EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(0U, backing_store_->removals().size());
|
| -
|
| - EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(0U, backing_store_->removals().size());
|
| +TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) {
|
| + struct TestState {
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
|
| + scoped_refptr<TestCallback> callback1;
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2;
|
| + scoped_refptr<TestCallback> callback2;
|
| + } state;
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + // Initiate transaction1.
|
| + state->transaction1 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + test->backing_store());
|
| + state->transaction1->Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1;
|
| + IndexedDBBackingStore::RecordIdentifier record1;
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->PutRecord(state->transaction1.get(), 1, 1,
|
| + test->key3_, &test->value3_, &handles1,
|
| + &record1)
|
| + .ok());
|
| + state->callback1 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction1->CommitPhaseOne(state->callback1).ok());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + // Verify transaction1 phase one completed.
|
| + EXPECT_TRUE(state->callback1->called);
|
| + EXPECT_TRUE(state->callback1->succeeded);
|
| + EXPECT_TRUE(test->CheckBlobWrites());
|
| + EXPECT_EQ(0U, test->backing_store()->removals().size());
|
| +
|
| + // Initiate transaction2.
|
| + state->transaction2 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + test->backing_store());
|
| + state->transaction2->Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2;
|
| + IndexedDBBackingStore::RecordIdentifier record2;
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->PutRecord(state->transaction2.get(), 1, 1,
|
| + test->key1_, &test->value1_, &handles2,
|
| + &record2)
|
| + .ok());
|
| + state->callback2 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction2->CommitPhaseOne(state->callback2).ok());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + // Verify transaction2 phase one completed.
|
| + EXPECT_TRUE(state->callback2->called);
|
| + EXPECT_TRUE(state->callback2->succeeded);
|
| + EXPECT_TRUE(test->CheckBlobWrites());
|
| + EXPECT_EQ(0U, test->backing_store()->removals().size());
|
| +
|
| + // Finalize both transactions.
|
| + EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
|
| + EXPECT_EQ(0U, test->backing_store()->removals().size());
|
| +
|
| + EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok());
|
| + EXPECT_EQ(0U, test->backing_store()->removals().size());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| -TEST_F(IndexedDBBackingStoreTest, LiveBlobJournal) {
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - EXPECT_TRUE(
|
| - backing_store_
|
| - ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles, &record)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(CheckBlobWrites());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| - }
|
| -
|
| - IndexedDBValue read_result_value;
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - EXPECT_TRUE(backing_store_
|
| - ->GetRecord(&transaction2, 1, 1, key3_, &read_result_value)
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(value3_.bits, read_result_value.bits);
|
| - EXPECT_TRUE(CheckBlobInfoMatches(read_result_value.blob_info));
|
| - EXPECT_TRUE(CheckBlobReadsMatchWrites(read_result_value.blob_info));
|
| - for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
|
| - read_result_value.blob_info[i].mark_used_callback().Run();
|
| - }
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction3(backing_store_.get());
|
| - transaction3.Begin();
|
| - EXPECT_TRUE(backing_store_
|
| - ->DeleteRange(&transaction3, 1, 1, IndexedDBKeyRange(key3_))
|
| - .ok());
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok());
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - EXPECT_TRUE(transaction3.CommitPhaseTwo().ok());
|
| - EXPECT_EQ(0U, backing_store_->removals().size());
|
| - for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
|
| - read_result_value.blob_info[i].release_callback().Run(
|
| - read_result_value.blob_info[i].file_path());
|
| - }
|
| - task_runner_->RunUntilIdle();
|
| - EXPECT_NE(0U, backing_store_->removals().size());
|
| - EXPECT_TRUE(CheckBlobRemovals());
|
| - }
|
| +TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
|
| + struct TestState {
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
|
| + scoped_refptr<TestCallback> callback1;
|
| + std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3;
|
| + scoped_refptr<TestCallback> callback3;
|
| + IndexedDBValue read_result_value;
|
| + } state;
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + state->transaction1 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + test->backing_store());
|
| + state->transaction1->Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->PutRecord(state->transaction1.get(), 1, 1,
|
| + test->key3_, &test->value3_, &handles,
|
| + &record)
|
| + .ok());
|
| + state->callback1 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction1->CommitPhaseOne(state->callback1).ok());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + EXPECT_TRUE(state->callback1->called);
|
| + EXPECT_TRUE(state->callback1->succeeded);
|
| + EXPECT_TRUE(test->CheckBlobWrites());
|
| + EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok());
|
| +
|
| + IndexedDBBackingStore::Transaction transaction2(
|
| + test->backing_store());
|
| + transaction2.Begin();
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->GetRecord(&transaction2, 1, 1, test->key3_,
|
| + &state->read_result_value)
|
| + .ok());
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| + EXPECT_EQ(test->value3_.bits, state->read_result_value.bits);
|
| + EXPECT_TRUE(
|
| + test->CheckBlobInfoMatches(state->read_result_value.blob_info));
|
| + EXPECT_TRUE(test->CheckBlobReadsMatchWrites(
|
| + state->read_result_value.blob_info));
|
| + for (size_t i = 0; i < state->read_result_value.blob_info.size();
|
| + ++i) {
|
| + state->read_result_value.blob_info[i].mark_used_callback().Run();
|
| + }
|
| +
|
| + state->transaction3 =
|
| + base::MakeUnique<IndexedDBBackingStore::Transaction>(
|
| + test->backing_store());
|
| + state->transaction3->Begin();
|
| + EXPECT_TRUE(test->backing_store()
|
| + ->DeleteRange(state->transaction3.get(), 1, 1,
|
| + IndexedDBKeyRange(test->key3_))
|
| + .ok());
|
| + state->callback3 = base::MakeRefCounted<TestCallback>();
|
| + EXPECT_TRUE(
|
| + state->transaction3->CommitPhaseOne(state->callback3).ok());
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
|
| + EXPECT_TRUE(state->callback3->called);
|
| + EXPECT_TRUE(state->callback3->succeeded);
|
| + EXPECT_TRUE(state->transaction3->CommitPhaseTwo().ok());
|
| + EXPECT_EQ(0U, test->backing_store()->removals().size());
|
| + for (size_t i = 0; i < state->read_result_value.blob_info.size();
|
| + ++i) {
|
| + state->read_result_value.blob_info[i].release_callback().Run(
|
| + state->read_result_value.blob_info[i].file_path());
|
| + }
|
| + },
|
| + base::Unretained(this), base::Unretained(&state)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| +
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE, base::BindOnce(
|
| + [](IndexedDBBackingStoreTestWithBlobs* test) {
|
| + EXPECT_NE(0U, test->backing_store()->removals().size());
|
| + EXPECT_TRUE(test->CheckBlobRemovals());
|
| + },
|
| + base::Unretained(this)));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| // Make sure that using very high ( more than 32 bit ) values for database_id
|
| // and object_store_id still work.
|
| TEST_F(IndexedDBBackingStoreTest, HighIds) {
|
| - const int64_t high_database_id = 1ULL << 35;
|
| - const int64_t high_object_store_id = 1ULL << 39;
|
| - // index_ids are capped at 32 bits for storage purposes.
|
| - const int64_t high_index_id = 1ULL << 29;
|
| -
|
| - const int64_t invalid_high_index_id = 1ULL << 37;
|
| -
|
| - const IndexedDBKey& index_key = key2_;
|
| - std::string index_key_raw;
|
| - EncodeIDBKey(index_key, &index_key_raw);
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - leveldb::Status s = backing_store_->PutRecord(
|
| - &transaction1, high_database_id, high_object_store_id, key1_, &value1_,
|
| - &handles, &record);
|
| - EXPECT_TRUE(s.ok());
|
| -
|
| - s = backing_store_->PutIndexDataForRecord(&transaction1,
|
| - high_database_id,
|
| - high_object_store_id,
|
| - invalid_high_index_id,
|
| - index_key,
|
| - record);
|
| - EXPECT_FALSE(s.ok());
|
| -
|
| - s = backing_store_->PutIndexDataForRecord(&transaction1,
|
| - high_database_id,
|
| - high_object_store_id,
|
| - high_index_id,
|
| - index_key,
|
| - record);
|
| - EXPECT_TRUE(s.ok());
|
| -
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - s = transaction1.CommitPhaseOne(callback);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - s = transaction1.CommitPhaseTwo();
|
| - EXPECT_TRUE(s.ok());
|
| - }
|
| -
|
| - {
|
| - IndexedDBBackingStore::Transaction transaction2(backing_store_.get());
|
| - transaction2.Begin();
|
| - IndexedDBValue result_value;
|
| - leveldb::Status s =
|
| - backing_store_->GetRecord(&transaction2, high_database_id,
|
| - high_object_store_id, key1_, &result_value);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_EQ(value1_.bits, result_value.bits);
|
| -
|
| - std::unique_ptr<IndexedDBKey> new_primary_key;
|
| - s = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
|
| - high_database_id,
|
| - high_object_store_id,
|
| - invalid_high_index_id,
|
| - index_key,
|
| - &new_primary_key);
|
| - EXPECT_FALSE(s.ok());
|
| -
|
| - s = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
|
| - high_database_id,
|
| - high_object_store_id,
|
| - high_index_id,
|
| - index_key,
|
| - &new_primary_key);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_TRUE(new_primary_key->Equals(key1_));
|
| -
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - s = transaction2.CommitPhaseOne(callback);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - s = transaction2.CommitPhaseTwo();
|
| - EXPECT_TRUE(s.ok());
|
| - }
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStore* backing_store, IndexedDBKey key1,
|
| + IndexedDBKey key2, IndexedDBValue value1) {
|
| + const int64_t high_database_id = 1ULL << 35;
|
| + const int64_t high_object_store_id = 1ULL << 39;
|
| + // index_ids are capped at 32 bits for storage purposes.
|
| + const int64_t high_index_id = 1ULL << 29;
|
| +
|
| + const int64_t invalid_high_index_id = 1ULL << 37;
|
| +
|
| + const IndexedDBKey& index_key = key2;
|
| + std::string index_key_raw;
|
| + EncodeIDBKey(index_key, &index_key_raw);
|
| + {
|
| + IndexedDBBackingStore::Transaction transaction1(backing_store);
|
| + transaction1.Begin();
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + leveldb::Status s = backing_store->PutRecord(
|
| + &transaction1, high_database_id, high_object_store_id, key1,
|
| + &value1, &handles, &record);
|
| + EXPECT_TRUE(s.ok());
|
| +
|
| + s = backing_store->PutIndexDataForRecord(
|
| + &transaction1, high_database_id, high_object_store_id,
|
| + invalid_high_index_id, index_key, record);
|
| + EXPECT_FALSE(s.ok());
|
| +
|
| + s = backing_store->PutIndexDataForRecord(
|
| + &transaction1, high_database_id, high_object_store_id,
|
| + high_index_id, index_key, record);
|
| + EXPECT_TRUE(s.ok());
|
| +
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction1.CommitPhaseTwo().ok());
|
| + }
|
| +
|
| + {
|
| + IndexedDBBackingStore::Transaction transaction2(backing_store);
|
| + transaction2.Begin();
|
| + IndexedDBValue result_value;
|
| + leveldb::Status s = backing_store->GetRecord(
|
| + &transaction2, high_database_id, high_object_store_id, key1,
|
| + &result_value);
|
| + EXPECT_TRUE(s.ok());
|
| + EXPECT_EQ(value1.bits, result_value.bits);
|
| +
|
| + std::unique_ptr<IndexedDBKey> new_primary_key;
|
| + s = backing_store->GetPrimaryKeyViaIndex(
|
| + &transaction2, high_database_id, high_object_store_id,
|
| + invalid_high_index_id, index_key, &new_primary_key);
|
| + EXPECT_FALSE(s.ok());
|
| +
|
| + s = backing_store->GetPrimaryKeyViaIndex(
|
| + &transaction2, high_database_id, high_object_store_id,
|
| + high_index_id, index_key, &new_primary_key);
|
| + EXPECT_TRUE(s.ok());
|
| + EXPECT_TRUE(new_primary_key->Equals(key1));
|
| +
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction2.CommitPhaseTwo().ok());
|
| + }
|
| + },
|
| + base::Unretained(backing_store()), key1_, key2_, value1_));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| // Make sure that other invalid ids do not crash.
|
| TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
|
| - // valid ids for use when testing invalid ids
|
| - const int64_t database_id = 1;
|
| - const int64_t object_store_id = 1;
|
| - const int64_t index_id = kMinimumIndexId;
|
| - const int64_t invalid_low_index_id =
|
| - 19; // index_ids must be > kMinimumIndexId
|
| -
|
| - IndexedDBValue result_value;
|
| -
|
| - IndexedDBBackingStore::Transaction transaction1(backing_store_.get());
|
| - transaction1.Begin();
|
| -
|
| - std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| - IndexedDBBackingStore::RecordIdentifier record;
|
| - leveldb::Status s = backing_store_->PutRecord(&transaction1, database_id,
|
| - KeyPrefix::kInvalidId, key1_,
|
| - &value1_, &handles, &record);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->PutRecord(&transaction1, database_id, 0, key1_, &value1_,
|
| - &handles, &record);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->PutRecord(&transaction1, KeyPrefix::kInvalidId,
|
| - object_store_id, key1_, &value1_, &handles,
|
| - &record);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->PutRecord(&transaction1, 0, object_store_id, key1_,
|
| - &value1_, &handles, &record);
|
| - EXPECT_FALSE(s.ok());
|
| -
|
| - s = backing_store_->GetRecord(&transaction1, database_id,
|
| - KeyPrefix::kInvalidId, key1_, &result_value);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->GetRecord(&transaction1, database_id, 0, key1_,
|
| - &result_value);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->GetRecord(&transaction1, KeyPrefix::kInvalidId,
|
| - object_store_id, key1_, &result_value);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->GetRecord(&transaction1, 0, object_store_id, key1_,
|
| - &result_value);
|
| - EXPECT_FALSE(s.ok());
|
| -
|
| - std::unique_ptr<IndexedDBKey> new_primary_key;
|
| - s = backing_store_->GetPrimaryKeyViaIndex(
|
| - &transaction1, database_id, object_store_id, KeyPrefix::kInvalidId, key1_,
|
| - &new_primary_key);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->GetPrimaryKeyViaIndex(
|
| - &transaction1, database_id, object_store_id, invalid_low_index_id, key1_,
|
| - &new_primary_key);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->GetPrimaryKeyViaIndex(
|
| - &transaction1, database_id, object_store_id, 0, key1_, &new_primary_key);
|
| - EXPECT_FALSE(s.ok());
|
| -
|
| - s = backing_store_->GetPrimaryKeyViaIndex(
|
| - &transaction1, KeyPrefix::kInvalidId, object_store_id, index_id, key1_,
|
| - &new_primary_key);
|
| - EXPECT_FALSE(s.ok());
|
| - s = backing_store_->GetPrimaryKeyViaIndex(&transaction1, database_id,
|
| - KeyPrefix::kInvalidId, index_id,
|
| - key1_, &new_primary_key);
|
| - EXPECT_FALSE(s.ok());
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStore* backing_store, IndexedDBKey key,
|
| + IndexedDBValue value) {
|
| + // valid ids for use when testing invalid ids
|
| + const int64_t database_id = 1;
|
| + const int64_t object_store_id = 1;
|
| + const int64_t index_id = kMinimumIndexId;
|
| + // index_ids must be > kMinimumIndexId
|
| + const int64_t invalid_low_index_id = 19;
|
| + IndexedDBValue result_value;
|
| +
|
| + IndexedDBBackingStore::Transaction transaction1(backing_store);
|
| + transaction1.Begin();
|
| +
|
| + std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
|
| + IndexedDBBackingStore::RecordIdentifier record;
|
| + leveldb::Status s = backing_store->PutRecord(
|
| + &transaction1, database_id, KeyPrefix::kInvalidId, key, &value,
|
| + &handles, &record);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->PutRecord(&transaction1, database_id, 0, key,
|
| + &value, &handles, &record);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->PutRecord(&transaction1, KeyPrefix::kInvalidId,
|
| + object_store_id, key, &value, &handles,
|
| + &record);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->PutRecord(&transaction1, 0, object_store_id, key,
|
| + &value, &handles, &record);
|
| + EXPECT_FALSE(s.ok());
|
| +
|
| + s = backing_store->GetRecord(&transaction1, database_id,
|
| + KeyPrefix::kInvalidId, key,
|
| + &result_value);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->GetRecord(&transaction1, database_id, 0, key,
|
| + &result_value);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->GetRecord(&transaction1, KeyPrefix::kInvalidId,
|
| + object_store_id, key, &result_value);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->GetRecord(&transaction1, 0, object_store_id, key,
|
| + &result_value);
|
| + EXPECT_FALSE(s.ok());
|
| +
|
| + std::unique_ptr<IndexedDBKey> new_primary_key;
|
| + s = backing_store->GetPrimaryKeyViaIndex(
|
| + &transaction1, database_id, object_store_id,
|
| + KeyPrefix::kInvalidId, key, &new_primary_key);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->GetPrimaryKeyViaIndex(
|
| + &transaction1, database_id, object_store_id,
|
| + invalid_low_index_id, key, &new_primary_key);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->GetPrimaryKeyViaIndex(&transaction1, database_id,
|
| + object_store_id, 0, key,
|
| + &new_primary_key);
|
| + EXPECT_FALSE(s.ok());
|
| +
|
| + s = backing_store->GetPrimaryKeyViaIndex(
|
| + &transaction1, KeyPrefix::kInvalidId, object_store_id, index_id,
|
| + key, &new_primary_key);
|
| + EXPECT_FALSE(s.ok());
|
| + s = backing_store->GetPrimaryKeyViaIndex(
|
| + &transaction1, database_id, KeyPrefix::kInvalidId, index_id,
|
| + key, &new_primary_key);
|
| + EXPECT_FALSE(s.ok());
|
| + },
|
| + base::Unretained(backing_store()), key1_, value1_));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
|
| - const base::string16 database_name(ASCIIToUTF16("db1"));
|
| - int64_t database_id;
|
| - const int64_t version = 9;
|
| -
|
| - const int64_t object_store_id = 99;
|
| - const base::string16 object_store_name(ASCIIToUTF16("object_store1"));
|
| - const bool auto_increment = true;
|
| - const IndexedDBKeyPath object_store_key_path(
|
| - ASCIIToUTF16("object_store_key"));
|
| -
|
| - const int64_t index_id = 999;
|
| - const base::string16 index_name(ASCIIToUTF16("index1"));
|
| - const bool unique = true;
|
| - const bool multi_entry = true;
|
| - const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key"));
|
| -
|
| - {
|
| - leveldb::Status s = backing_store_->CreateIDBDatabaseMetaData(
|
| - database_name, version, &database_id);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_GT(database_id, 0);
|
| -
|
| - IndexedDBBackingStore::Transaction transaction(backing_store_.get());
|
| - transaction.Begin();
|
| -
|
| - s = backing_store_->CreateObjectStore(&transaction,
|
| - database_id,
|
| - object_store_id,
|
| - object_store_name,
|
| - object_store_key_path,
|
| - auto_increment);
|
| - EXPECT_TRUE(s.ok());
|
| -
|
| - s = backing_store_->CreateIndex(&transaction,
|
| - database_id,
|
| - object_store_id,
|
| - index_id,
|
| - index_name,
|
| - index_key_path,
|
| - unique,
|
| - multi_entry);
|
| - EXPECT_TRUE(s.ok());
|
| -
|
| - scoped_refptr<TestCallback> callback(new TestCallback());
|
| - s = transaction.CommitPhaseOne(callback);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_TRUE(callback->called);
|
| - EXPECT_TRUE(callback->succeeded);
|
| - s = transaction.CommitPhaseTwo();
|
| - EXPECT_TRUE(s.ok());
|
| - }
|
| -
|
| - {
|
| - IndexedDBDatabaseMetadata database;
|
| - bool found;
|
| - leveldb::Status s = backing_store_->GetIDBDatabaseMetaData(
|
| - database_name, &database, &found);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_TRUE(found);
|
| -
|
| - // database.name is not filled in by the implementation.
|
| - EXPECT_EQ(version, database.version);
|
| - EXPECT_EQ(database_id, database.id);
|
| -
|
| - s = backing_store_->GetObjectStores(database.id, &database.object_stores);
|
| - EXPECT_TRUE(s.ok());
|
| -
|
| - EXPECT_EQ(1UL, database.object_stores.size());
|
| - IndexedDBObjectStoreMetadata object_store =
|
| - database.object_stores[object_store_id];
|
| - EXPECT_EQ(object_store_name, object_store.name);
|
| - EXPECT_EQ(object_store_key_path, object_store.key_path);
|
| - EXPECT_EQ(auto_increment, object_store.auto_increment);
|
| -
|
| - EXPECT_EQ(1UL, object_store.indexes.size());
|
| - IndexedDBIndexMetadata index = object_store.indexes[index_id];
|
| - EXPECT_EQ(index_name, index.name);
|
| - EXPECT_EQ(index_key_path, index.key_path);
|
| - EXPECT_EQ(unique, index.unique);
|
| - EXPECT_EQ(multi_entry, index.multi_entry);
|
| - }
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(
|
| + [](IndexedDBBackingStore* backing_store) {
|
| + const base::string16 database_name(ASCIIToUTF16("db1"));
|
| + int64_t database_id;
|
| + const int64_t version = 9;
|
| +
|
| + const int64_t object_store_id = 99;
|
| + const base::string16 object_store_name(
|
| + ASCIIToUTF16("object_store1"));
|
| + const bool auto_increment = true;
|
| + const IndexedDBKeyPath object_store_key_path(
|
| + ASCIIToUTF16("object_store_key"));
|
| +
|
| + const int64_t index_id = 999;
|
| + const base::string16 index_name(ASCIIToUTF16("index1"));
|
| + const bool unique = true;
|
| + const bool multi_entry = true;
|
| + const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key"));
|
| +
|
| + {
|
| + leveldb::Status s = backing_store->CreateIDBDatabaseMetaData(
|
| + database_name, version, &database_id);
|
| + EXPECT_TRUE(s.ok());
|
| + EXPECT_GT(database_id, 0);
|
| +
|
| + IndexedDBBackingStore::Transaction transaction(backing_store);
|
| + transaction.Begin();
|
| +
|
| + s = backing_store->CreateObjectStore(
|
| + &transaction, database_id, object_store_id, object_store_name,
|
| + object_store_key_path, auto_increment);
|
| + EXPECT_TRUE(s.ok());
|
| +
|
| + s = backing_store->CreateIndex(
|
| + &transaction, database_id, object_store_id, index_id,
|
| + index_name, index_key_path, unique, multi_entry);
|
| + EXPECT_TRUE(s.ok());
|
| +
|
| + scoped_refptr<TestCallback> callback(
|
| + base::MakeRefCounted<TestCallback>());
|
| + EXPECT_TRUE(transaction.CommitPhaseOne(callback).ok());
|
| + EXPECT_TRUE(callback->called);
|
| + EXPECT_TRUE(callback->succeeded);
|
| + EXPECT_TRUE(transaction.CommitPhaseTwo().ok());
|
| + }
|
| +
|
| + {
|
| + IndexedDBDatabaseMetadata database;
|
| + bool found;
|
| + leveldb::Status s = backing_store->GetIDBDatabaseMetaData(
|
| + database_name, &database, &found);
|
| + EXPECT_TRUE(s.ok());
|
| + EXPECT_TRUE(found);
|
| +
|
| + // database.name is not filled in by the implementation.
|
| + EXPECT_EQ(version, database.version);
|
| + EXPECT_EQ(database_id, database.id);
|
| +
|
| + s = backing_store->GetObjectStores(database.id,
|
| + &database.object_stores);
|
| + EXPECT_TRUE(s.ok());
|
| +
|
| + EXPECT_EQ(1UL, database.object_stores.size());
|
| + IndexedDBObjectStoreMetadata object_store =
|
| + database.object_stores[object_store_id];
|
| + EXPECT_EQ(object_store_name, object_store.name);
|
| + EXPECT_EQ(object_store_key_path, object_store.key_path);
|
| + EXPECT_EQ(auto_increment, object_store.auto_increment);
|
| +
|
| + EXPECT_EQ(1UL, object_store.indexes.size());
|
| + IndexedDBIndexMetadata index = object_store.indexes[index_id];
|
| + EXPECT_EQ(index_name, index.name);
|
| + EXPECT_EQ(index_key_path, index.key_path);
|
| + EXPECT_EQ(unique, index.unique);
|
| + EXPECT_EQ(multi_entry, index.multi_entry);
|
| + }
|
| + },
|
| + base::Unretained(backing_store())));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| TEST_F(IndexedDBBackingStoreTest, GetDatabaseNames) {
|
| - const base::string16 db1_name(ASCIIToUTF16("db1"));
|
| - const int64_t db1_version = 1LL;
|
| - int64_t db1_id;
|
| -
|
| - // Database records with DEFAULT_VERSION represent stale data,
|
| - // and should not be enumerated.
|
| - const base::string16 db2_name(ASCIIToUTF16("db2"));
|
| - const int64_t db2_version = IndexedDBDatabaseMetadata::DEFAULT_VERSION;
|
| - int64_t db2_id;
|
| -
|
| - leveldb::Status s =
|
| - backing_store_->CreateIDBDatabaseMetaData(db1_name, db1_version, &db1_id);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_GT(db1_id, 0LL);
|
| -
|
| - s = backing_store_->CreateIDBDatabaseMetaData(db2_name, db2_version, &db2_id);
|
| - EXPECT_TRUE(s.ok());
|
| - EXPECT_GT(db2_id, db1_id);
|
| -
|
| - std::vector<base::string16> names = backing_store_->GetDatabaseNames(&s);
|
| - EXPECT_TRUE(s.ok());
|
| - ASSERT_EQ(1U, names.size());
|
| - EXPECT_EQ(db1_name, names[0]);
|
| + idb_context_->TaskRunner()->PostTask(
|
| + FROM_HERE, base::BindOnce(
|
| + [](IndexedDBBackingStore* backing_store) {
|
| + const base::string16 db1_name(ASCIIToUTF16("db1"));
|
| + const int64_t db1_version = 1LL;
|
| + int64_t db1_id;
|
| +
|
| + // Database records with DEFAULT_VERSION represent
|
| + // stale data, and should not be enumerated.
|
| + const base::string16 db2_name(ASCIIToUTF16("db2"));
|
| + const int64_t db2_version =
|
| + IndexedDBDatabaseMetadata::DEFAULT_VERSION;
|
| + int64_t db2_id;
|
| +
|
| + leveldb::Status s =
|
| + backing_store->CreateIDBDatabaseMetaData(
|
| + db1_name, db1_version, &db1_id);
|
| + EXPECT_TRUE(s.ok());
|
| + EXPECT_GT(db1_id, 0LL);
|
| +
|
| + s = backing_store->CreateIDBDatabaseMetaData(
|
| + db2_name, db2_version, &db2_id);
|
| + EXPECT_TRUE(s.ok());
|
| + EXPECT_GT(db2_id, db1_id);
|
| +
|
| + std::vector<base::string16> names =
|
| + backing_store->GetDatabaseNames(&s);
|
| + EXPECT_TRUE(s.ok());
|
| + ASSERT_EQ(1U, names.size());
|
| + EXPECT_EQ(db1_name, names[0]);
|
| + },
|
| + base::Unretained(backing_store())));
|
| + RunAllBlockingPoolTasksUntilIdle();
|
| }
|
|
|
| } // namespace
|
|
|