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 "base/run_loop.h"
10 #include "net/base/net_errors.h"
11 #include "net/socket/socket.h"
12 #include "net/socket/stream_socket.h"
13 #include "remoting/base/constants.h"
14 #include "remoting/protocol/connection_tester.h"
15 #include "remoting/protocol/fake_session.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::AtMost
;
21 using testing::InvokeWithoutArgs
;
28 const int kMessageSize
= 1024;
29 const int kMessages
= 100;
30 const char kMuxChannelName
[] = "mux";
32 const char kTestChannelName
[] = "test";
33 const char kTestChannelName2
[] = "test2";
36 void QuitCurrentThread() {
37 base::MessageLoop::current()->PostTask(FROM_HERE
,
38 base::MessageLoop::QuitClosure());
41 class MockSocketCallback
{
43 MOCK_METHOD1(OnDone
, void(int result
));
46 class MockConnectCallback
{
48 MOCK_METHOD1(OnConnectedPtr
, void(P2PStreamSocket
* socket
));
49 void OnConnected(scoped_ptr
<P2PStreamSocket
> socket
) {
50 OnConnectedPtr(socket
.release());
56 class ChannelMultiplexerTest
: public testing::Test
{
59 host_socket1_
.reset();
60 host_socket2_
.reset();
61 client_socket1_
.reset();
62 client_socket2_
.reset();
67 void DeleteAfterSessionFail() {
68 host_mux_
->CancelChannelCreation(kTestChannelName2
);
73 void SetUp() override
{
74 // Create pair of multiplexers and connect them to each other.
75 host_mux_
.reset(new ChannelMultiplexer(
76 host_session_
.GetTransportChannelFactory(), kMuxChannelName
));
77 client_mux_
.reset(new ChannelMultiplexer(
78 client_session_
.GetTransportChannelFactory(), kMuxChannelName
));
81 // Connect sockets to each other. Must be called after we've created at least
82 // one channel with each multiplexer.
83 void ConnectSockets() {
84 FakeStreamSocket
* host_socket
=
85 host_session_
.fake_channel_factory().GetFakeChannel(
86 ChannelMultiplexer::kMuxChannelName
);
87 FakeStreamSocket
* client_socket
=
88 client_session_
.fake_channel_factory().GetFakeChannel(
89 ChannelMultiplexer::kMuxChannelName
);
90 host_socket
->PairWith(client_socket
);
92 // Make writes asynchronous in one direction.
93 host_socket
->set_async_write(true);
96 void CreateChannel(const std::string
& name
,
97 scoped_ptr
<P2PStreamSocket
>* host_socket
,
98 scoped_ptr
<P2PStreamSocket
>* client_socket
) {
100 host_mux_
->CreateChannel(name
, base::Bind(
101 &ChannelMultiplexerTest::OnChannelConnected
, base::Unretained(this),
102 host_socket
, &counter
));
103 client_mux_
->CreateChannel(name
, base::Bind(
104 &ChannelMultiplexerTest::OnChannelConnected
, base::Unretained(this),
105 client_socket
, &counter
));
109 EXPECT_TRUE(host_socket
->get());
110 EXPECT_TRUE(client_socket
->get());
113 void OnChannelConnected(
114 scoped_ptr
<P2PStreamSocket
>* storage
,
116 scoped_ptr
<P2PStreamSocket
> socket
) {
117 *storage
= socket
.Pass();
119 EXPECT_GE(*counter
, 0);
124 scoped_refptr
<net::IOBufferWithSize
> CreateTestBuffer(int size
) {
125 scoped_refptr
<net::IOBufferWithSize
> result
=
126 new net::IOBufferWithSize(size
);
127 for (int i
= 0; i
< size
; ++i
) {
128 result
->data()[i
] = rand() % 256;
133 base::MessageLoop message_loop_
;
135 FakeSession host_session_
;
136 FakeSession client_session_
;
138 scoped_ptr
<ChannelMultiplexer
> host_mux_
;
139 scoped_ptr
<ChannelMultiplexer
> client_mux_
;
141 scoped_ptr
<P2PStreamSocket
> host_socket1_
;
142 scoped_ptr
<P2PStreamSocket
> client_socket1_
;
143 scoped_ptr
<P2PStreamSocket
> host_socket2_
;
144 scoped_ptr
<P2PStreamSocket
> client_socket2_
;
148 TEST_F(ChannelMultiplexerTest
, OneChannel
) {
149 scoped_ptr
<P2PStreamSocket
> host_socket
;
150 scoped_ptr
<P2PStreamSocket
> client_socket
;
151 ASSERT_NO_FATAL_FAILURE(
152 CreateChannel(kTestChannelName
, &host_socket
, &client_socket
));
156 StreamConnectionTester
tester(host_socket
.get(), client_socket
.get(),
157 kMessageSize
, kMessages
);
160 tester
.CheckResults();
163 TEST_F(ChannelMultiplexerTest
, TwoChannels
) {
164 scoped_ptr
<P2PStreamSocket
> host_socket1_
;
165 scoped_ptr
<P2PStreamSocket
> client_socket1_
;
166 ASSERT_NO_FATAL_FAILURE(
167 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
169 scoped_ptr
<P2PStreamSocket
> host_socket2_
;
170 scoped_ptr
<P2PStreamSocket
> client_socket2_
;
171 ASSERT_NO_FATAL_FAILURE(
172 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
176 StreamConnectionTester
tester1(host_socket1_
.get(), client_socket1_
.get(),
177 kMessageSize
, kMessages
);
178 StreamConnectionTester
tester2(host_socket2_
.get(), client_socket2_
.get(),
179 kMessageSize
, kMessages
);
182 while (!tester1
.done() || !tester2
.done()) {
185 tester1
.CheckResults();
186 tester2
.CheckResults();
189 // Four channels, two in each direction
190 TEST_F(ChannelMultiplexerTest
, FourChannels
) {
191 scoped_ptr
<P2PStreamSocket
> host_socket1_
;
192 scoped_ptr
<P2PStreamSocket
> client_socket1_
;
193 ASSERT_NO_FATAL_FAILURE(
194 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
196 scoped_ptr
<P2PStreamSocket
> host_socket2_
;
197 scoped_ptr
<P2PStreamSocket
> client_socket2_
;
198 ASSERT_NO_FATAL_FAILURE(
199 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
201 scoped_ptr
<P2PStreamSocket
> host_socket3
;
202 scoped_ptr
<P2PStreamSocket
> client_socket3
;
203 ASSERT_NO_FATAL_FAILURE(
204 CreateChannel("test3", &host_socket3
, &client_socket3
));
206 scoped_ptr
<P2PStreamSocket
> host_socket4
;
207 scoped_ptr
<P2PStreamSocket
> client_socket4
;
208 ASSERT_NO_FATAL_FAILURE(
209 CreateChannel("ch4", &host_socket4
, &client_socket4
));
213 StreamConnectionTester
tester1(host_socket1_
.get(), client_socket1_
.get(),
214 kMessageSize
, kMessages
);
215 StreamConnectionTester
tester2(host_socket2_
.get(), client_socket2_
.get(),
216 kMessageSize
, kMessages
);
217 StreamConnectionTester
tester3(client_socket3
.get(), host_socket3
.get(),
218 kMessageSize
, kMessages
);
219 StreamConnectionTester
tester4(client_socket4
.get(), host_socket4
.get(),
220 kMessageSize
, kMessages
);
225 while (!tester1
.done() || !tester2
.done() ||
226 !tester3
.done() || !tester4
.done()) {
229 tester1
.CheckResults();
230 tester2
.CheckResults();
231 tester3
.CheckResults();
232 tester4
.CheckResults();
235 TEST_F(ChannelMultiplexerTest
, WriteFailSync
) {
236 scoped_ptr
<P2PStreamSocket
> host_socket1_
;
237 scoped_ptr
<P2PStreamSocket
> client_socket1_
;
238 ASSERT_NO_FATAL_FAILURE(
239 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
241 scoped_ptr
<P2PStreamSocket
> host_socket2_
;
242 scoped_ptr
<P2PStreamSocket
> client_socket2_
;
243 ASSERT_NO_FATAL_FAILURE(
244 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
248 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
249 set_next_write_error(net::ERR_FAILED
);
250 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
251 set_async_write(false);
253 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
255 MockSocketCallback cb1
;
256 MockSocketCallback cb2
;
257 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
));
258 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
));
260 EXPECT_EQ(net::ERR_IO_PENDING
,
261 host_socket1_
->Write(buf
.get(),
263 base::Bind(&MockSocketCallback::OnDone
,
264 base::Unretained(&cb1
))));
265 EXPECT_EQ(net::ERR_IO_PENDING
,
266 host_socket2_
->Write(buf
.get(),
268 base::Bind(&MockSocketCallback::OnDone
,
269 base::Unretained(&cb2
))));
271 base::RunLoop().RunUntilIdle();
274 TEST_F(ChannelMultiplexerTest
, WriteFailAsync
) {
275 ASSERT_NO_FATAL_FAILURE(
276 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
278 ASSERT_NO_FATAL_FAILURE(
279 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
283 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
284 set_next_write_error(net::ERR_FAILED
);
285 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
286 set_async_write(true);
288 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
290 MockSocketCallback cb1
;
291 MockSocketCallback cb2
;
292 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
));
293 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
));
295 EXPECT_EQ(net::ERR_IO_PENDING
,
296 host_socket1_
->Write(buf
.get(),
298 base::Bind(&MockSocketCallback::OnDone
,
299 base::Unretained(&cb1
))));
300 EXPECT_EQ(net::ERR_IO_PENDING
,
301 host_socket2_
->Write(buf
.get(),
303 base::Bind(&MockSocketCallback::OnDone
,
304 base::Unretained(&cb2
))));
306 base::RunLoop().RunUntilIdle();
309 TEST_F(ChannelMultiplexerTest
, DeleteWhenFailed
) {
310 ASSERT_NO_FATAL_FAILURE(
311 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
312 ASSERT_NO_FATAL_FAILURE(
313 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
317 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
318 set_next_write_error(net::ERR_FAILED
);
319 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
320 set_async_write(true);
322 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
324 MockSocketCallback cb1
;
325 MockSocketCallback cb2
;
327 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
))
329 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll
));
330 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
))
332 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll
));
334 EXPECT_EQ(net::ERR_IO_PENDING
,
335 host_socket1_
->Write(buf
.get(),
337 base::Bind(&MockSocketCallback::OnDone
,
338 base::Unretained(&cb1
))));
339 EXPECT_EQ(net::ERR_IO_PENDING
,
340 host_socket2_
->Write(buf
.get(),
342 base::Bind(&MockSocketCallback::OnDone
,
343 base::Unretained(&cb2
))));
345 base::RunLoop().RunUntilIdle();
347 // Check that the sockets were destroyed.
348 EXPECT_FALSE(host_mux_
.get());
351 TEST_F(ChannelMultiplexerTest
, SessionFail
) {
352 host_session_
.fake_channel_factory().set_asynchronous_create(true);
353 host_session_
.fake_channel_factory().set_fail_create(true);
355 MockConnectCallback cb1
;
356 MockConnectCallback cb2
;
358 host_mux_
->CreateChannel(kTestChannelName
, base::Bind(
359 &MockConnectCallback::OnConnected
, base::Unretained(&cb1
)));
360 host_mux_
->CreateChannel(kTestChannelName2
, base::Bind(
361 &MockConnectCallback::OnConnected
, base::Unretained(&cb2
)));
363 EXPECT_CALL(cb1
, OnConnectedPtr(nullptr))
365 .WillOnce(InvokeWithoutArgs(
366 this, &ChannelMultiplexerTest::DeleteAfterSessionFail
));
367 EXPECT_CALL(cb2
, OnConnectedPtr(_
))
370 base::RunLoop().RunUntilIdle();
373 } // namespace protocol
374 } // namespace remoting