| Index: extensions/browser/api/cast_channel/cast_transport_unittest.cc
|
| diff --git a/extensions/browser/api/cast_channel/cast_transport_unittest.cc b/extensions/browser/api/cast_channel/cast_transport_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bef17b0dfe96e216dfd91510bac61890855fa0de
|
| --- /dev/null
|
| +++ b/extensions/browser/api/cast_channel/cast_transport_unittest.cc
|
| @@ -0,0 +1,649 @@
|
| +// Copyright 2014 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 "extensions/browser/api/cast_channel/cast_transport.h"
|
| +
|
| +#include <stddef.h>
|
| +#include <queue>
|
| +
|
| +#include "base/test/simple_test_tick_clock.h"
|
| +#include "extensions/browser/api/cast_channel/cast_channel.pb.h"
|
| +#include "extensions/browser/api/cast_channel/cast_framer.h"
|
| +#include "extensions/browser/api/cast_channel/cast_transport.h"
|
| +#include "extensions/browser/api/cast_channel/logger.h"
|
| +#include "extensions/browser/api/cast_channel/logger_util.h"
|
| +#include "net/base/capturing_net_log.h"
|
| +#include "net/base/completion_callback.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using testing::_;
|
| +using testing::DoAll;
|
| +using testing::InSequence;
|
| +using testing::Invoke;
|
| +using testing::NotNull;
|
| +using testing::Return;
|
| +using testing::WithArg;
|
| +
|
| +namespace extensions {
|
| +namespace core_api {
|
| +namespace cast_channel {
|
| +namespace {
|
| +// Mockable placeholder for write completion events.
|
| +class CompleteHandler {
|
| + public:
|
| + CompleteHandler() {}
|
| + MOCK_METHOD1(Complete, void(int result));
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(CompleteHandler);
|
| +};
|
| +
|
| +// Creates a CastMessage proto with the bare minimum required fields set.
|
| +CastMessage CreateCastMessage() {
|
| + CastMessage output;
|
| + output.set_protocol_version(CastMessage::CASTV2_1_0);
|
| + output.set_namespace_("x");
|
| + output.set_source_id("source");
|
| + output.set_destination_id("destination");
|
| + output.set_payload_type(CastMessage::STRING);
|
| + output.set_payload_utf8("payload");
|
| + return output;
|
| +}
|
| +
|
| +// FIFO queue of completion callbacks. Outstanding write operations are
|
| +// Push()ed into the queue. Callback completion is simulated by invoking
|
| +// Pop() in the same order as Push().
|
| +class CompletionQueue {
|
| + public:
|
| + CompletionQueue() {}
|
| + ~CompletionQueue() { CHECK_EQ(0u, cb_queue_.size()); }
|
| +
|
| + // Enqueues a pending completion callback.
|
| + void Push(const net::CompletionCallback& cb) { cb_queue_.push(cb); }
|
| + // Runs the next callback and removes it from the queue.
|
| + void Pop(int rv) {
|
| + CHECK_GT(cb_queue_.size(), 0u);
|
| + cb_queue_.front().Run(rv);
|
| + cb_queue_.pop();
|
| + }
|
| +
|
| + private:
|
| + std::queue<net::CompletionCallback> cb_queue_;
|
| + DISALLOW_COPY_AND_ASSIGN(CompletionQueue);
|
| +};
|
| +
|
| +// GMock action that reads data from an IOBuffer and writes it to a string
|
| +// variable.
|
| +//
|
| +// buf_idx (template parameter 0): 0-based index of the net::IOBuffer
|
| +// in the function mock arg list.
|
| +// size_idx (template parameter 1): 0-based index of the byte count arg.
|
| +// str: pointer to the string which will receive data from the buffer.
|
| +ACTION_TEMPLATE(ReadBufferToString,
|
| + HAS_2_TEMPLATE_PARAMS(int, buf_idx, int, size_idx),
|
| + AND_1_VALUE_PARAMS(str)) {
|
| + str->assign(testing::get<buf_idx>(args)->data(),
|
| + testing::get<size_idx>(args));
|
| +}
|
| +
|
| +// GMock action that writes data from a string to an IOBuffer.
|
| +//
|
| +// buf_idx (template parameter 0): 0-based index of the IOBuffer arg.
|
| +// str: the string containing data to be written to the IOBuffer.
|
| +ACTION_TEMPLATE(FillBufferFromString,
|
| + HAS_1_TEMPLATE_PARAMS(int, buf_idx),
|
| + AND_1_VALUE_PARAMS(str)) {
|
| + memcpy(testing::get<buf_idx>(args)->data(), str.data(), str.size());
|
| +}
|
| +
|
| +// Checks if two proto messages are the same.
|
| +// From
|
| +// third_party/cacheinvalidation/overrides/google/cacheinvalidation/deps/gmock.h
|
| +MATCHER_P(EqualsProto, message, "") {
|
| + std::string expected_serialized, actual_serialized;
|
| + message.SerializeToString(&expected_serialized);
|
| + arg.SerializeToString(&actual_serialized);
|
| + return expected_serialized == actual_serialized;
|
| +}
|
| +} // namespace
|
| +
|
| +class MockCastTransportDelegate : public CastTransport::Delegate {
|
| + public:
|
| + MOCK_METHOD3(OnError,
|
| + void(const CastSocketPlaceholder* socket,
|
| + ChannelError error,
|
| + const LastErrors& last_errors));
|
| + MOCK_METHOD2(OnMessage,
|
| + void(const CastSocketPlaceholder* socket,
|
| + const CastMessage& message));
|
| +};
|
| +
|
| +class MockCastSocket : public CastSocketPlaceholder {
|
| + public:
|
| + MockCastSocket() {
|
| + net::IPAddressNumber number;
|
| + number.push_back(192);
|
| + number.push_back(0);
|
| + number.push_back(0);
|
| + number.push_back(1);
|
| + ip_ = net::IPEndPoint(number, 8009);
|
| + }
|
| +
|
| + virtual ~MockCastSocket() {}
|
| +
|
| + // The IP endpoint for the destination of the channel.
|
| + virtual const net::IPEndPoint& ip_endpoint() const OVERRIDE { return ip_; }
|
| +
|
| + // The authentication level requested for the channel.
|
| + virtual ChannelAuthType channel_auth() const OVERRIDE {
|
| + return CHANNEL_AUTH_TYPE_SSL_VERIFIED;
|
| + }
|
| +
|
| + virtual int id() const OVERRIDE { return 1; }
|
| +
|
| + MOCK_METHOD3(Write,
|
| + int(net::IOBuffer* buffer,
|
| + size_t size,
|
| + const net::CompletionCallback& callback));
|
| + MOCK_METHOD3(Read,
|
| + int(net::IOBuffer* buf,
|
| + int buf_len,
|
| + const net::CompletionCallback& callback));
|
| + MOCK_METHOD1(Close, void(const net::CompletionCallback& callback));
|
| + MOCK_METHOD1(CloseWithError, void(ChannelError error));
|
| +
|
| + protected:
|
| + virtual void CloseInternal() {}
|
| +
|
| + private:
|
| + net::IPEndPoint ip_;
|
| + net::CapturingNetLog capturing_net_log_;
|
| +};
|
| +
|
| +class CastTransportTest : public testing::Test {
|
| + public:
|
| + CastTransportTest()
|
| + : logger_(new Logger(
|
| + scoped_ptr<base::TickClock>(new base::SimpleTestTickClock),
|
| + base::TimeTicks())) {
|
| + transport_.reset(new CastTransport(&mock_socket_, &delegate_, logger_));
|
| + }
|
| + virtual ~CastTransportTest() {}
|
| +
|
| + protected:
|
| + MockCastTransportDelegate delegate_;
|
| + MockCastSocket mock_socket_;
|
| + scoped_refptr<Logger> logger_;
|
| + scoped_ptr<CastTransport> transport_;
|
| +};
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Asynchronous write tests
|
| +TEST_F(CastTransportTest, TestFullWriteAsync) {
|
| + CompletionQueue socket_cbs;
|
| + CompleteHandler write_handler;
|
| + std::string output;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _))
|
| + .WillOnce(DoAll(ReadBufferToString<0, 1>(&output),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)));
|
| + EXPECT_CALL(write_handler, Complete(net::OK));
|
| + transport_->SendMessage(
|
| + message,
|
| + base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler)));
|
| + socket_cbs.Pop(serialized_message.size());
|
| + EXPECT_EQ(serialized_message, output);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestPartialWritesAsync) {
|
| + InSequence seq;
|
| + CompletionQueue socket_cbs;
|
| + CompleteHandler write_handler;
|
| + std::string output;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Only one byte is written.
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _))
|
| + .WillOnce(DoAll(ReadBufferToString<0, 1>(&output),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)));
|
| + // Remainder of bytes are written.
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size() - 1, _))
|
| + .WillOnce(DoAll(ReadBufferToString<0, 1>(&output),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)));
|
| +
|
| + transport_->SendMessage(
|
| + message,
|
| + base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler)));
|
| + EXPECT_EQ(serialized_message, output);
|
| + socket_cbs.Pop(1);
|
| +
|
| + EXPECT_CALL(write_handler, Complete(net::OK));
|
| + socket_cbs.Pop(serialized_message.size() - 1);
|
| + EXPECT_EQ(serialized_message.substr(1, serialized_message.size() - 1),
|
| + output);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestWriteFailureAsync) {
|
| + CompletionQueue socket_cbs;
|
| + CompleteHandler write_handler;
|
| + CastMessage message = CreateCastMessage();
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), _, _))
|
| + .WillOnce(DoAll(WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)));
|
| + EXPECT_CALL(write_handler, Complete(net::ERR_FAILED));
|
| + transport_->SendMessage(
|
| + message,
|
| + base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler)));
|
| + socket_cbs.Pop(net::ERR_CONNECTION_RESET);
|
| +}
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Synchronous write tests
|
| +TEST_F(CastTransportTest, TestFullWriteSync) {
|
| + CompleteHandler write_handler;
|
| + std::string output;
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _))
|
| + .WillOnce(DoAll(ReadBufferToString<0, 1>(&output),
|
| + Return(serialized_message.size())));
|
| + EXPECT_CALL(write_handler, Complete(net::OK));
|
| + transport_->SendMessage(
|
| + message,
|
| + base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler)));
|
| + EXPECT_EQ(serialized_message, output);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestPartialWritesSync) {
|
| + InSequence seq;
|
| + CompleteHandler write_handler;
|
| + std::string output;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Only one byte is written.
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _))
|
| + .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), Return(1)));
|
| + // Remainder of bytes are written.
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size() - 1, _))
|
| + .WillOnce(DoAll(ReadBufferToString<0, 1>(&output),
|
| + Return(serialized_message.size() - 1)));
|
| +
|
| + EXPECT_CALL(write_handler, Complete(net::OK));
|
| + transport_->SendMessage(
|
| + message,
|
| + base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler)));
|
| + EXPECT_EQ(serialized_message.substr(1, serialized_message.size() - 1),
|
| + output);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestWriteFailureSync) {
|
| + CompleteHandler write_handler;
|
| + CastMessage message = CreateCastMessage();
|
| + EXPECT_CALL(mock_socket_, Write(NotNull(), _, _))
|
| + .WillOnce(Return(net::ERR_CONNECTION_RESET));
|
| + EXPECT_CALL(write_handler, Complete(net::ERR_FAILED));
|
| + transport_->SendMessage(
|
| + message,
|
| + base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler)));
|
| +}
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Asynchronous read tests
|
| +TEST_F(CastTransportTest, TestFullReadAsync) {
|
| + CompletionQueue socket_cbs;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size())),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| +
|
| + EXPECT_CALL(delegate_, OnMessage(&mock_socket_, EqualsProto(message)));
|
| + transport_->StartReadLoop();
|
| + socket_cbs.Pop(MessageFramer::MessageHeader::header_size());
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(Return(net::ERR_IO_PENDING));
|
| + socket_cbs.Pop(serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size());
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestPartialReadAsync) {
|
| + CompletionQueue socket_cbs;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n-1].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| + // Read final byte.
|
| + EXPECT_CALL(mock_socket_, Read(NotNull(), 1, _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + serialized_message.size() - 1, 1)),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| +
|
| + EXPECT_CALL(delegate_, OnMessage(&mock_socket_, EqualsProto(message)));
|
| + transport_->StartReadLoop();
|
| + socket_cbs.Pop(MessageFramer::MessageHeader::header_size());
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(Return(net::ERR_IO_PENDING));
|
| + socket_cbs.Pop(serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1);
|
| + socket_cbs.Pop(1);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestReadErrorInHeaderAsync) {
|
| + CompletionQueue socket_cbs;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| +
|
| + EXPECT_CALL(delegate_,
|
| + OnError(&mock_socket_, CHANNEL_ERROR_TRANSPORT_ERROR, _));
|
| + transport_->StartReadLoop();
|
| + // Header read failure.
|
| + socket_cbs.Pop(net::ERR_CONNECTION_RESET);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestReadErrorInBodyAsync) {
|
| + CompletionQueue socket_cbs;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n-1].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| +
|
| + EXPECT_CALL(delegate_,
|
| + OnError(&mock_socket_, CHANNEL_ERROR_TRANSPORT_ERROR, _));
|
| + transport_->StartReadLoop();
|
| + // Header read is OK.
|
| + socket_cbs.Pop(MessageFramer::MessageHeader::header_size());
|
| + // Body read fails.
|
| + socket_cbs.Pop(net::ERR_CONNECTION_RESET);
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestReadCorruptedMessageAsync) {
|
| + CompletionQueue socket_cbs;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Corrupt the serialized message body(set it to X's).
|
| + for (size_t i = MessageFramer::MessageHeader::header_size();
|
| + i < serialized_message.size();
|
| + ++i) {
|
| + serialized_message[i] = 'x';
|
| + }
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)),
|
| + WithArg<2>(Invoke(&socket_cbs, &CompletionQueue::Push)),
|
| + Return(net::ERR_IO_PENDING)))
|
| + .RetiresOnSaturation();
|
| +
|
| + EXPECT_CALL(delegate_,
|
| + OnError(&mock_socket_, CHANNEL_ERROR_INVALID_MESSAGE, _));
|
| + transport_->StartReadLoop();
|
| + socket_cbs.Pop(MessageFramer::MessageHeader::header_size());
|
| + socket_cbs.Pop(serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size());
|
| +}
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Synchronous read tests
|
| +TEST_F(CastTransportTest, TestFullReadSync) {
|
| + InSequence s;
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + Return(MessageFramer::MessageHeader::header_size())))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size())),
|
| + Return(serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size())))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(delegate_, OnMessage(&mock_socket_, EqualsProto(message)));
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(Return(net::ERR_IO_PENDING));
|
| + transport_->StartReadLoop();
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestPartialReadSync) {
|
| + InSequence s;
|
| +
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + Return(MessageFramer::MessageHeader::header_size())))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n-1].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)),
|
| + Return(serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)))
|
| + .RetiresOnSaturation();
|
| + // Read final byte.
|
| + EXPECT_CALL(mock_socket_, Read(NotNull(), 1, _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + serialized_message.size() - 1, 1)),
|
| + Return(1)))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(delegate_, OnMessage(&mock_socket_, EqualsProto(message)));
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(Return(net::ERR_IO_PENDING));
|
| + transport_->StartReadLoop();
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestReadErrorInHeaderSync) {
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + Return(net::ERR_CONNECTION_RESET)))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(delegate_,
|
| + OnError(&mock_socket_, CHANNEL_ERROR_TRANSPORT_ERROR, _));
|
| + transport_->StartReadLoop();
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestReadErrorInBodySync) {
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + Return(MessageFramer::MessageHeader::header_size())))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n-1].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)),
|
| + Return(net::ERR_CONNECTION_RESET)))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(delegate_,
|
| + OnError(&mock_socket_, CHANNEL_ERROR_TRANSPORT_ERROR, _));
|
| + transport_->StartReadLoop();
|
| +}
|
| +
|
| +TEST_F(CastTransportTest, TestReadCorruptedMessageSync) {
|
| + CastMessage message = CreateCastMessage();
|
| + std::string serialized_message;
|
| + EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message));
|
| +
|
| + // Corrupt the serialized message body(set it to X's).
|
| + for (size_t i = MessageFramer::MessageHeader::header_size();
|
| + i < serialized_message.size();
|
| + ++i) {
|
| + serialized_message[i] = 'x';
|
| + }
|
| +
|
| + // Read bytes [0, 3].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(), MessageFramer::MessageHeader::header_size(), _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message),
|
| + Return(MessageFramer::MessageHeader::header_size())))
|
| + .RetiresOnSaturation();
|
| + // Read bytes [4, n].
|
| + EXPECT_CALL(mock_socket_,
|
| + Read(NotNull(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size(),
|
| + _))
|
| + .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr(
|
| + MessageFramer::MessageHeader::header_size(),
|
| + serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size() - 1)),
|
| + Return(serialized_message.size() -
|
| + MessageFramer::MessageHeader::header_size())))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(delegate_,
|
| + OnError(&mock_socket_, CHANNEL_ERROR_INVALID_MESSAGE, _));
|
| + transport_->StartReadLoop();
|
| +}
|
| +} // namespace cast_channel
|
| +} // namespace core_api
|
| +} // namespace extensions
|
|
|