blob: 59c7a39a370f218e2a17c58283f87dd14d19822b [file] [log] [blame]
// Copyright 2015 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 "blimp/net/blimp_connection.h"
#include <stddef.h>
#include <string>
#include "base/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "blimp/common/proto/blimp_message.pb.h"
#include "blimp/net/common.h"
#include "blimp/net/connection_error_observer.h"
#include "blimp/net/test_common.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
using testing::InSequence;
using testing::Return;
using testing::SaveArg;
namespace blimp {
namespace {
class BlimpConnectionTest : public testing::Test {
public:
BlimpConnectionTest() {
std::unique_ptr<testing::StrictMock<MockPacketWriter>> writer(
new testing::StrictMock<MockPacketWriter>);
writer_ = writer.get();
connection_.reset(new BlimpConnection(
base::WrapUnique(new MockPacketReader), std::move(writer)));
connection_->AddConnectionErrorObserver(&error_observer1_);
connection_->AddConnectionErrorObserver(&error_observer2_);
connection_->AddConnectionErrorObserver(&error_observer3_);
connection_->RemoveConnectionErrorObserver(&error_observer3_);
}
~BlimpConnectionTest() override {}
protected:
std::unique_ptr<BlimpMessage> CreateInputMessage() {
std::unique_ptr<BlimpMessage> msg(new BlimpMessage);
msg->set_type(BlimpMessage::INPUT);
return msg;
}
std::unique_ptr<BlimpMessage> CreateControlMessage() {
std::unique_ptr<BlimpMessage> msg(new BlimpMessage);
msg->set_type(BlimpMessage::TAB_CONTROL);
return msg;
}
base::MessageLoop message_loop_;
testing::StrictMock<MockPacketWriter>* writer_;
testing::StrictMock<MockConnectionErrorObserver> error_observer1_;
testing::StrictMock<MockConnectionErrorObserver> error_observer2_;
// This error observer is Removed() immediately after it's added;
// it should never be called.
testing::StrictMock<MockConnectionErrorObserver> error_observer3_;
testing::StrictMock<MockBlimpMessageProcessor> receiver_;
std::unique_ptr<BlimpConnection> connection_;
};
// Write completes writing two packets asynchronously.
TEST_F(BlimpConnectionTest, AsyncTwoPacketsWrite) {
net::CompletionCallback write_packet_cb;
InSequence s;
EXPECT_CALL(*writer_,
WritePacket(BufferEqualsProto(*CreateInputMessage()), _))
.WillOnce(SaveArg<1>(&write_packet_cb))
.RetiresOnSaturation();
EXPECT_CALL(*writer_,
WritePacket(BufferEqualsProto(*CreateControlMessage()), _))
.WillOnce(SaveArg<1>(&write_packet_cb))
.RetiresOnSaturation();
BlimpMessageProcessor* sender = connection_->GetOutgoingMessageProcessor();
net::TestCompletionCallback complete_cb_1;
ASSERT_TRUE(write_packet_cb.is_null());
sender->ProcessMessage(CreateInputMessage(),
complete_cb_1.callback());
ASSERT_FALSE(write_packet_cb.is_null());
base::ResetAndReturn(&write_packet_cb).Run(net::OK);
EXPECT_EQ(net::OK, complete_cb_1.WaitForResult());
net::TestCompletionCallback complete_cb_2;
ASSERT_TRUE(write_packet_cb.is_null());
sender->ProcessMessage(CreateControlMessage(),
complete_cb_2.callback());
ASSERT_FALSE(write_packet_cb.is_null());
base::ResetAndReturn(&write_packet_cb).Run(net::OK);
EXPECT_EQ(net::OK, complete_cb_2.WaitForResult());
}
// Writer completes writing two packets asynchronously.
// First write succeeds, second fails.
TEST_F(BlimpConnectionTest, AsyncTwoPacketsWriteWithError) {
net::CompletionCallback write_packet_cb;
InSequence s;
EXPECT_CALL(*writer_,
WritePacket(BufferEqualsProto(*CreateInputMessage()), _))
.WillOnce(SaveArg<1>(&write_packet_cb))
.RetiresOnSaturation();
EXPECT_CALL(*writer_,
WritePacket(BufferEqualsProto(*CreateControlMessage()), _))
.WillOnce(SaveArg<1>(&write_packet_cb))
.RetiresOnSaturation();
EXPECT_CALL(error_observer1_, OnConnectionError(net::ERR_FAILED));
EXPECT_CALL(error_observer2_, OnConnectionError(net::ERR_FAILED));
BlimpMessageProcessor* sender = connection_->GetOutgoingMessageProcessor();
net::TestCompletionCallback complete_cb_1;
sender->ProcessMessage(CreateInputMessage(),
complete_cb_1.callback());
base::ResetAndReturn(&write_packet_cb).Run(net::OK);
EXPECT_EQ(net::OK, complete_cb_1.WaitForResult());
net::TestCompletionCallback complete_cb_2;
sender->ProcessMessage(CreateControlMessage(),
complete_cb_2.callback());
base::ResetAndReturn(&write_packet_cb).Run(net::ERR_FAILED);
EXPECT_EQ(net::ERR_FAILED, complete_cb_2.WaitForResult());
}
} // namespace
} // namespace blimp