summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-01 20:54:32 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-01 20:54:32 +0000
commit10c94b3a6c2d47dbcb3be355dcbcaae0f8b024c6 (patch)
tree43da6baae2611225bf46bc65367dfc63fe895b43 /remoting
parente326bb9ab32dea06c9419ee774a9a893fb02da52 (diff)
downloadchromium_src-10c94b3a6c2d47dbcb3be355dcbcaae0f8b024c6.zip
chromium_src-10c94b3a6c2d47dbcb3be355dcbcaae0f8b024c6.tar.gz
chromium_src-10c94b3a6c2d47dbcb3be355dcbcaae0f8b024c6.tar.bz2
Unittests for chromotocol code.
BUG=53986 TEST=Unittests FTW! Review URL: http://codereview.chromium.org/3407007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61228 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/jingle_glue/channel_socket_adapter_unittest.cc121
-rw-r--r--remoting/jingle_glue/jingle_channel_unittest.cc16
-rw-r--r--remoting/jingle_glue/jingle_client.cc2
-rw-r--r--remoting/jingle_glue/mock_objects.h18
-rw-r--r--remoting/jingle_glue/stream_socket_adapter_unittest.cc151
-rw-r--r--remoting/protocol/jingle_chromoting_connection.cc14
-rw-r--r--remoting/protocol/jingle_chromoting_connection_unittest.cc579
-rw-r--r--remoting/protocol/jingle_chromoting_server.cc7
-rw-r--r--remoting/protocol/jingle_chromoting_server.h6
-rw-r--r--remoting/protocol/session_manager_pair.cc91
-rw-r--r--remoting/protocol/session_manager_pair.h70
-rw-r--r--remoting/remoting.gyp6
12 files changed, 1057 insertions, 24 deletions
diff --git a/remoting/jingle_glue/channel_socket_adapter_unittest.cc b/remoting/jingle_glue/channel_socket_adapter_unittest.cc
new file mode 100644
index 0000000..ac2c591
--- /dev/null
+++ b/remoting/jingle_glue/channel_socket_adapter_unittest.cc
@@ -0,0 +1,121 @@
+// Copyright (c) 2010 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/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/socket/socket.h"
+#include "remoting/jingle_glue/channel_socket_adapter.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libjingle/source/talk/p2p/base/transportchannel.h"
+
+using net::IOBuffer;
+
+using testing::_;
+using testing::Return;
+
+namespace remoting {
+
+namespace {
+const int kBufferSize = 4096;
+const char kTestData[] = "data";
+const int kTestDataSize = 4;
+const int kTestError = -32123;
+} // namespace
+
+class MockTransportChannel : public cricket::TransportChannel {
+ public:
+ MockTransportChannel()
+ : cricket::TransportChannel("", "") {
+ }
+
+ MOCK_METHOD2(SendPacket, int(const char *data, size_t len));
+ MOCK_METHOD2(SetOption, int(talk_base::Socket::Option opt, int value));
+ MOCK_METHOD0(GetError, int());
+};
+
+class TransportChannelSocketAdapterTest : public testing::Test {
+ public:
+ TransportChannelSocketAdapterTest()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(
+ callback_(this, &TransportChannelSocketAdapterTest::Callback)),
+ callback_result_(0) {
+ }
+
+ protected:
+ virtual void SetUp() {
+ target_.reset(new TransportChannelSocketAdapter(&channel_));
+ }
+
+ void Callback(int result) {
+ callback_result_ = result;
+ }
+
+ MockTransportChannel channel_;
+ scoped_ptr<TransportChannelSocketAdapter> target_;
+ net::CompletionCallbackImpl<TransportChannelSocketAdapterTest> callback_;
+ int callback_result_;
+ MessageLoopForIO message_loop_;
+};
+
+// Verify that Read() returns net::ERR_IO_PENDING.
+TEST_F(TransportChannelSocketAdapterTest, Read) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kBufferSize);
+
+ int result = target_->Read(buffer, kBufferSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ channel_.SignalReadPacket(&channel_, kTestData, kTestDataSize);
+ EXPECT_EQ(kTestDataSize, callback_result_);
+}
+
+// Verify that Read() after Close() returns error.
+TEST_F(TransportChannelSocketAdapterTest, ReadClose) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kBufferSize);
+
+ int result = target_->Read(buffer, kBufferSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ target_->Close(kTestError);
+ EXPECT_EQ(kTestError, callback_result_);
+
+ // All Read() calls after Close() should return the error.
+ EXPECT_EQ(kTestError, target_->Read(buffer, kBufferSize, &callback_));
+}
+
+// Verify that Write sends the packet and returns correct result.
+TEST_F(TransportChannelSocketAdapterTest, Write) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kTestDataSize);
+
+ EXPECT_CALL(channel_, SendPacket(buffer->data(), kTestDataSize))
+ .WillOnce(Return(kTestDataSize));
+
+ int result = target_->Write(buffer, kTestDataSize, &callback_);
+ EXPECT_EQ(kTestDataSize, result);
+}
+
+// Verify that the message is still send if Write() is called while
+// socket is not open yet, and that the callback is called.
+TEST_F(TransportChannelSocketAdapterTest, WritePending) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kTestDataSize);
+
+ EXPECT_CALL(channel_, SendPacket(buffer->data(), kTestDataSize))
+ .Times(2)
+ .WillOnce(Return(SOCKET_ERROR))
+ .WillOnce(Return(kTestDataSize));
+
+ EXPECT_CALL(channel_, GetError())
+ .WillOnce(Return(EWOULDBLOCK));
+
+ int result = target_->Write(buffer, kTestDataSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ channel_.SignalWritableState(&channel_);
+ EXPECT_EQ(kTestDataSize, callback_result_);
+}
+
+} // namespace remoting
diff --git a/remoting/jingle_glue/jingle_channel_unittest.cc b/remoting/jingle_glue/jingle_channel_unittest.cc
index 175d69c..97b5a17 100644
--- a/remoting/jingle_glue/jingle_channel_unittest.cc
+++ b/remoting/jingle_glue/jingle_channel_unittest.cc
@@ -7,6 +7,7 @@
#include "media/base/data_buffer.h"
#include "remoting/jingle_glue/jingle_channel.h"
#include "remoting/jingle_glue/jingle_thread.h"
+#include "remoting/jingle_glue/mock_objects.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libjingle/source/talk/base/stream.h"
@@ -30,21 +31,6 @@ class MockJingleChannelCallback : public JingleChannel::Callback {
scoped_refptr<media::DataBuffer>));
};
-class MockStream : public talk_base::StreamInterface {
- public:
- virtual ~MockStream() {}
- MOCK_CONST_METHOD0(GetState, talk_base::StreamState());
-
- MOCK_METHOD4(Read, talk_base::StreamResult(void*, size_t, size_t*, int*));
- MOCK_METHOD4(Write, talk_base::StreamResult(const void*, size_t,
- size_t*, int*));
- MOCK_CONST_METHOD1(GetAvailable, bool(size_t*));
- MOCK_METHOD0(Close, void());
-
- MOCK_METHOD3(PostEvent, void(talk_base::Thread*, int, int));
- MOCK_METHOD2(PostEvent, void(int, int));
-};
-
class JingleChannelTest : public testing::Test {
public:
virtual ~JingleChannelTest() { }
diff --git a/remoting/jingle_glue/jingle_client.cc b/remoting/jingle_glue/jingle_client.cc
index c6206f7..e371850 100644
--- a/remoting/jingle_glue/jingle_client.cc
+++ b/remoting/jingle_glue/jingle_client.cc
@@ -35,7 +35,7 @@ class LocalTunnelSessionClient : public cricket::TunnelSessionClient {
virtual cricket::TunnelSession* MakeTunnelSession(
cricket::Session* session, talk_base::Thread* stream_thread,
cricket::TunnelSessionRole role) {
- session->transport()->set_allow_local_ips(true);
+ session->set_allow_local_ips(true);
return new cricket::TunnelSession(this, session, stream_thread);
}
};
diff --git a/remoting/jingle_glue/mock_objects.h b/remoting/jingle_glue/mock_objects.h
index c1a1e26..0698ca6 100644
--- a/remoting/jingle_glue/mock_objects.h
+++ b/remoting/jingle_glue/mock_objects.h
@@ -5,8 +5,10 @@
#ifndef REMOTING_JINGLE_GLUE_MOCK_OBJECTS_H_
#define REMOTING_JINGLE_GLUE_MOCK_OBJECTS_H_
+#include "media/base/data_buffer.h"
#include "remoting/jingle_glue/jingle_channel.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/libjingle/source/talk/base/stream.h"
namespace remoting {
@@ -21,6 +23,22 @@ class MockJingleChannel : public JingleChannel {
DISALLOW_COPY_AND_ASSIGN(MockJingleChannel);
};
+class MockStream : public talk_base::StreamInterface {
+ public:
+ virtual ~MockStream() { }
+
+ MOCK_CONST_METHOD0(GetState, talk_base::StreamState());
+
+ MOCK_METHOD4(Read, talk_base::StreamResult(void*, size_t, size_t*, int*));
+ MOCK_METHOD4(Write, talk_base::StreamResult(const void*, size_t,
+ size_t*, int*));
+ MOCK_CONST_METHOD1(GetAvailable, bool(size_t*));
+ MOCK_METHOD0(Close, void());
+
+ MOCK_METHOD3(PostEvent, void(talk_base::Thread*, int, int));
+ MOCK_METHOD2(PostEvent, void(int, int));
+};
+
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_MOCK_OBJECTS_H_
diff --git a/remoting/jingle_glue/stream_socket_adapter_unittest.cc b/remoting/jingle_glue/stream_socket_adapter_unittest.cc
new file mode 100644
index 0000000..7d1dd62
--- /dev/null
+++ b/remoting/jingle_glue/stream_socket_adapter_unittest.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2010 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/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/socket/socket.h"
+#include "remoting/jingle_glue/stream_socket_adapter.h"
+#include "remoting/jingle_glue/mock_objects.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libjingle/source/talk/p2p/base/transportchannel.h"
+
+using net::IOBuffer;
+
+using testing::_;
+using testing::Return;
+using testing::SetArgumentPointee;
+
+namespace remoting {
+
+namespace {
+const int kBufferSize = 4096;
+const int kTestDataSize = 4;
+const int kTestError = -32123;
+} // namespace
+
+class StreamSocketAdapterTest : public testing::Test {
+ public:
+ StreamSocketAdapterTest()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(
+ callback_(this, &StreamSocketAdapterTest::Callback)),
+ callback_result_(0) {
+ stream_ = new MockStream();
+ target_.reset(new StreamSocketAdapter(stream_));
+ }
+
+ protected:
+ void Callback(int result) {
+ callback_result_ = result;
+ }
+
+ // |stream_| must be allocated on the heap, because StreamSocketAdapter
+ // owns the object and it will free it in the end.
+ MockStream* stream_;
+ scoped_ptr<StreamSocketAdapter> target_;
+ net::CompletionCallbackImpl<StreamSocketAdapterTest> callback_;
+ int callback_result_;
+ MessageLoopForIO message_loop_;
+};
+
+// Verify that Read() calls Read() in stream.
+TEST_F(StreamSocketAdapterTest, Read) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kBufferSize);
+
+ EXPECT_CALL(*stream_, Read(buffer->data(), kBufferSize, _, _))
+ .WillOnce(DoAll(SetArgumentPointee<2>(kTestDataSize),
+ Return(talk_base::SR_SUCCESS)));
+
+ int result = target_->Read(buffer, kBufferSize, &callback_);
+ EXPECT_EQ(kTestDataSize, result);
+ EXPECT_EQ(0, callback_result_);
+}
+
+// Verify that read callback is called for pending reads.
+TEST_F(StreamSocketAdapterTest, ReadPending) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kBufferSize);
+
+ EXPECT_CALL(*stream_, Read(buffer->data(), kBufferSize, _, _))
+ .Times(2)
+ .WillOnce(Return(talk_base::SR_BLOCK))
+ .WillOnce(DoAll(SetArgumentPointee<2>(kTestDataSize),
+ Return(talk_base::SR_SUCCESS)));
+
+ int result = target_->Read(buffer, kBufferSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ stream_->SignalEvent(stream_, talk_base::SE_READ, 0);
+ EXPECT_EQ(kTestDataSize, callback_result_);
+}
+
+// Verify that Read() returns error after Close().
+TEST_F(StreamSocketAdapterTest, ReadClose) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kBufferSize);
+
+ EXPECT_CALL(*stream_, Read(buffer->data(), kBufferSize, _, _))
+ .WillOnce(Return(talk_base::SR_BLOCK));
+
+ int result = target_->Read(buffer, kBufferSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ EXPECT_CALL(*stream_, Close());
+ target_->Close(kTestError);
+ EXPECT_EQ(kTestError, callback_result_);
+
+ // All Read() calls after Close() should return the error.
+ EXPECT_EQ(kTestError, target_->Read(buffer, kBufferSize, &callback_));
+}
+
+// Verify that Write() calls stream's Write() and returns result.
+TEST_F(StreamSocketAdapterTest, Write) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kTestDataSize);
+
+ EXPECT_CALL(*stream_, Write(buffer->data(), kTestDataSize, _, _))
+ .WillOnce(DoAll(SetArgumentPointee<2>(kTestDataSize),
+ Return(talk_base::SR_SUCCESS)));
+
+ int result = target_->Write(buffer, kTestDataSize, &callback_);
+ EXPECT_EQ(kTestDataSize, result);
+ EXPECT_EQ(0, callback_result_);
+}
+
+// Verify that write callback is called for pending writes.
+TEST_F(StreamSocketAdapterTest, WritePending) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kTestDataSize);
+
+ EXPECT_CALL(*stream_, Write(buffer->data(), kTestDataSize, _, _))
+ .Times(2)
+ .WillOnce(Return(talk_base::SR_BLOCK))
+ .WillOnce(DoAll(SetArgumentPointee<2>(kTestDataSize),
+ Return(talk_base::SR_SUCCESS)));
+
+ int result = target_->Write(buffer, kTestDataSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ stream_->SignalEvent(stream_, talk_base::SE_WRITE, 0);
+ EXPECT_EQ(kTestDataSize, callback_result_);
+}
+
+// Verify that Write() returns error after Close().
+TEST_F(StreamSocketAdapterTest, WriteClose) {
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(kTestDataSize);
+
+ EXPECT_CALL(*stream_, Write(buffer->data(), kTestDataSize, _, _))
+ .WillOnce(Return(talk_base::SR_BLOCK));
+
+ int result = target_->Write(buffer, kTestDataSize, &callback_);
+ ASSERT_EQ(net::ERR_IO_PENDING, result);
+
+ EXPECT_CALL(*stream_, Close());
+ target_->Close(kTestError);
+ EXPECT_EQ(kTestError, callback_result_);
+
+ // All Write() calls after Close() should return the error.
+ EXPECT_EQ(kTestError, target_->Write(buffer, kTestError, &callback_));
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/jingle_chromoting_connection.cc b/remoting/protocol/jingle_chromoting_connection.cc
index 48e3ec0..758057c 100644
--- a/remoting/protocol/jingle_chromoting_connection.cc
+++ b/remoting/protocol/jingle_chromoting_connection.cc
@@ -6,6 +6,7 @@
#include "base/message_loop.h"
#include "net/base/net_errors.h"
+#include "remoting/base/constants.h"
#include "remoting/jingle_glue/channel_socket_adapter.h"
#include "remoting/jingle_glue/stream_socket_adapter.h"
#include "remoting/protocol/jingle_chromoting_server.h"
@@ -173,16 +174,21 @@ void JingleChromotingConnection::OnInitiate(bool incoming) {
}
void JingleChromotingConnection::OnAccept() {
+ const cricket::ContentInfo* content =
+ session_->remote_description()->FirstContentByType(
+ kChromotingXmlNamespace);
+ ASSERT(content != NULL);
+
// Create video RTP channels.
video_rtp_channel_.reset(new TransportChannelSocketAdapter(
- session_->CreateChannel(kVideoRtpChannelName)));
+ session_->CreateChannel(content->name, kVideoRtpChannelName)));
video_rtcp_channel_.reset(new TransportChannelSocketAdapter(
- session_->CreateChannel(kVideoRtcpChannelName)));
+ session_->CreateChannel(content->name, kVideoRtcpChannelName)));
// Create events channel.
events_channel_ =
new PseudoTcpChannel(talk_base::Thread::Current(), session_);
- events_channel_->Connect(kEventsChannelName);
+ events_channel_->Connect(content->name, kEventsChannelName);
events_channel_adapter_.reset(new StreamSocketAdapter(
events_channel_->GetStream()));
@@ -190,7 +196,7 @@ void JingleChromotingConnection::OnAccept() {
// TODO(sergeyu): Remove video channel when we are ready to switch to RTP.
video_channel_ =
new PseudoTcpChannel(talk_base::Thread::Current(), session_);
- video_channel_->Connect(kVideoChannelName);
+ video_channel_->Connect(content->name, kVideoChannelName);
video_channel_adapter_.reset(new StreamSocketAdapter(
video_channel_->GetStream()));
diff --git a/remoting/protocol/jingle_chromoting_connection_unittest.cc b/remoting/protocol/jingle_chromoting_connection_unittest.cc
new file mode 100644
index 0000000..1f6f2e7
--- /dev/null
+++ b/remoting/protocol/jingle_chromoting_connection_unittest.cc
@@ -0,0 +1,579 @@
+// Copyright (c) 2010 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/time.h"
+#include "base/waitable_event.h"
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/socket/socket.h"
+#include "remoting/protocol/jingle_chromoting_connection.h"
+#include "remoting/protocol/jingle_chromoting_server.h"
+#include "remoting/protocol/session_manager_pair.h"
+#include "remoting/jingle_glue/jingle_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libjingle/source/talk/p2p/client/basicportallocator.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Return;
+using testing::SaveArg;
+using testing::SetArgumentPointee;
+using testing::WithArg;
+
+namespace remoting {
+class JingleChromotingConnectionTest;
+} // namespace remoting
+
+DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::JingleChromotingConnectionTest);
+
+namespace remoting {
+
+namespace {
+const int kConnectionTimeoutMs = 10000;
+const int kSendTimeoutMs = 20000;
+
+// Send 100 messages 1024 bytes each. For UDP messages are send with
+// 10ms interval (about 1 seconds for 100 messages).
+const int kMessageSize = 1024;
+const int kMessages = 100;
+const int kTestDataSize = kMessages * kMessageSize;
+const int kUdpWriteDelayMs = 10;
+} // namespace
+
+class MockServerCallback {
+ public:
+ MOCK_METHOD2(OnNewConnection, void(ChromotingConnection*, bool*));
+};
+
+class MockConnectionCallback {
+ public:
+ MOCK_METHOD1(OnStateChange, void(ChromotingConnection::State));
+};
+
+class JingleChromotingConnectionTest : public testing::Test {
+ public:
+ // Helper method to copy to set value of client_connection_.
+ void SetHostConnection(ChromotingConnection* connection) {
+ DCHECK(connection);
+ host_connection_ = connection;
+ host_connection_->SetStateChangeCallback(
+ NewCallback(&host_connection_callback_,
+ &MockConnectionCallback::OnStateChange));
+ }
+
+ protected:
+ virtual void SetUp() {
+ thread_.Start();
+ }
+
+ virtual void TearDown() {
+ CloseConnections();
+
+ if (host_server_) {
+ host_server_->Close(NewRunnableFunction(
+ &JingleChromotingConnectionTest::DoNothing));
+ }
+ if (client_server_) {
+ client_server_->Close(NewRunnableFunction(
+ &JingleChromotingConnectionTest::DoNothing));
+ }
+ thread_.Stop();
+ }
+
+ void CreateServerPair() {
+ // SessionManagerPair must be initialized on the jingle thread.
+ thread_.message_loop()->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &JingleChromotingConnectionTest::DoCreateServerPair));
+ SyncWithJingleThread();
+ }
+
+ void CloseConnections() {
+ if (host_connection_) {
+ host_connection_->Close(NewRunnableFunction(
+ &JingleChromotingConnectionTest::DoNothing));
+ }
+ if (client_connection_) {
+ client_connection_->Close(NewRunnableFunction(
+ &JingleChromotingConnectionTest::DoNothing));
+ }
+ SyncWithJingleThread();
+ }
+
+ void DoCreateServerPair() {
+ session_manager_pair_ = new SessionManagerPair(&thread_);
+ session_manager_pair_->Init();
+ host_server_ = new JingleChromotingServer(thread_.message_loop());
+ host_server_->set_allow_local_ips(true);
+ host_server_->Init(SessionManagerPair::kHostJid,
+ session_manager_pair_->host_session_manager(),
+ NewCallback(&host_server_callback_,
+ &MockServerCallback::OnNewConnection));
+ client_server_ = new JingleChromotingServer(thread_.message_loop());
+ client_server_->set_allow_local_ips(true);
+ client_server_->Init(SessionManagerPair::kClientJid,
+ session_manager_pair_->client_session_manager(),
+ NewCallback(&client_server_callback_,
+ &MockServerCallback::OnNewConnection));
+ }
+
+ void InitiateConnection() {
+ EXPECT_CALL(host_server_callback_, OnNewConnection(_, _))
+ .WillOnce(DoAll(
+ WithArg<0>(
+ Invoke(this,
+ &JingleChromotingConnectionTest::SetHostConnection)),
+ SetArgumentPointee<1>(true)));
+
+ base::WaitableEvent host_connected_event(false, false);
+ EXPECT_CALL(host_connection_callback_,
+ OnStateChange(ChromotingConnection::CONNECTING))
+ .Times(1);
+ EXPECT_CALL(host_connection_callback_,
+ OnStateChange(ChromotingConnection::CONNECTED))
+ .Times(1)
+ .WillOnce(InvokeWithoutArgs(&host_connected_event,
+ &base::WaitableEvent::Signal));
+
+ base::WaitableEvent client_connected_event(false, false);
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(ChromotingConnection::CONNECTING))
+ .Times(1);
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(ChromotingConnection::CONNECTED))
+ .Times(1)
+ .WillOnce(InvokeWithoutArgs(&client_connected_event,
+ &base::WaitableEvent::Signal));
+
+ client_connection_ = client_server_->Connect(
+ SessionManagerPair::kHostJid,
+ NewCallback(&client_connection_callback_,
+ &MockConnectionCallback::OnStateChange));
+
+ host_connected_event.TimedWait(
+ base::TimeDelta::FromMilliseconds(kConnectionTimeoutMs));
+ client_connected_event.TimedWait(
+ base::TimeDelta::FromMilliseconds(kConnectionTimeoutMs));
+ }
+
+ static void SignalEvent(base::WaitableEvent* event) {
+ event->Signal();
+ }
+
+ static void DoNothing() { }
+
+ void SyncWithJingleThread() {
+ base::WaitableEvent event(true, false);
+ thread_.message_loop()->PostTask(
+ FROM_HERE, NewRunnableFunction(&SignalEvent, &event));
+ event.Wait();
+ }
+
+ JingleThread thread_;
+ scoped_refptr<SessionManagerPair> session_manager_pair_;
+ scoped_refptr<JingleChromotingServer> host_server_;
+ MockServerCallback host_server_callback_;
+ scoped_refptr<JingleChromotingServer> client_server_;
+ MockServerCallback client_server_callback_;
+
+ scoped_refptr<ChromotingConnection> host_connection_;
+ MockConnectionCallback host_connection_callback_;
+ scoped_refptr<ChromotingConnection> client_connection_;
+ MockConnectionCallback client_connection_callback_;
+};
+
+class ChannelTesterBase : public base::RefCountedThreadSafe<ChannelTesterBase> {
+ public:
+ enum ChannelType {
+ EVENTS,
+ VIDEO,
+ VIDEO_RTP,
+ VIDEO_RTCP,
+ };
+
+ ChannelTesterBase(MessageLoop* message_loop,
+ ChromotingConnection* host_connection,
+ ChromotingConnection* client_connection)
+ : message_loop_(message_loop),
+ host_connection_(host_connection),
+ client_connection_(client_connection),
+ done_event_(true, false) {
+ }
+
+ virtual ~ChannelTesterBase() { }
+
+ void Start(ChannelType channel) {
+ message_loop_->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &ChannelTesterBase::DoStart,
+ channel));
+ }
+
+ void WaitFinished() {
+ done_event_.TimedWait(base::TimeDelta::FromMilliseconds(kSendTimeoutMs));
+ }
+
+ virtual void CheckResults() = 0;
+
+ protected:
+ void DoStart(ChannelType channel) {
+ socket_1_ = SelectChannel(host_connection_, channel);
+ socket_2_ = SelectChannel(client_connection_, channel);
+
+ InitBuffers();
+ DoRead();
+ DoWrite();
+ }
+
+ virtual void InitBuffers() = 0;
+ virtual void DoWrite() = 0;
+ virtual void DoRead() = 0;
+
+ net::Socket* SelectChannel(ChromotingConnection* connection,
+ ChannelType channel) {
+ switch (channel) {
+ case EVENTS:
+ return connection->GetEventsChannel();
+ case VIDEO:
+ return connection->GetVideoChannel();
+ case VIDEO_RTP:
+ return connection->GetVideoRtpChannel();
+ case VIDEO_RTCP:
+ return connection->GetVideoRtcpChannel();
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+ }
+
+ MessageLoop* message_loop_;
+ scoped_refptr<ChromotingConnection> host_connection_;
+ scoped_refptr<ChromotingConnection> client_connection_;
+ net::Socket* socket_1_;
+ net::Socket* socket_2_;
+ base::WaitableEvent done_event_;
+};
+
+class TCPChannelTester : public ChannelTesterBase {
+ public:
+ TCPChannelTester(MessageLoop* message_loop,
+ ChromotingConnection* host_connection,
+ ChromotingConnection* client_connection)
+ : ChannelTesterBase(message_loop, host_connection, client_connection),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ write_cb_(this, &TCPChannelTester::OnWritten)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ read_cb_(this, &TCPChannelTester::OnRead)),
+ write_errors_(0),
+ read_errors_(0) {
+ }
+
+ virtual ~TCPChannelTester() { }
+
+ virtual void CheckResults() {
+ EXPECT_EQ(0, write_errors_);
+ EXPECT_EQ(0, read_errors_);
+
+ input_buffer_->set_offset(0);
+ ASSERT_EQ(kTestDataSize + kMessageSize, input_buffer_->capacity());
+
+ output_buffer_->SetOffset(0);
+ ASSERT_EQ(kTestDataSize, output_buffer_->size());
+
+ EXPECT_EQ(0, memcmp(output_buffer_->data(),
+ input_buffer_->data(), kTestDataSize));
+ }
+
+ protected:
+ virtual void InitBuffers() {
+ output_buffer_ = new net::DrainableIOBuffer(
+ new net::IOBuffer(kTestDataSize), kTestDataSize);
+ memset(output_buffer_->data(), 123, kTestDataSize);
+
+ input_buffer_ = new net::GrowableIOBuffer();
+ // Always keep kMessageSize bytes available at the end of the input buffer.
+ input_buffer_->SetCapacity(kMessageSize);
+ }
+
+ virtual void DoWrite() {
+ int result = 1;
+ while (result > 0) {
+ if (output_buffer_->BytesRemaining() == 0)
+ break;
+
+ int bytes_to_write = std::min(output_buffer_->BytesRemaining(),
+ kMessageSize);
+ result = socket_1_->Write(output_buffer_, bytes_to_write, &write_cb_);
+ HandleWriteResult(result);
+ };
+ }
+
+ void OnWritten(int result) {
+ HandleWriteResult(result);
+ DoWrite();
+ }
+
+ void HandleWriteResult(int result) {
+ if (result <= 0 && result != net::ERR_IO_PENDING) {
+ LOG(ERROR) << "Received error " << result << " when trying to write";
+ write_errors_++;
+ done_event_.Signal();
+ } else if (result > 0) {
+ output_buffer_->DidConsume(result);
+ }
+ }
+
+ virtual void DoRead() {
+ int result = 1;
+ while (result > 0) {
+ input_buffer_->set_offset(input_buffer_->capacity() - kMessageSize);
+
+ result = socket_2_->Read(input_buffer_, kMessageSize, &read_cb_);
+ HandleReadResult(result);
+ };
+ }
+
+ void OnRead(int result) {
+ HandleReadResult(result);
+ DoRead();
+ }
+
+ void HandleReadResult(int result) {
+ if (result <= 0 && result != net::ERR_IO_PENDING) {
+ if (!done_event_.IsSignaled()) {
+ LOG(ERROR) << "Received error " << result << " when trying to read";
+ read_errors_++;
+ done_event_.Signal();
+ }
+ } else if (result > 0) {
+ // Allocate memory for the next read.
+ input_buffer_->SetCapacity(input_buffer_->capacity() + result);
+ if (input_buffer_->capacity() == kTestDataSize + kMessageSize)
+ done_event_.Signal();
+ }
+ }
+
+ private:
+ scoped_refptr<net::DrainableIOBuffer> output_buffer_;
+ scoped_refptr<net::GrowableIOBuffer> input_buffer_;
+
+ net::CompletionCallbackImpl<TCPChannelTester> write_cb_;
+ net::CompletionCallbackImpl<TCPChannelTester> read_cb_;
+ int write_errors_;
+ int read_errors_;
+};
+
+class UDPChannelTester : public ChannelTesterBase {
+ public:
+ UDPChannelTester(MessageLoop* message_loop,
+ ChromotingConnection* host_connection,
+ ChromotingConnection* client_connection)
+ : ChannelTesterBase(message_loop, host_connection, client_connection),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ write_cb_(this, &UDPChannelTester::OnWritten)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ read_cb_(this, &UDPChannelTester::OnRead)),
+ write_errors_(0),
+ read_errors_(0),
+ packets_sent_(0),
+ packets_received_(0),
+ broken_packets_(0) {
+ }
+
+ virtual ~UDPChannelTester() { }
+
+ virtual void CheckResults() {
+ EXPECT_EQ(0, write_errors_);
+ EXPECT_EQ(0, read_errors_);
+
+ EXPECT_EQ(0, broken_packets_);
+
+ // Verify that we've received at least one packet.
+ EXPECT_GT(packets_received_, 0);
+ LOG(INFO) << "Received " << packets_received_ << " packets out of "
+ << kMessages;
+ }
+
+ protected:
+ virtual void InitBuffers() {
+ }
+
+ virtual void DoWrite() {
+ if (packets_sent_ >= kMessages) {
+ done_event_.Signal();
+ return;
+ }
+
+ scoped_refptr<net::IOBuffer> packet = new net::IOBuffer(kMessageSize);
+ memset(packet->data(), 123, kMessageSize);
+ sent_packets_[packets_sent_] = packet;
+ // Put index of this packet in the beginning of the packet body.
+ memcpy(packet->data(), &packets_sent_, sizeof(packets_sent_));
+
+ int result = socket_1_->Write(packet, kMessageSize, &write_cb_);
+ HandleWriteResult(result);
+ }
+
+ void OnWritten(int result) {
+ HandleWriteResult(result);
+ }
+
+ void HandleWriteResult(int result) {
+ if (result <= 0 && result != net::ERR_IO_PENDING) {
+ LOG(ERROR) << "Received error " << result << " when trying to write";
+ write_errors_++;
+ done_event_.Signal();
+ } else if (result > 0) {
+ EXPECT_EQ(kMessageSize, result);
+ packets_sent_++;
+ message_loop_->PostDelayedTask(
+ FROM_HERE, NewRunnableMethod(this, &UDPChannelTester::DoWrite),
+ kUdpWriteDelayMs);
+ }
+ }
+
+ virtual void DoRead() {
+ int result = 1;
+ while (result > 0) {
+ int kReadSize = kMessageSize * 2;
+ read_buffer_ = new net::IOBuffer(kReadSize);
+
+ result = socket_2_->Read(read_buffer_, kReadSize, &read_cb_);
+ HandleReadResult(result);
+ };
+ }
+
+ void OnRead(int result) {
+ HandleReadResult(result);
+ DoRead();
+ }
+
+ void HandleReadResult(int result) {
+ if (result <= 0 && result != net::ERR_IO_PENDING) {
+ // Error will be received after the socket is closed.
+ if (!done_event_.IsSignaled()) {
+ LOG(ERROR) << "Received error " << result << " when trying to read";
+ read_errors_++;
+ done_event_.Signal();
+ }
+ } else if (result > 0) {
+ packets_received_++;
+ if (kMessageSize != result) {
+ // Invalid packet size;
+ broken_packets_++;
+ } else {
+ // Validate packet body.
+ int packet_id;
+ memcpy(&packet_id, read_buffer_->data(), sizeof(packet_id));
+ if (packet_id < 0 || packet_id >= kMessages) {
+ broken_packets_++;
+ } else {
+ if (memcmp(read_buffer_->data(), sent_packets_[packet_id]->data(),
+ kMessageSize) != 0)
+ broken_packets_++;
+ }
+ }
+ }
+ }
+
+ private:
+ scoped_refptr<net::IOBuffer> sent_packets_[kMessages];
+ scoped_refptr<net::IOBuffer> read_buffer_;
+
+ net::CompletionCallbackImpl<UDPChannelTester> write_cb_;
+ net::CompletionCallbackImpl<UDPChannelTester> read_cb_;
+ int write_errors_;
+ int read_errors_;
+ int packets_sent_;
+ int packets_received_;
+ int broken_packets_;
+};
+
+// Verify that we can create and destory server objects without a connection.
+TEST_F(JingleChromotingConnectionTest, CreateAndDestoy) {
+ CreateServerPair();
+}
+
+// Verify that incoming connection can be rejected, and that the status
+// of the connection is set to CLOSED in this case.
+TEST_F(JingleChromotingConnectionTest, RejectConnection) {
+ CreateServerPair();
+
+ // Reject incoming connection.
+ EXPECT_CALL(host_server_callback_, OnNewConnection(_, _))
+ .WillOnce(SetArgumentPointee<1>(false));
+
+ base::WaitableEvent done_event(false, false);
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(ChromotingConnection::CONNECTING))
+ .Times(1);
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(ChromotingConnection::CLOSED))
+ .Times(1)
+ .WillOnce(InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal));
+
+ client_connection_ = client_server_->Connect(
+ SessionManagerPair::kHostJid,
+ NewCallback(&client_connection_callback_,
+ &MockConnectionCallback::OnStateChange));
+
+ done_event.TimedWait(
+ base::TimeDelta::FromMilliseconds(kConnectionTimeoutMs));
+}
+
+// Verify that we can connect two endpoints.
+TEST_F(JingleChromotingConnectionTest, Connect) {
+ CreateServerPair();
+ InitiateConnection();
+}
+
+// Verify that data can be transmitted over the video channel.
+TEST_F(JingleChromotingConnectionTest, TestVideoChannel) {
+ CreateServerPair();
+ InitiateConnection();
+ scoped_refptr<TCPChannelTester> tester =
+ new TCPChannelTester(thread_.message_loop(), host_connection_,
+ client_connection_);
+ tester->Start(ChannelTesterBase::VIDEO);
+ tester->WaitFinished();
+ tester->CheckResults();
+
+ // Connections must be closed while |tester| still exists.
+ CloseConnections();
+}
+
+// Verify that data can be transmitted over the events channel.
+TEST_F(JingleChromotingConnectionTest, TestEventsChannel) {
+ CreateServerPair();
+ InitiateConnection();
+ scoped_refptr<TCPChannelTester> tester =
+ new TCPChannelTester(thread_.message_loop(), host_connection_,
+ client_connection_);
+ tester->Start(ChannelTesterBase::EVENTS);
+ tester->WaitFinished();
+ tester->CheckResults();
+
+ // Connections must be closed while |tester| still exists.
+ CloseConnections();
+}
+
+// Verify that data can be transmitted over the video RTP channel.
+TEST_F(JingleChromotingConnectionTest, TestVideoRtpChannel) {
+ CreateServerPair();
+ InitiateConnection();
+ scoped_refptr<UDPChannelTester> tester =
+ new UDPChannelTester(thread_.message_loop(), host_connection_,
+ client_connection_);
+ tester->Start(ChannelTesterBase::VIDEO_RTP);
+ tester->WaitFinished();
+ tester->CheckResults();
+
+ // Connections must be closed while |tester| still exists.
+ CloseConnections();
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/jingle_chromoting_server.cc b/remoting/protocol/jingle_chromoting_server.cc
index 851221f..517967f 100644
--- a/remoting/protocol/jingle_chromoting_server.cc
+++ b/remoting/protocol/jingle_chromoting_server.cc
@@ -6,6 +6,7 @@
#include "base/message_loop.h"
#include "remoting/base/constants.h"
+#include "third_party/libjingle/source/talk/p2p/base/constants.h"
#include "third_party/libjingle/source/talk/p2p/base/transport.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
@@ -125,7 +126,7 @@ void JingleChromotingServer::OnSessionCreate(
DCHECK_EQ(message_loop(), MessageLoop::current());
// Allow local connections if neccessary.
- session->transport()->set_allow_local_ips(allow_local_ips_);
+ session->set_allow_local_ips(allow_local_ips_);
// If this is an outcoming session, the the connection object is already
// created.
@@ -161,10 +162,11 @@ void JingleChromotingServer::AcceptConnection(
if (accept)
session->Accept(CreateSessionDescription());
else
- session->Reject();
+ session->Reject(cricket::STR_TERMINATE_DECLINE);
}
bool JingleChromotingServer::ParseContent(
+ cricket::SignalingProtocol protocol,
const buzz::XmlElement* element,
const cricket::ContentDescription** content,
cricket::ParseError* error) {
@@ -190,6 +192,7 @@ bool JingleChromotingServer::ParseContent(
// TODO(sergeyu): Add more information to the content description. E.g.
// protocol version, etc.
bool JingleChromotingServer::WriteContent(
+ cricket::SignalingProtocol protocol,
const cricket::ContentDescription* content,
buzz::XmlElement** elem,
cricket::WriteError* error) {
diff --git a/remoting/protocol/jingle_chromoting_server.h b/remoting/protocol/jingle_chromoting_server.h
index 7a6fd84..7dff47d 100644
--- a/remoting/protocol/jingle_chromoting_server.h
+++ b/remoting/protocol/jingle_chromoting_server.h
@@ -86,10 +86,12 @@ class JingleChromotingServer
bool received_initiate);
virtual void OnSessionDestroy(cricket::Session* session);
- virtual bool ParseContent(const buzz::XmlElement* elem,
+ virtual bool ParseContent(cricket::SignalingProtocol protocol,
+ const buzz::XmlElement* elem,
const cricket::ContentDescription** content,
cricket::ParseError* error);
- virtual bool WriteContent(const cricket::ContentDescription* content,
+ virtual bool WriteContent(cricket::SignalingProtocol protocol,
+ const cricket::ContentDescription* content,
buzz::XmlElement** elem,
cricket::WriteError* error);
diff --git a/remoting/protocol/session_manager_pair.cc b/remoting/protocol/session_manager_pair.cc
new file mode 100644
index 0000000..2a1308c
--- /dev/null
+++ b/remoting/protocol/session_manager_pair.cc
@@ -0,0 +1,91 @@
+// Copyright (c) 2010 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/session_manager_pair.h"
+
+#include "base/logging.h"
+#include "remoting/jingle_glue/jingle_thread.h"
+#include "third_party/libjingle/source/talk/base/network.h"
+#include "third_party/libjingle/source/talk/p2p/base/sessionmanager.h"
+#include "third_party/libjingle/source/talk/p2p/client/basicportallocator.h"
+#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
+
+namespace remoting {
+
+const char SessionManagerPair::kHostJid[] = "host1@gmail.com/123";
+const char SessionManagerPair::kClientJid[] = "host2@gmail.com/321";
+
+SessionManagerPair::SessionManagerPair(JingleThread* thread)
+ : message_loop_(thread->message_loop()) {
+}
+
+void SessionManagerPair::Init() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ network_manager_.reset(new talk_base::NetworkManager());
+
+ cricket::BasicPortAllocator* port_allocator =
+ new cricket::BasicPortAllocator(network_manager_.get());
+ port_allocator_.reset(port_allocator);
+
+ host_session_manager_.reset(new cricket::SessionManager(port_allocator));
+ host_session_manager_->SignalOutgoingMessage.connect(
+ this, &SessionManagerPair::ProcessMessage);
+ host_session_manager_->SignalRequestSignaling.connect(
+ host_session_manager_.get(), &cricket::SessionManager::OnSignalingReady);
+
+ client_session_manager_.reset(new cricket::SessionManager(port_allocator));
+ client_session_manager_->SignalOutgoingMessage.connect(
+ this, &SessionManagerPair::ProcessMessage);
+ client_session_manager_->SignalRequestSignaling.connect(
+ client_session_manager_.get(),
+ &cricket::SessionManager::OnSignalingReady);
+}
+
+cricket::SessionManager* SessionManagerPair::host_session_manager() {
+ return host_session_manager_.get();
+}
+
+cricket::SessionManager* SessionManagerPair::client_session_manager() {
+ return client_session_manager_.get();
+}
+
+void SessionManagerPair::ProcessMessage(cricket::SessionManager* manager,
+ const buzz::XmlElement* stanza) {
+ message_loop_->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &SessionManagerPair::DoProcessMessage,
+ manager, new buzz::XmlElement(*stanza)));
+}
+
+void SessionManagerPair::DoProcessMessage(cricket::SessionManager* manager,
+ buzz::XmlElement* stanza) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK(manager == host_session_manager_.get() ||
+ manager == client_session_manager_.get());
+ buzz::QName from_attr("", "from");
+ buzz::QName to_attr("", "to");
+ std::string to = stanza->Attr(to_attr);
+ if (to == kHostJid) {
+ DCHECK(manager == client_session_manager_.get());
+ stanza->SetAttr(from_attr, kClientJid);
+ DeliverMessage(host_session_manager_.get(), stanza);
+ } else if (to == kClientJid) {
+ DCHECK(manager == host_session_manager_.get());
+ stanza->SetAttr(from_attr, kHostJid);
+ DeliverMessage(client_session_manager_.get(), stanza);
+ } else {
+ LOG(ERROR) << "Dropping stanza sent to unknown jid " << to;
+ }
+ delete stanza;
+}
+
+void SessionManagerPair::DeliverMessage(cricket::SessionManager* to,
+ buzz::XmlElement* stanza) {
+ if (to->IsSessionMessage(stanza)) {
+ to->OnIncomingMessage(stanza);
+ }
+}
+
+
+} // namespace remoting
diff --git a/remoting/protocol/session_manager_pair.h b/remoting/protocol/session_manager_pair.h
new file mode 100644
index 0000000..8fe0416
--- /dev/null
+++ b/remoting/protocol/session_manager_pair.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 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.
+
+// SessionManagerPair class is used by unittests to create a pair of session
+// managers connected to each other. These session managers are then can be
+// passed to a pair of JingleChromotingConnection objects, so that it is
+// possible to simulate connection between host and client.
+
+#ifndef REMOTING_PROTOCOL_MOCK_SESSION_MANAGER_H_
+#define REMOTING_PROTOCOL_MOCK_SESSION_MANAGER_H_
+
+#include <base/ref_counted.h>
+#include <base/scoped_ptr.h>
+
+#include "third_party/libjingle/source/talk/base/sigslot.h"
+
+class MessageLoop;
+
+namespace buzz {
+class XmlElement;
+} // namespace buzz
+
+namespace cricket {
+class BasicPortAllocator;
+class SessionManager;
+} // namespace cricket
+
+namespace talk_base {
+class NetworkManager;
+} // namespace talk_base
+
+namespace remoting {
+
+class JingleThread;
+
+class SessionManagerPair
+ : public sigslot::has_slots<>,
+ public base::RefCountedThreadSafe<SessionManagerPair>{
+ public:
+ static const char kHostJid[];
+ static const char kClientJid[];
+
+ SessionManagerPair(JingleThread* thread);
+
+ void Init();
+
+ // The session managers are named 'host' and 'client' just for convenience.
+ // Both can be used for client or host.
+ cricket::SessionManager* host_session_manager();
+ cricket::SessionManager* client_session_manager();
+
+ private:
+ void ProcessMessage(cricket::SessionManager* manager,
+ const buzz::XmlElement* stanza);
+ void DoProcessMessage(cricket::SessionManager* manager,
+ buzz::XmlElement* stanza);
+ void DeliverMessage(cricket::SessionManager* to,
+ buzz::XmlElement* stanza);
+
+ MessageLoop* message_loop_;
+ scoped_ptr<talk_base::NetworkManager> network_manager_;
+ scoped_ptr<cricket::BasicPortAllocator> port_allocator_;
+ scoped_ptr<cricket::SessionManager> host_session_manager_;
+ scoped_ptr<cricket::SessionManager> client_session_manager_;
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_MOCK_SESSION_MANAGER_H_
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 7a87ce0..1d57e6e 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -387,6 +387,7 @@
'chromoting_client',
'chromoting_host',
'chromoting_jingle_glue',
+ 'chromoting_protocol',
'../base/base.gyp:base',
'../base/base.gyp:base_i18n',
'../base/base.gyp:test_support_base',
@@ -426,11 +427,16 @@
'host/mock_objects.h',
'host/session_manager_unittest.cc',
'host/test_key_pair.h',
+ 'jingle_glue/channel_socket_adapter_unittest.cc',
'jingle_glue/jingle_client_unittest.cc',
'jingle_glue/jingle_channel_unittest.cc',
'jingle_glue/jingle_thread_unittest.cc',
'jingle_glue/iq_request_unittest.cc',
'jingle_glue/mock_objects.h',
+ 'jingle_glue/stream_socket_adapter_unittest.cc',
+ 'protocol/jingle_chromoting_connection_unittest.cc',
+ 'protocol/session_manager_pair.cc',
+ 'protocol/session_manager_pair.h',
'run_all_unittests.cc',
],
'conditions': [