| Index: content/child/indexed_db/webidbcursor_impl_unittest.cc
|
| diff --git a/content/child/indexed_db/webidbcursor_impl_unittest.cc b/content/child/indexed_db/webidbcursor_impl_unittest.cc
|
| index 83b2110ac14140f1c4b927e7aad776f6992bc806..55dfe57995df4c1bd75dc71d6510c58a3ec83445 100644
|
| --- a/content/child/indexed_db/webidbcursor_impl_unittest.cc
|
| +++ b/content/child/indexed_db/webidbcursor_impl_unittest.cc
|
| @@ -11,14 +11,14 @@
|
|
|
| #include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/run_loop.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "base/values.h"
|
| -#include "content/child/indexed_db/indexed_db_dispatcher.h"
|
| #include "content/child/indexed_db/indexed_db_key_builders.h"
|
| #include "content/child/indexed_db/mock_webidbcallbacks.h"
|
| #include "content/child/thread_safe_sender.h"
|
| #include "content/common/indexed_db/indexed_db_key.h"
|
| -#include "ipc/ipc_sync_message_filter.h"
|
| +#include "mojo/public/cpp/bindings/associated_binding.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "third_party/WebKit/public/platform/WebData.h"
|
|
|
| @@ -29,59 +29,50 @@ using blink::WebIDBKey;
|
| using blink::WebIDBKeyTypeNumber;
|
| using blink::WebIDBValue;
|
| using blink::WebVector;
|
| +using indexed_db::mojom::Cursor;
|
| using testing::StrictMock;
|
|
|
| namespace content {
|
|
|
| namespace {
|
|
|
| -class MockDispatcher : public IndexedDBDispatcher {
|
| +class MockCursorImpl : public Cursor {
|
| public:
|
| - explicit MockDispatcher(ThreadSafeSender* thread_safe_sender)
|
| - : IndexedDBDispatcher(thread_safe_sender),
|
| - prefetch_calls_(0),
|
| - last_prefetch_count_(0),
|
| - reset_calls_(0),
|
| - last_used_count_(0),
|
| - advance_calls_(0),
|
| - continue_calls_(0),
|
| - destroyed_cursor_id_(0) {}
|
| -
|
| - void RequestIDBCursorPrefetch(int n,
|
| - WebIDBCallbacks* callbacks,
|
| - int32_t ipc_cursor_id) override {
|
| + explicit MockCursorImpl(indexed_db::mojom::CursorAssociatedRequest request)
|
| + : binding_(this, std::move(request)) {
|
| + binding_.set_connection_error_handler(
|
| + base::Bind(&MockCursorImpl::CursorDestroyed, base::Unretained(this)));
|
| + }
|
| +
|
| + void Prefetch(
|
| + int32_t count,
|
| + ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks) override {
|
| ++prefetch_calls_;
|
| - last_prefetch_count_ = n;
|
| - callbacks_.reset(callbacks);
|
| + last_prefetch_count_ = count;
|
| }
|
|
|
| - void RequestIDBCursorPrefetchReset(int used_prefetches,
|
| - int unused_prefetches,
|
| - int32_t ipc_cursor_id) override {
|
| + void PrefetchReset(
|
| + int32_t used_prefetches,
|
| + int32_t unused_prefetches,
|
| + const std::vector<std::string>& unused_blob_uuids) override {
|
| ++reset_calls_;
|
| last_used_count_ = used_prefetches;
|
| }
|
|
|
| - void RequestIDBCursorAdvance(unsigned long count,
|
| - WebIDBCallbacks* callbacks,
|
| - int32_t ipc_cursor_id,
|
| - int64_t transaction_id) override {
|
| + void Advance(
|
| + uint32_t count,
|
| + ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks) override {
|
| ++advance_calls_;
|
| - callbacks_.reset(callbacks);
|
| }
|
|
|
| - void RequestIDBCursorContinue(const IndexedDBKey& key,
|
| - const IndexedDBKey& primary_key,
|
| - WebIDBCallbacks* callbacks,
|
| - int32_t ipc_cursor_id,
|
| - int64_t transaction_id) override {
|
| + void Continue(
|
| + const IndexedDBKey& key,
|
| + const IndexedDBKey& primary_key,
|
| + ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks) override {
|
| ++continue_calls_;
|
| - callbacks_.reset(callbacks);
|
| }
|
|
|
| - void CursorDestroyed(int32_t ipc_cursor_id) override {
|
| - destroyed_cursor_id_ = ipc_cursor_id;
|
| - }
|
| + void CursorDestroyed() { destroyed_ = true; }
|
|
|
| int prefetch_calls() { return prefetch_calls_; }
|
| int last_prefetch_count() { return last_prefetch_count_; }
|
| @@ -89,17 +80,18 @@ class MockDispatcher : public IndexedDBDispatcher {
|
| int last_used_count() { return last_used_count_; }
|
| int advance_calls() { return advance_calls_; }
|
| int continue_calls() { return continue_calls_; }
|
| - int32_t destroyed_cursor_id() { return destroyed_cursor_id_; }
|
| + bool destroyed() { return destroyed_; }
|
|
|
| private:
|
| - int prefetch_calls_;
|
| - int last_prefetch_count_;
|
| - int reset_calls_;
|
| - int last_used_count_;
|
| - int advance_calls_;
|
| - int continue_calls_;
|
| - int32_t destroyed_cursor_id_;
|
| - std::unique_ptr<WebIDBCallbacks> callbacks_;
|
| + int prefetch_calls_ = 0;
|
| + int last_prefetch_count_ = 0;
|
| + int reset_calls_ = 0;
|
| + int last_used_count_ = 0;
|
| + int advance_calls_ = 0;
|
| + int continue_calls_ = 0;
|
| + bool destroyed_ = false;
|
| +
|
| + mojo::AssociatedBinding<Cursor> binding_;
|
| };
|
|
|
| class MockContinueCallbacks : public StrictMock<MockWebIDBCallbacks> {
|
| @@ -122,126 +114,113 @@ class MockContinueCallbacks : public StrictMock<MockWebIDBCallbacks> {
|
| WebVector<WebBlobInfo>* web_blob_info_;
|
| };
|
|
|
| -class MockSyncMessageFilter : public IPC::SyncMessageFilter {
|
| - public:
|
| - MockSyncMessageFilter() : SyncMessageFilter(nullptr) {}
|
| -
|
| - private:
|
| - ~MockSyncMessageFilter() override {}
|
| -};
|
| -
|
| } // namespace
|
|
|
| class WebIDBCursorImplTest : public testing::Test {
|
| public:
|
| WebIDBCursorImplTest() {
|
| null_key_.assignNull();
|
| - thread_safe_sender_ = new ThreadSafeSender(
|
| - base::ThreadTaskRunnerHandle::Get(), new MockSyncMessageFilter);
|
| - dispatcher_ = base::MakeUnique<MockDispatcher>(thread_safe_sender_.get());
|
| + indexed_db::mojom::CursorAssociatedPtr ptr;
|
| + mock_cursor_ =
|
| + base::MakeUnique<MockCursorImpl>(mojo::GetProxyForTesting(&ptr));
|
| + cursor_ = base::MakeUnique<WebIDBCursorImpl>(
|
| + ptr.PassInterface(), 1, base::ThreadTaskRunnerHandle::Get());
|
| }
|
|
|
| protected:
|
| base::MessageLoop message_loop_;
|
| WebIDBKey null_key_;
|
| - scoped_refptr<ThreadSafeSender> thread_safe_sender_;
|
| - std::unique_ptr<MockDispatcher> dispatcher_;
|
| + std::unique_ptr<WebIDBCursorImpl> cursor_;
|
| + std::unique_ptr<MockCursorImpl> mock_cursor_;
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(WebIDBCursorImplTest);
|
| };
|
|
|
| TEST_F(WebIDBCursorImplTest, PrefetchTest) {
|
| - const int64_t transaction_id = 1;
|
| - {
|
| - WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
|
| - transaction_id,
|
| - thread_safe_sender_.get());
|
| -
|
| - // Call continue() until prefetching should kick in.
|
| - int continue_calls = 0;
|
| - EXPECT_EQ(dispatcher_->continue_calls(), 0);
|
| - for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks());
|
| - EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
|
| - EXPECT_EQ(0, dispatcher_->prefetch_calls());
|
| - }
|
| + // Call continue() until prefetching should kick in.
|
| + int continue_calls = 0;
|
| + EXPECT_EQ(mock_cursor_->continue_calls(), 0);
|
| + for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(++continue_calls, mock_cursor_->continue_calls());
|
| + EXPECT_EQ(0, mock_cursor_->prefetch_calls());
|
| + }
|
|
|
| - // Do enough repetitions to verify that the count grows each time,
|
| - // but not so many that the maximum limit is hit.
|
| - const int kPrefetchRepetitions = 5;
|
| -
|
| - int expected_key = 0;
|
| - int last_prefetch_count = 0;
|
| - for (int repetitions = 0; repetitions < kPrefetchRepetitions;
|
| - ++repetitions) {
|
| - // Initiate the prefetch
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks());
|
| - EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
|
| - EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
|
| -
|
| - // Verify that the requested count has increased since last time.
|
| - int prefetch_count = dispatcher_->last_prefetch_count();
|
| - EXPECT_GT(prefetch_count, last_prefetch_count);
|
| - last_prefetch_count = prefetch_count;
|
| -
|
| - // Fill the prefetch cache as requested.
|
| - std::vector<IndexedDBKey> keys;
|
| - std::vector<IndexedDBKey> primary_keys(prefetch_count);
|
| - std::vector<WebIDBValue> values(prefetch_count);
|
| - for (int i = 0; i < prefetch_count; ++i) {
|
| - keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
|
| - values[i].webBlobInfo =
|
| - WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i));
|
| - }
|
| - cursor.SetPrefetchData(keys, primary_keys, values);
|
| -
|
| - // Note that the real dispatcher would call cursor->CachedContinue()
|
| - // immediately after cursor->SetPrefetchData() to service the request
|
| - // that initiated the prefetch.
|
| -
|
| - // Verify that the cache is used for subsequent continue() calls.
|
| - for (int i = 0; i < prefetch_count; ++i) {
|
| - IndexedDBKey key;
|
| - WebVector<WebBlobInfo> web_blob_info;
|
| - cursor.continueFunction(
|
| - null_key_, new MockContinueCallbacks(&key, &web_blob_info));
|
| - EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
|
| - EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
|
| -
|
| - EXPECT_EQ(WebIDBKeyTypeNumber, key.type());
|
| - EXPECT_EQ(expected_key, static_cast<int>(web_blob_info.size()));
|
| - EXPECT_EQ(expected_key++, key.number());
|
| - }
|
| + // Do enough repetitions to verify that the count grows each time,
|
| + // but not so many that the maximum limit is hit.
|
| + const int kPrefetchRepetitions = 5;
|
| +
|
| + int expected_key = 0;
|
| + int last_prefetch_count = 0;
|
| + for (int repetitions = 0; repetitions < kPrefetchRepetitions; ++repetitions) {
|
| + // Initiate the prefetch
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(continue_calls, mock_cursor_->continue_calls());
|
| + EXPECT_EQ(repetitions + 1, mock_cursor_->prefetch_calls());
|
| +
|
| + // Verify that the requested count has increased since last time.
|
| + int prefetch_count = mock_cursor_->last_prefetch_count();
|
| + EXPECT_GT(prefetch_count, last_prefetch_count);
|
| + last_prefetch_count = prefetch_count;
|
| +
|
| + // Fill the prefetch cache as requested.
|
| + std::vector<IndexedDBKey> keys;
|
| + std::vector<IndexedDBKey> primary_keys(prefetch_count);
|
| + std::vector<WebIDBValue> values(prefetch_count);
|
| + for (int i = 0; i < prefetch_count; ++i) {
|
| + keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
|
| + values[i].webBlobInfo =
|
| + WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i));
|
| + }
|
| + cursor_->SetPrefetchData(keys, primary_keys, values);
|
| +
|
| + // Note that the real dispatcher would call cursor->CachedContinue()
|
| + // immediately after cursor->SetPrefetchData() to service the request
|
| + // that initiated the prefetch.
|
| +
|
| + // Verify that the cache is used for subsequent continue() calls.
|
| + for (int i = 0; i < prefetch_count; ++i) {
|
| + IndexedDBKey key;
|
| + WebVector<WebBlobInfo> web_blob_info;
|
| + cursor_->continueFunction(
|
| + null_key_, new MockContinueCallbacks(&key, &web_blob_info));
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(continue_calls, mock_cursor_->continue_calls());
|
| + EXPECT_EQ(repetitions + 1, mock_cursor_->prefetch_calls());
|
| +
|
| + EXPECT_EQ(WebIDBKeyTypeNumber, key.type());
|
| + EXPECT_EQ(expected_key, static_cast<int>(web_blob_info.size()));
|
| + EXPECT_EQ(expected_key++, key.number());
|
| }
|
| }
|
|
|
| - EXPECT_EQ(dispatcher_->destroyed_cursor_id(),
|
| - WebIDBCursorImpl::kInvalidCursorId);
|
| + cursor_.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(mock_cursor_->destroyed());
|
| }
|
|
|
| TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
|
| - const int64_t transaction_id = 1;
|
| - WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
|
| - transaction_id,
|
| - thread_safe_sender_.get());
|
| -
|
| // Call continue() until prefetching should kick in.
|
| - EXPECT_EQ(0, dispatcher_->continue_calls());
|
| + EXPECT_EQ(0, mock_cursor_->continue_calls());
|
| for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks());
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks());
|
| }
|
| - EXPECT_EQ(0, dispatcher_->prefetch_calls());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(0, mock_cursor_->prefetch_calls());
|
|
|
| // Initiate the prefetch
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks());
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks());
|
|
|
| - EXPECT_EQ(1, dispatcher_->prefetch_calls());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1, mock_cursor_->prefetch_calls());
|
| EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
|
| - dispatcher_->continue_calls());
|
| - EXPECT_EQ(0, dispatcher_->advance_calls());
|
| + mock_cursor_->continue_calls());
|
| + EXPECT_EQ(0, mock_cursor_->advance_calls());
|
|
|
| - const int prefetch_count = dispatcher_->last_prefetch_count();
|
| + const int prefetch_count = mock_cursor_->last_prefetch_count();
|
|
|
| // Fill the prefetch cache as requested.
|
| int expected_key = 0;
|
| @@ -253,7 +232,7 @@ TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
|
| values[i].webBlobInfo =
|
| WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i));
|
| }
|
| - cursor.SetPrefetchData(keys, primary_keys, values);
|
| + cursor_->SetPrefetchData(keys, primary_keys, values);
|
|
|
| // Note that the real dispatcher would call cursor->CachedContinue()
|
| // immediately after cursor->SetPrefetchData() to service the request
|
| @@ -264,76 +243,89 @@ TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
|
|
|
| // IDBCursor.continue()
|
| IndexedDBKey key;
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks(&key));
|
| + base::RunLoop().RunUntilIdle();
|
| EXPECT_EQ(0, key.number());
|
|
|
| // IDBCursor.advance(1)
|
| - cursor.advance(1, new MockContinueCallbacks(&key));
|
| + cursor_->advance(1, new MockContinueCallbacks(&key));
|
| + base::RunLoop().RunUntilIdle();
|
| EXPECT_EQ(1, key.number());
|
|
|
| // IDBCursor.continue()
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks(&key));
|
| + base::RunLoop().RunUntilIdle();
|
| EXPECT_EQ(2, key.number());
|
|
|
| // IDBCursor.advance(2)
|
| - cursor.advance(2, new MockContinueCallbacks(&key));
|
| + cursor_->advance(2, new MockContinueCallbacks(&key));
|
| + base::RunLoop().RunUntilIdle();
|
| EXPECT_EQ(4, key.number());
|
|
|
| - EXPECT_EQ(0, dispatcher_->advance_calls());
|
| + EXPECT_EQ(0, mock_cursor_->advance_calls());
|
|
|
| // IDBCursor.advance(lots) - beyond the fetched amount
|
| - cursor.advance(WebIDBCursorImpl::kMaxPrefetchAmount,
|
| - new MockContinueCallbacks(&key));
|
| - EXPECT_EQ(1, dispatcher_->advance_calls());
|
| - EXPECT_EQ(1, dispatcher_->prefetch_calls());
|
| + cursor_->advance(WebIDBCursorImpl::kMaxPrefetchAmount,
|
| + new MockContinueCallbacks(&key));
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1, mock_cursor_->advance_calls());
|
| + EXPECT_EQ(1, mock_cursor_->prefetch_calls());
|
| EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
|
| - dispatcher_->continue_calls());
|
| + mock_cursor_->continue_calls());
|
| +
|
| + cursor_.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(mock_cursor_->destroyed());
|
| }
|
|
|
| TEST_F(WebIDBCursorImplTest, PrefetchReset) {
|
| - const int64_t transaction_id = 1;
|
| - WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
|
| - transaction_id,
|
| - thread_safe_sender_.get());
|
| -
|
| // Call continue() until prefetching should kick in.
|
| int continue_calls = 0;
|
| - EXPECT_EQ(dispatcher_->continue_calls(), 0);
|
| + EXPECT_EQ(mock_cursor_->continue_calls(), 0);
|
| for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks());
|
| - EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
|
| - EXPECT_EQ(0, dispatcher_->prefetch_calls());
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(++continue_calls, mock_cursor_->continue_calls());
|
| + EXPECT_EQ(0, mock_cursor_->prefetch_calls());
|
| }
|
|
|
| // Initiate the prefetch
|
| - cursor.continueFunction(null_key_, new MockContinueCallbacks());
|
| - EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
|
| - EXPECT_EQ(1, dispatcher_->prefetch_calls());
|
| - EXPECT_EQ(0, dispatcher_->reset_calls());
|
| + cursor_->continueFunction(null_key_, new MockContinueCallbacks());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(continue_calls, mock_cursor_->continue_calls());
|
| + EXPECT_EQ(1, mock_cursor_->prefetch_calls());
|
| + EXPECT_EQ(0, mock_cursor_->reset_calls());
|
|
|
| // Now invalidate it
|
| - cursor.ResetPrefetchCache();
|
| + cursor_->ResetPrefetchCache();
|
|
|
| // No reset should have been sent since nothing has been received yet.
|
| - EXPECT_EQ(0, dispatcher_->reset_calls());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(0, mock_cursor_->reset_calls());
|
|
|
| // Fill the prefetch cache as requested.
|
| - int prefetch_count = dispatcher_->last_prefetch_count();
|
| + int prefetch_count = mock_cursor_->last_prefetch_count();
|
| std::vector<IndexedDBKey> keys(prefetch_count);
|
| std::vector<IndexedDBKey> primary_keys(prefetch_count);
|
| std::vector<WebIDBValue> values(prefetch_count);
|
| - cursor.SetPrefetchData(keys, primary_keys, values);
|
| + cursor_->SetPrefetchData(keys, primary_keys, values);
|
|
|
| // No reset should have been sent since prefetch data hasn't been used.
|
| - EXPECT_EQ(0, dispatcher_->reset_calls());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(0, mock_cursor_->reset_calls());
|
|
|
| // The real dispatcher would call cursor->CachedContinue(), so do that:
|
| MockContinueCallbacks callbacks;
|
| - cursor.CachedContinue(&callbacks);
|
| + cursor_->CachedContinue(&callbacks);
|
|
|
| // Now the cursor should have reset the rest of the cache.
|
| - EXPECT_EQ(1, dispatcher_->reset_calls());
|
| - EXPECT_EQ(1, dispatcher_->last_used_count());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1, mock_cursor_->reset_calls());
|
| + EXPECT_EQ(1, mock_cursor_->last_used_count());
|
| +
|
| + cursor_.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(mock_cursor_->destroyed());
|
| }
|
|
|
| } // namespace content
|
|
|