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
;
258 EXPECT_CALL(cb1
, OnDone(_
))
260 EXPECT_CALL(cb2
, OnDone(_
))
263 EXPECT_EQ(net::ERR_FAILED
,
264 host_socket1_
->Write(buf
.get(),
266 base::Bind(&MockSocketCallback::OnDone
,
267 base::Unretained(&cb1
))));
268 EXPECT_EQ(net::ERR_FAILED
,
269 host_socket2_
->Write(buf
.get(),
271 base::Bind(&MockSocketCallback::OnDone
,
272 base::Unretained(&cb2
))));
274 base::RunLoop().RunUntilIdle();
277 TEST_F(ChannelMultiplexerTest
, WriteFailAsync
) {
278 ASSERT_NO_FATAL_FAILURE(
279 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
281 ASSERT_NO_FATAL_FAILURE(
282 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
286 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
287 set_next_write_error(net::ERR_FAILED
);
288 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
289 set_async_write(true);
291 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
293 MockSocketCallback cb1
;
294 MockSocketCallback cb2
;
295 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
));
296 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
));
298 EXPECT_EQ(net::ERR_IO_PENDING
,
299 host_socket1_
->Write(buf
.get(),
301 base::Bind(&MockSocketCallback::OnDone
,
302 base::Unretained(&cb1
))));
303 EXPECT_EQ(net::ERR_IO_PENDING
,
304 host_socket2_
->Write(buf
.get(),
306 base::Bind(&MockSocketCallback::OnDone
,
307 base::Unretained(&cb2
))));
309 base::RunLoop().RunUntilIdle();
312 TEST_F(ChannelMultiplexerTest
, DeleteWhenFailed
) {
313 ASSERT_NO_FATAL_FAILURE(
314 CreateChannel(kTestChannelName
, &host_socket1_
, &client_socket1_
));
315 ASSERT_NO_FATAL_FAILURE(
316 CreateChannel(kTestChannelName2
, &host_socket2_
, &client_socket2_
));
320 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
321 set_next_write_error(net::ERR_FAILED
);
322 host_session_
.fake_channel_factory().GetFakeChannel(kMuxChannelName
)->
323 set_async_write(true);
325 scoped_refptr
<net::IOBufferWithSize
> buf
= CreateTestBuffer(100);
327 MockSocketCallback cb1
;
328 MockSocketCallback cb2
;
330 EXPECT_CALL(cb1
, OnDone(net::ERR_FAILED
))
332 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll
));
333 EXPECT_CALL(cb2
, OnDone(net::ERR_FAILED
))
335 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll
));
337 EXPECT_EQ(net::ERR_IO_PENDING
,
338 host_socket1_
->Write(buf
.get(),
340 base::Bind(&MockSocketCallback::OnDone
,
341 base::Unretained(&cb1
))));
342 EXPECT_EQ(net::ERR_IO_PENDING
,
343 host_socket2_
->Write(buf
.get(),
345 base::Bind(&MockSocketCallback::OnDone
,
346 base::Unretained(&cb2
))));
348 base::RunLoop().RunUntilIdle();
350 // Check that the sockets were destroyed.
351 EXPECT_FALSE(host_mux_
.get());
354 TEST_F(ChannelMultiplexerTest
, SessionFail
) {
355 host_session_
.fake_channel_factory().set_asynchronous_create(true);
356 host_session_
.fake_channel_factory().set_fail_create(true);
358 MockConnectCallback cb1
;
359 MockConnectCallback cb2
;
361 host_mux_
->CreateChannel(kTestChannelName
, base::Bind(
362 &MockConnectCallback::OnConnected
, base::Unretained(&cb1
)));
363 host_mux_
->CreateChannel(kTestChannelName2
, base::Bind(
364 &MockConnectCallback::OnConnected
, base::Unretained(&cb2
)));
366 EXPECT_CALL(cb1
, OnConnectedPtr(nullptr))
368 .WillOnce(InvokeWithoutArgs(
369 this, &ChannelMultiplexerTest::DeleteAfterSessionFail
));
370 EXPECT_CALL(cb2
, OnConnectedPtr(_
))
373 base::RunLoop().RunUntilIdle();
376 } // namespace protocol
377 } // namespace remoting