1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/protocol/channel_multiplexer.h"
8 #include "base/message_loop/message_loop.h"
9 #include "net/base/net_errors.h"
10 #include "net/socket/socket.h"
11 #include "net/socket/stream_socket.h"
12 #include "remoting/base/constants.h"
13 #include "remoting/protocol/connection_tester.h"
14 #include "remoting/protocol/fake_session.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
19 using testing::AtMost
;
20 using testing::InvokeWithoutArgs
;
27 const int kMessageSize
= 1024;
28 const int kMessages
= 100;
29 const char kMuxChannelName
[] = "mux";
31 const char kTestChannelName
[] = "test";
32 const char kTestChannelName2
[] = "test2";
35 void QuitCurrentThread() {
36 base::MessageLoop::current()->PostTask(FROM_HERE
,
37 base::MessageLoop::QuitClosure());
40 class MockSocketCallback
{
42 MOCK_METHOD1(OnDone
, void(int result
));
45 class MockConnectCallback
{
47 MOCK_METHOD1(OnConnectedPtr
, void(net::StreamSocket
* socket
));
48 void OnConnected(scoped_ptr
<net::StreamSocket
> socket
) {
49 OnConnectedPtr(socket
.release());
55 class ChannelMultiplexerTest
: public testing::Test
{
58 host_socket1_
.reset();
59 host_socket2_
.reset();
60 client_socket1_
.reset();
61 client_socket2_
.reset();
66 void DeleteAfterSessionFail() {
67 host_mux_
->CancelChannelCreation(kTestChannelName2
);
72 virtual void SetUp() OVERRIDE
{
73 // Create pair of multiplexers and connect them to each other.
74 host_mux_
.reset(new ChannelMultiplexer(&host_session_
, kMuxChannelName
));
75 client_mux_
.reset(new ChannelMultiplexer(&client_session_
,
79 // Connect sockets to each other. Must be called after we've created at least
80 // one channel with each multiplexer.
81 void ConnectSockets() {
82 FakeSocket
* host_socket
=
83 host_session_
.GetStreamChannel(ChannelMultiplexer::kMuxChannelName
);
84 FakeSocket
* client_socket
=
85 client_session_
.GetStreamChannel(ChannelMultiplexer::kMuxChannelName
);
86 host_socket
->PairWith(client_socket
);
88 // Make writes asynchronous in one direction.
89 host_socket
->set_async_write(true);
92 void CreateChannel(const std::string
& name
,
93 scoped_ptr
<net::StreamSocket
>* host_socket
,
94 scoped_ptr
<net::StreamSocket
>* client_socket
) {
96 host_mux_
->CreateStreamChannel(name
, base::Bind(
97 &ChannelMultiplexerTest::OnChannelConnected
, base::Unretained(this),
98 host_socket
, &counter
));
99 client_mux_
->CreateStreamChannel(name
, base::Bind(
100 &ChannelMultiplexerTest::OnChannelConnected
, base::Unretained(this),
101 client_socket
, &counter
));
105 EXPECT_TRUE(host_socket
->get());
106 EXPECT_TRUE(client_socket
->get());
109 void OnChannelConnected(
110 scoped_ptr
<net::StreamSocket
>* storage
,
112 scoped_ptr
<net::StreamSocket
> socket
) {
113 *storage
= socket
.Pass();
115 EXPECT_GE(*counter
, 0);
120 scoped_refptr
<net::IOBufferWithSize
> CreateTestBuffer(int size
) {
121 scoped_refptr
<net::IOBufferWithSize
> result
=
122 new net::IOBufferWithSize(size
);
123 for (int i
= 0; i
< size
; ++i
) {
124 result
->data()[i
] = rand() % 256;
129 base::MessageLoop message_loop_
;
131 FakeSession host_session_
;
132 FakeSession client_session_
;
134 scoped_ptr
<ChannelMultiplexer
> host_mux_
;
135 scoped_ptr
<ChannelMultiplexer
> client_mux_
;
137 scoped_ptr
<net::StreamSocket
> host_socket1_
;
138 scoped_ptr
<net::StreamSocket
> client_socket1_
;
139 scoped_ptr
<net::StreamSocket
> host_socket2_
;
140 scoped_ptr
<net::StreamSocket
> client_socket2_
;
144 TEST_F(ChannelMultiplexerTest
, OneChannel
) {
145 scoped_ptr
<net::StreamSocket
> host_socket
;
146 scoped_ptr
<net::StreamSocket
> client_socket
;
147 ASSERT_NO_FATAL_FAILURE(
148 CreateChannel(kTestChannelName
, &host_socket
, &client_socket
));
152 StreamConnectionTester
tester(host_socket
.get(), client_socket
.get(),
153 kMessageSize
, kMessages
);
156 tester
.CheckResults();
159 TEST_F(ChannelMultiplexerTest
, TwoChannels
) {
160 scoped_ptr
<net::StreamSocket
> host_socket1_
;
161 scoped_ptr
<net::StreamSocket
> client_socket1_
;
162 ASSERT_NO_FATAL_FAILURE(
163 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
165 scoped_ptr
<net::StreamSocket
> host_socket2_
;
166 scoped_ptr
<net::StreamSocket
> client_socket2_
;
167 ASSERT_NO_FATAL_FAILURE(
168 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
172 StreamConnectionTester
tester1(host_socket1_
.get(), client_socket1_
.get(),
173 kMessageSize
, kMessages
);
174 StreamConnectionTester
tester2(host_socket2_
.get(), client_socket2_
.get(),
175 kMessageSize
, kMessages
);
178 while (!tester1
.done() || !tester2
.done()) {
181 tester1
.CheckResults();
182 tester2
.CheckResults();
185 // Four channels, two in each direction
186 TEST_F(ChannelMultiplexerTest
, FourChannels
) {
187 scoped_ptr
<net::StreamSocket
> host_socket1_
;
188 scoped_ptr
<net::StreamSocket
> client_socket1_
;
189 ASSERT_NO_FATAL_FAILURE(
190 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
192 scoped_ptr
<net::StreamSocket
> host_socket2_
;
193 scoped_ptr
<net::StreamSocket
> client_socket2_
;
194 ASSERT_NO_FATAL_FAILURE(
195 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
197 scoped_ptr
<net::StreamSocket
> host_socket3
;
198 scoped_ptr
<net::StreamSocket
> client_socket3
;
199 ASSERT_NO_FATAL_FAILURE(
200 CreateChannel("test3", &host_socket3
, &client_socket3
));
202 scoped_ptr
<net::StreamSocket
> host_socket4
;
203 scoped_ptr
<net::StreamSocket
> client_socket4
;
204 ASSERT_NO_FATAL_FAILURE(
205 CreateChannel("ch4", &host_socket4
, &client_socket4
));
209 StreamConnectionTester
tester1(host_socket1_
.get(), client_socket1_
.get(),
210 kMessageSize
, kMessages
);
211 StreamConnectionTester
tester2(host_socket2_
.get(), client_socket2_
.get(),
212 kMessageSize
, kMessages
);
213 StreamConnectionTester
tester3(client_socket3
.get(), host_socket3
.get(),
214 kMessageSize
, kMessages
);
215 StreamConnectionTester
tester4(client_socket4
.get(), host_socket4
.get(),
216 kMessageSize
, kMessages
);
221 while (!tester1
.done() || !tester2
.done() ||
222 !tester3
.done() || !tester4
.done()) {
225 tester1
.CheckResults();
226 tester2
.CheckResults();
227 tester3
.CheckResults();
228 tester4
.CheckResults();
231 TEST_F(ChannelMultiplexerTest
, WriteFailSync
) {
232 scoped_ptr
<net::StreamSocket
> host_socket1_
;
233 scoped_ptr
<net::StreamSocket
> client_socket1_
;
234 ASSERT_NO_FATAL_FAILURE(
235 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
237 scoped_ptr
<net::StreamSocket
> host_socket2_
;
238 scoped_ptr
<net::StreamSocket
> client_socket2_
;
239 ASSERT_NO_FATAL_FAILURE(
240 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
244 host_session_
.GetStreamChannel(kMuxChannelName
)->
245 set_next_write_error(net::ERR_FAILED
);
246 host_session_
.GetStreamChannel(kMuxChannelName
)->
247 set_async_write(false);
249 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
251 MockSocketCallback cb1
;
252 MockSocketCallback cb2
;
254 EXPECT_CALL(cb1
, OnDone(_
))
256 EXPECT_CALL(cb2
, OnDone(_
))
259 EXPECT_EQ(net::ERR_FAILED
,
260 host_socket1_
->Write(buf
.get(),
262 base::Bind(&MockSocketCallback::OnDone
,
263 base::Unretained(&cb1
))));
264 EXPECT_EQ(net::ERR_FAILED
,
265 host_socket2_
->Write(buf
.get(),
267 base::Bind(&MockSocketCallback::OnDone
,
268 base::Unretained(&cb2
))));
270 message_loop_
.RunUntilIdle();
273 TEST_F(ChannelMultiplexerTest
, WriteFailAsync
) {
274 ASSERT_NO_FATAL_FAILURE(
275 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
277 ASSERT_NO_FATAL_FAILURE(
278 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
282 host_session_
.GetStreamChannel(kMuxChannelName
)->
283 set_next_write_error(net::ERR_FAILED
);
284 host_session_
.GetStreamChannel(kMuxChannelName
)->
285 set_async_write(true);
287 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
289 MockSocketCallback cb1
;
290 MockSocketCallback cb2
;
291 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
));
292 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
));
294 EXPECT_EQ(net::ERR_IO_PENDING
,
295 host_socket1_
->Write(buf
.get(),
297 base::Bind(&MockSocketCallback::OnDone
,
298 base::Unretained(&cb1
))));
299 EXPECT_EQ(net::ERR_IO_PENDING
,
300 host_socket2_
->Write(buf
.get(),
302 base::Bind(&MockSocketCallback::OnDone
,
303 base::Unretained(&cb2
))));
305 message_loop_
.RunUntilIdle();
308 TEST_F(ChannelMultiplexerTest
, DeleteWhenFailed
) {
309 ASSERT_NO_FATAL_FAILURE(
310 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
311 ASSERT_NO_FATAL_FAILURE(
312 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
316 host_session_
.GetStreamChannel(kMuxChannelName
)->
317 set_next_write_error(net::ERR_FAILED
);
318 host_session_
.GetStreamChannel(kMuxChannelName
)->
319 set_async_write(true);
321 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
323 MockSocketCallback cb1
;
324 MockSocketCallback cb2
;
326 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
))
328 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll
));
329 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
))
331 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll
));
333 EXPECT_EQ(net::ERR_IO_PENDING
,
334 host_socket1_
->Write(buf
.get(),
336 base::Bind(&MockSocketCallback::OnDone
,
337 base::Unretained(&cb1
))));
338 EXPECT_EQ(net::ERR_IO_PENDING
,
339 host_socket2_
->Write(buf
.get(),
341 base::Bind(&MockSocketCallback::OnDone
,
342 base::Unretained(&cb2
))));
344 message_loop_
.RunUntilIdle();
346 // Check that the sockets were destroyed.
347 EXPECT_FALSE(host_mux_
.get());
350 TEST_F(ChannelMultiplexerTest
, SessionFail
) {
351 host_session_
.set_async_creation(true);
352 host_session_
.set_error(AUTHENTICATION_FAILED
);
354 MockConnectCallback cb1
;
355 MockConnectCallback cb2
;
357 host_mux_
->CreateStreamChannel(kTestChannelName
, base::Bind(
358 &MockConnectCallback::OnConnected
, base::Unretained(&cb1
)));
359 host_mux_
->CreateStreamChannel(kTestChannelName2
, base::Bind(
360 &MockConnectCallback::OnConnected
, base::Unretained(&cb2
)));
362 EXPECT_CALL(cb1
, OnConnectedPtr(NULL
))
364 .WillOnce(InvokeWithoutArgs(
365 this, &ChannelMultiplexerTest::DeleteAfterSessionFail
));
366 EXPECT_CALL(cb2
, OnConnectedPtr(_
))
369 message_loop_
.RunUntilIdle();
372 } // namespace protocol
373 } // namespace remoting