| Index: blimp/net/blob_channel/blob_channel_receiver_unittest.cc
|
| diff --git a/blimp/net/blob_channel/blob_channel_receiver_unittest.cc b/blimp/net/blob_channel/blob_channel_receiver_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2e0b89e56db6b2cbd17bfacf03dced0210ade07c
|
| --- /dev/null
|
| +++ b/blimp/net/blob_channel/blob_channel_receiver_unittest.cc
|
| @@ -0,0 +1,162 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <algorithm>
|
| +#include <memory>
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "blimp/common/blob_cache/mock_blob_cache.h"
|
| +#include "blimp/net/blob_channel/blob_channel_receiver.h"
|
| +#include "blimp/net/blob_channel/mock_blob_channel_bindings.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace blimp {
|
| +namespace {
|
| +
|
| +using testing::_;
|
| +using testing::Pointee;
|
| +using testing::Return;
|
| +using testing::SaveArg;
|
| +
|
| +const char kBlobId1[] = "blob-1";
|
| +const char kBlobId2[] = "blob-2";
|
| +const char kBlobPayload1[] = "blob-1-payload";
|
| +const char kBlobPayload2[] = "blob-2-payload";
|
| +
|
| +// Helper function for creating a cache payload vector from a string.
|
| +scoped_refptr<RefCountedVector> CreatePayload(const std::string& input) {
|
| + scoped_refptr<RefCountedVector> output(new RefCountedVector);
|
| + output->data.assign(input.begin(), input.end());
|
| + return output;
|
| +}
|
| +
|
| +MATCHER_P(RefCountedVectorsEqual, expected, "") {
|
| + return expected->data == arg->data;
|
| +}
|
| +
|
| +class BlobChannelReceiverTest : public testing::Test {
|
| + public:
|
| + BlobChannelReceiverTest() {}
|
| + ~BlobChannelReceiverTest() override {}
|
| +
|
| + void SetUp() override {
|
| + EXPECT_CALL(mock_bindings_, SetDelegate(_))
|
| + .WillOnce(SaveArg<0>(&delegate_));
|
| + blob_receiver_.reset(
|
| + new BlobChannelReceiver(&mock_cache_, &mock_bindings_));
|
| + ASSERT_NE(nullptr, delegate_);
|
| + }
|
| +
|
| + MOCK_METHOD2(OnBlobReceived,
|
| + void(const std::string&, scoped_refptr<RefCountedVector>));
|
| +
|
| + testing::StrictMock<MockBlobReceiverBindings> mock_bindings_;
|
| + testing::StrictMock<MockBlobCache> mock_cache_;
|
| + std::unique_ptr<BlobChannelReceiver> blob_receiver_;
|
| + BlobReceiverBindings::Delegate* delegate_ = nullptr;
|
| +};
|
| +
|
| +TEST_F(BlobChannelReceiverTest, TestGetSync) {
|
| + auto payload1 = CreatePayload(kBlobPayload1);
|
| + EXPECT_CALL(mock_cache_, Contains(kBlobId1)).WillOnce(Return(true));
|
| + EXPECT_CALL(mock_cache_, Get(kBlobId1)).WillOnce(Return(payload1));
|
| + auto result = blob_receiver_->Get(
|
| + kBlobId1, BlobChannelReceiver::BlobReceivedCallback());
|
| + ASSERT_NE(result.get(), nullptr);
|
| + EXPECT_EQ(result->data, payload1->data);
|
| +
|
| + auto payload2 = CreatePayload(kBlobPayload2);
|
| + EXPECT_CALL(mock_cache_, Contains(kBlobId2)).WillOnce(Return(true));
|
| + EXPECT_CALL(mock_cache_, Get(kBlobId2)).WillOnce(Return(payload2));
|
| + result = blob_receiver_->Get(kBlobId2,
|
| + BlobChannelReceiver::BlobReceivedCallback());
|
| + ASSERT_NE(result.get(), nullptr);
|
| + EXPECT_EQ(result->data, payload2->data);
|
| +}
|
| +
|
| +// Test concurrent async reads across multiple blobs.
|
| +// kBlobId1: Get() called twice.
|
| +// kBlobId2: Get() called once.
|
| +TEST_F(BlobChannelReceiverTest, TestGetAsync) {
|
| + auto payload1 = CreatePayload(kBlobPayload1);
|
| + auto payload2 = CreatePayload(kBlobPayload2);
|
| +
|
| + EXPECT_CALL(mock_cache_, Contains(kBlobId1))
|
| + .Times(3)
|
| + .WillRepeatedly(Return(false));
|
| + EXPECT_CALL(mock_bindings_, Get(kBlobId1));
|
| + EXPECT_CALL(mock_cache_, Contains(kBlobId2))
|
| + .Times(2)
|
| + .WillRepeatedly(Return(false));
|
| + EXPECT_CALL(mock_bindings_, Get(kBlobId2));
|
| +
|
| + // Async Get() operations are started.
|
| + ASSERT_EQ(
|
| + nullptr,
|
| + blob_receiver_
|
| + ->Get(kBlobId1, base::Bind(&BlobChannelReceiverTest::OnBlobReceived,
|
| + base::Unretained(this)))
|
| + .get());
|
| + ASSERT_EQ(
|
| + nullptr,
|
| + blob_receiver_
|
| + ->Get(kBlobId1, base::Bind(&BlobChannelReceiverTest::OnBlobReceived,
|
| + base::Unretained(this)))
|
| + .get());
|
| + ASSERT_EQ(
|
| + nullptr,
|
| + blob_receiver_
|
| + ->Get(kBlobId2, base::Bind(&BlobChannelReceiverTest::OnBlobReceived,
|
| + base::Unretained(this)))
|
| + .get());
|
| +
|
| + // Blobs start arriving asynchronously. Verify that our read callback is hit.
|
| + EXPECT_CALL(mock_cache_, Put(kBlobId1, RefCountedVectorsEqual(payload1)));
|
| + EXPECT_CALL(mock_cache_, Put(kBlobId2, RefCountedVectorsEqual(payload2)));
|
| + EXPECT_CALL(*this, OnBlobReceived(kBlobId1, RefCountedVectorsEqual(payload1)))
|
| + .Times(2);
|
| + EXPECT_CALL(*this,
|
| + OnBlobReceived(kBlobId2, RefCountedVectorsEqual(payload2)));
|
| + delegate_->OnBlobReceived(
|
| + kBlobId1, base::WrapUnique(new std::vector<uint8_t>(payload1->data)));
|
| + delegate_->OnBlobReceived(
|
| + kBlobId2, base::WrapUnique(new std::vector<uint8_t>(payload2->data)));
|
| +
|
| + // Pretend that the cache was evicted. See if another request is issued.
|
| + EXPECT_CALL(mock_cache_, Contains(kBlobId1)).WillOnce(Return(false));
|
| + EXPECT_CALL(mock_bindings_, Get(kBlobId1));
|
| + ASSERT_EQ(
|
| + nullptr,
|
| + blob_receiver_
|
| + ->Get(kBlobId1, base::Bind(&BlobChannelReceiverTest::OnBlobReceived,
|
| + base::Unretained(this)))
|
| + .get());
|
| +}
|
| +
|
| +TEST_F(BlobChannelReceiverTest, TestGetRedundantArrival) {
|
| + auto payload = CreatePayload(kBlobPayload1);
|
| +
|
| + EXPECT_CALL(mock_cache_, Contains(kBlobId1))
|
| + .WillOnce(Return(false))
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(mock_bindings_, Get(kBlobId1));
|
| +
|
| + // Async Get() operations are started.
|
| + ASSERT_EQ(
|
| + nullptr,
|
| + blob_receiver_
|
| + ->Get(kBlobId1, base::Bind(&BlobChannelReceiverTest::OnBlobReceived,
|
| + base::Unretained(this)))
|
| + .get());
|
| +
|
| + // Blobs start arriving asynchronously. Verify that our read callback is hit.
|
| + EXPECT_CALL(mock_cache_, Put(kBlobId1, RefCountedVectorsEqual(payload)));
|
| + EXPECT_CALL(*this, OnBlobReceived(kBlobId1, RefCountedVectorsEqual(payload)));
|
| + delegate_->OnBlobReceived(
|
| + kBlobId1, base::WrapUnique(new std::vector<uint8_t>(payload->data)));
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace blimp
|
|
|