Commit ba057a79 authored by sergeyu's avatar sergeyu Committed by Commit bot

Replace ice_connection_to_client_unittest.cc with connection_unittest.cc

The new tests setup both ends of the connection, which also means
they test both ends. Previously there were no unittests for
ConnectionToHostImpl. It will also be possible to use the same tests
for WebRTC-based connections.

Review URL: https://codereview.chromium.org/1531983002

Cr-Commit-Position: refs/heads/master@{#365948}
parent 42d476e6
......@@ -98,8 +98,8 @@ source_set("unit_tests") {
"clipboard_filter_unittest.cc",
"connection_tester.cc",
"connection_tester.h",
"connection_unittest.cc",
"content_description_unittest.cc",
"ice_connection_to_client_unittest.cc",
"ice_transport_unittest.cc",
"input_event_tracker_unittest.cc",
"input_filter_unittest.cc",
......
// 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 "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/connection_to_host_impl.h"
#include "remoting/protocol/fake_session.h"
#include "remoting/protocol/ice_connection_to_client.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
using ::testing::StrictMock;
namespace remoting {
namespace protocol {
namespace {
MATCHER_P(EqualsCapabilitiesMessage, message, "") {
return arg.capabilities() == message.capabilities();
}
MATCHER_P(EqualsKeyEvent, event, "") {
return arg.usb_keycode() == event.usb_keycode() &&
arg.pressed() == event.pressed();
}
class MockConnectionToHostEventCallback
: public ConnectionToHost::HostEventCallback {
public:
MockConnectionToHostEventCallback() {}
~MockConnectionToHostEventCallback() override {}
MOCK_METHOD2(OnConnectionState,
void(ConnectionToHost::State state, ErrorCode error));
MOCK_METHOD1(OnConnectionReady, void(bool ready));
MOCK_METHOD2(OnRouteChanged,
void(const std::string& channel_name,
const TransportRoute& route));
};
} // namespace
class ConnectionTest : public testing::Test {
public:
ConnectionTest() {}
protected:
void SetUp() override {
// Setup host side.
host_session_ = new FakeSession();
host_connection_.reset(new IceConnectionToClient(
make_scoped_ptr(host_session_), message_loop_.task_runner()));
host_connection_->SetEventHandler(&host_event_handler_);
host_connection_->set_clipboard_stub(&host_clipboard_stub_);
host_connection_->set_host_stub(&host_stub_);
host_connection_->set_input_stub(&host_input_stub_);
// Setup client side.
owned_client_session_.reset(new FakeSession());
client_session_ = owned_client_session_.get();
client_connection_.reset(new ConnectionToHostImpl());
client_connection_->set_client_stub(&client_stub_);
client_connection_->set_clipboard_stub(&client_clipboard_stub_);
client_connection_->set_video_stub(&client_video_stub_);
}
void Connect() {
{
testing::InSequence sequence;
EXPECT_CALL(host_event_handler_,
OnConnectionAuthenticating(host_connection_.get()));
EXPECT_CALL(host_event_handler_,
OnConnectionAuthenticated(host_connection_.get()));
}
EXPECT_CALL(host_event_handler_,
OnConnectionChannelsConnected(host_connection_.get()));
{
testing::InSequence sequence;
EXPECT_CALL(client_event_handler_,
OnConnectionState(ConnectionToHost::CONNECTING, OK));
EXPECT_CALL(client_event_handler_,
OnConnectionState(ConnectionToHost::AUTHENTICATED, OK));
EXPECT_CALL(client_event_handler_,
OnConnectionState(ConnectionToHost::CONNECTED, OK));
}
client_connection_->Connect(owned_client_session_.Pass(),
&client_event_handler_);
client_session_->SimulateConnection(host_session_);
base::RunLoop().RunUntilIdle();
}
void TearDown() override {
client_connection_.reset();
host_connection_.reset();
base::RunLoop().RunUntilIdle();
}
base::MessageLoop message_loop_;
MockConnectionToClientEventHandler host_event_handler_;
MockClipboardStub host_clipboard_stub_;
MockHostStub host_stub_;
MockInputStub host_input_stub_;
scoped_ptr<ConnectionToClient> host_connection_;
FakeSession* host_session_; // Owned by |host_connection_|.
MockConnectionToHostEventCallback client_event_handler_;
MockClientStub client_stub_;
MockClipboardStub client_clipboard_stub_;
MockVideoStub client_video_stub_;
scoped_ptr<ConnectionToHost> client_connection_;
FakeSession* client_session_; // Owned by |client_connection_|.
scoped_ptr<FakeSession> owned_client_session_;
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionTest);
};
TEST_F(ConnectionTest, RejectConnection) {
EXPECT_CALL(client_event_handler_,
OnConnectionState(ConnectionToHost::CONNECTING, OK));
EXPECT_CALL(client_event_handler_,
OnConnectionState(ConnectionToHost::CLOSED, OK));
client_connection_->Connect(owned_client_session_.Pass(),
&client_event_handler_);
client_session_->event_handler()->OnSessionStateChange(Session::CLOSED);
}
TEST_F(ConnectionTest, Disconnect) {
Connect();
EXPECT_CALL(client_event_handler_,
OnConnectionState(ConnectionToHost::CLOSED, OK));
EXPECT_CALL(host_event_handler_,
OnConnectionClosed(host_connection_.get(), OK));
client_session_->Close(OK);
base::RunLoop().RunUntilIdle();
}
TEST_F(ConnectionTest, Control) {
Connect();
Capabilities capabilities_msg;
capabilities_msg.set_capabilities("test_capability");
EXPECT_CALL(client_stub_,
SetCapabilities(EqualsCapabilitiesMessage(capabilities_msg)));
// Send capabilities from the host.
host_connection_->client_stub()->SetCapabilities(capabilities_msg);
base::RunLoop().RunUntilIdle();
}
TEST_F(ConnectionTest, Events) {
Connect();
KeyEvent event;
event.set_usb_keycode(3);
event.set_pressed(true);
EXPECT_CALL(host_event_handler_,
OnInputEventReceived(host_connection_.get(), _));
EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(event)));
// Send capabilities from the client.
client_connection_->input_stub()->InjectKeyEvent(event);
base::RunLoop().RunUntilIdle();
}
} // namespace protocol
} // namespace remoting
......@@ -32,14 +32,31 @@ FakeStreamChannelFactory* FakeTransport::GetMultiplexedChannelFactory() {
}
FakeSession::FakeSession()
: event_handler_(nullptr),
config_(SessionConfig::ForTest()),
jid_(kTestJid),
error_(OK),
closed_(false) {}
: config_(SessionConfig::ForTest()), jid_(kTestJid), weak_factory_(this) {}
FakeSession::~FakeSession() {}
void FakeSession::SimulateConnection(FakeSession* peer) {
peer_ = peer->weak_factory_.GetWeakPtr();
peer->peer_ = weak_factory_.GetWeakPtr();
transport_.GetStreamChannelFactory()->PairWith(
peer->transport_.GetStreamChannelFactory());
transport_.GetMultiplexedChannelFactory()->PairWith(
peer->transport_.GetMultiplexedChannelFactory());
event_handler_->OnSessionStateChange(CONNECTING);
peer->event_handler_->OnSessionStateChange(ACCEPTING);
peer->event_handler_->OnSessionStateChange(ACCEPTED);
event_handler_->OnSessionStateChange(ACCEPTED);
event_handler_->OnSessionStateChange(AUTHENTICATING);
peer->event_handler_->OnSessionStateChange(AUTHENTICATING);
event_handler_->OnSessionStateChange(AUTHENTICATED);
peer->event_handler_->OnSessionStateChange(AUTHENTICATED);
event_handler_->OnSessionStateChange(CONNECTED);
peer->event_handler_->OnSessionStateChange(CONNECTED);
}
void FakeSession::SetEventHandler(EventHandler* event_handler) {
event_handler_ = event_handler;
}
......@@ -63,6 +80,14 @@ FakeTransport* FakeSession::GetTransport() {
void FakeSession::Close(ErrorCode error) {
closed_ = true;
error_ = error;
event_handler_->OnSessionStateChange(CLOSED);
FakeSession* peer = peer_.get();
if (peer) {
peer->peer_.reset();
peer_.reset();
peer->Close(error);
}
}
} // namespace protocol
......
......@@ -10,6 +10,7 @@
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "remoting/protocol/fake_stream_socket.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/transport.h"
......@@ -42,10 +43,10 @@ class FakeSession : public Session {
FakeSession();
~FakeSession() override;
EventHandler* event_handler() { return event_handler_; }
void SimulateConnection(FakeSession* peer);
EventHandler* event_handler() { return event_handler_; }
void set_error(ErrorCode error) { error_ = error; }
bool is_closed() const { return closed_; }
// Session interface.
......@@ -56,16 +57,20 @@ class FakeSession : public Session {
FakeTransport* GetTransport() override;
void Close(ErrorCode error) override;
public:
EventHandler* event_handler_;
private:
EventHandler* event_handler_ = nullptr;
scoped_ptr<SessionConfig> config_;
std::string jid_;
FakeTransport transport_;
ErrorCode error_;
bool closed_;
ErrorCode error_ = OK;
bool closed_ = false;
base::WeakPtr<FakeSession> peer_;
base::WeakPtrFactory<FakeSession> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeSession);
};
......
......@@ -169,12 +169,24 @@ FakeStreamSocket* FakeStreamChannelFactory::GetFakeChannel(
return channels_[name].get();
}
void FakeStreamChannelFactory::PairWith(
FakeStreamChannelFactory* peer_factory) {
peer_factory_ = peer_factory->weak_factory_.GetWeakPtr();
peer_factory->peer_factory_ = weak_factory_.GetWeakPtr();
}
void FakeStreamChannelFactory::CreateChannel(
const std::string& name,
const ChannelCreatedCallback& callback) {
scoped_ptr<FakeStreamSocket> channel(new FakeStreamSocket());
channels_[name] = channel->GetWeakPtr();
if (peer_factory_) {
FakeStreamSocket* peer_channel = peer_factory_->GetFakeChannel(name);
if (peer_channel)
channel->PairWith(peer_channel);
}
if (fail_create_)
channel.reset();
......
......@@ -114,6 +114,10 @@ class FakeStreamChannelFactory : public StreamChannelFactory {
FakeStreamSocket* GetFakeChannel(const std::string& name);
// Pairs the socket with |peer_socket|. Deleting either of the paired sockets
// unpairs them.
void PairWith(FakeStreamChannelFactory* peer_factory);
// ChannelFactory interface.
void CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) override;
......@@ -130,6 +134,7 @@ class FakeStreamChannelFactory : public StreamChannelFactory {
bool fail_create_;
base::WeakPtr<FakeStreamChannelFactory> peer_factory_;
base::WeakPtrFactory<FakeStreamChannelFactory> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeStreamChannelFactory);
......
......@@ -47,7 +47,10 @@ IceConnectionToClient::IceConnectionToClient(
scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner)
: event_handler_(nullptr),
session_(session.Pass()),
video_encode_task_runner_(video_encode_task_runner) {
video_encode_task_runner_(video_encode_task_runner),
control_dispatcher_(new HostControlDispatcher()),
event_dispatcher_(new HostEventDispatcher()),
video_dispatcher_(new HostVideoDispatcher()) {
session_->SetEventHandler(this);
}
......@@ -139,18 +142,15 @@ void IceConnectionToClient::OnSessionStateChange(Session::State state) {
break;
case Session::AUTHENTICATED:
// Initialize channels.
control_dispatcher_.reset(new HostControlDispatcher());
control_dispatcher_->Init(session_.get(),
session_->config().control_config(), this);
event_dispatcher_.reset(new HostEventDispatcher());
event_dispatcher_->Init(session_.get(), session_->config().event_config(),
this);
event_dispatcher_->set_on_input_event_callback(
base::Bind(&IceConnectionToClient::OnInputEventReceived,
base::Unretained(this)));
video_dispatcher_.reset(new HostVideoDispatcher());
video_dispatcher_->Init(session_.get(), session_->config().video_config(),
this);
......
// 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 "remoting/protocol/ice_connection_to_client.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/fake_session.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "testing/gmock/include/gmock/gmock.h"
using ::testing::_;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
using ::testing::StrictMock;
namespace remoting {
namespace protocol {
class IpcConnectionToClientTest : public testing::Test {
public:
IpcConnectionToClientTest() {}
protected:
void SetUp() override {
session_ = new FakeSession();
// Allocate a ClientConnection object with the mock objects.
viewer_.reset(new IceConnectionToClient(make_scoped_ptr(session_),
message_loop_.task_runner()));
viewer_->SetEventHandler(&handler_);
EXPECT_CALL(handler_, OnConnectionAuthenticated(viewer_.get()))
.WillOnce(
InvokeWithoutArgs(this, &IpcConnectionToClientTest::ConnectStubs));
EXPECT_CALL(handler_, OnConnectionChannelsConnected(viewer_.get()));
session_->event_handler()->OnSessionStateChange(Session::ACCEPTED);
session_->event_handler()->OnSessionStateChange(Session::AUTHENTICATED);
base::RunLoop().RunUntilIdle();
}
void TearDown() override {
viewer_.reset();
base::RunLoop().RunUntilIdle();
}
void ConnectStubs() {
viewer_->set_clipboard_stub(&clipboard_stub_);
viewer_->set_host_stub(&host_stub_);
viewer_->set_input_stub(&input_stub_);
}
base::MessageLoop message_loop_;
MockConnectionToClientEventHandler handler_;
MockClipboardStub clipboard_stub_;
MockHostStub host_stub_;
MockInputStub input_stub_;
scoped_ptr<ConnectionToClient> viewer_;
FakeSession* session_;
private:
DISALLOW_COPY_AND_ASSIGN(IpcConnectionToClientTest);
};
TEST_F(IpcConnectionToClientTest, SendUpdateStream) {
Capabilities capabilities;
viewer_->client_stub()->SetCapabilities(capabilities);
base::RunLoop().RunUntilIdle();
// Verify that something has been written.
// TODO(sergeyu): Verify that the correct data has been written.
FakeStreamSocket* channel =
session_->GetTransport()->GetStreamChannelFactory()->GetFakeChannel(
kControlChannelName);
ASSERT_TRUE(channel);
EXPECT_FALSE(channel->written_data().empty());
// And then close the connection to ConnectionToClient.
viewer_->Disconnect(protocol::OK);
base::RunLoop().RunUntilIdle();
}
TEST_F(IpcConnectionToClientTest, NoWriteAfterDisconnect) {
Capabilities capabilities;
viewer_->client_stub()->SetCapabilities(capabilities);
// And then close the connection to ConnectionToClient.
viewer_->Disconnect(protocol::OK);
// The test will crash if data writer tries to write data to the
// channel socket.
// TODO(sergeyu): Use MockSession to verify that no data is written?
base::RunLoop().RunUntilIdle();
}
TEST_F(IpcConnectionToClientTest, StateChange) {
EXPECT_CALL(handler_, OnConnectionClosed(viewer_.get(), OK));
session_->event_handler()->OnSessionStateChange(Session::CLOSED);
base::RunLoop().RunUntilIdle();
EXPECT_CALL(handler_, OnConnectionClosed(viewer_.get(), SESSION_REJECTED));
session_->set_error(SESSION_REJECTED);
session_->event_handler()->OnSessionStateChange(Session::FAILED);
base::RunLoop().RunUntilIdle();
}
} // namespace protocol
} // namespace remoting
......@@ -312,8 +312,8 @@
'protocol/clipboard_filter_unittest.cc',
'protocol/connection_tester.cc',
'protocol/connection_tester.h',
'protocol/connection_unittest.cc',
'protocol/content_description_unittest.cc',
'protocol/ice_connection_to_client_unittest.cc',
'protocol/ice_transport_unittest.cc',
'protocol/input_event_tracker_unittest.cc',
'protocol/input_filter_unittest.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment