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/jingle_session.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/time/time.h"
12 #include "jingle/glue/thread_wrapper.h"
13 #include "net/socket/socket.h"
14 #include "net/socket/stream_socket.h"
15 #include "net/url_request/url_request_context_getter.h"
16 #include "remoting/base/constants.h"
17 #include "remoting/protocol/authenticator.h"
18 #include "remoting/protocol/channel_authenticator.h"
19 #include "remoting/protocol/chromium_port_allocator.h"
20 #include "remoting/protocol/connection_tester.h"
21 #include "remoting/protocol/fake_authenticator.h"
22 #include "remoting/protocol/jingle_session_manager.h"
23 #include "remoting/protocol/libjingle_transport_factory.h"
24 #include "remoting/protocol/network_settings.h"
25 #include "remoting/protocol/stream_channel_factory.h"
26 #include "remoting/signaling/fake_signal_strategy.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
31 using testing::AtLeast
;
32 using testing::AtMost
;
33 using testing::DeleteArg
;
35 using testing::InSequence
;
36 using testing::Invoke
;
37 using testing::InvokeWithoutArgs
;
38 using testing::Return
;
39 using testing::SaveArg
;
40 using testing::SetArgumentPointee
;
41 using testing::WithArg
;
48 const char kHostJid
[] = "host1@gmail.com/123";
49 const char kClientJid
[] = "host2@gmail.com/321";
51 // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
52 // between messages (about 1 second for 100 messages).
53 const int kMessageSize
= 1024;
54 const int kMessages
= 100;
55 const char kChannelName
[] = "test_channel";
57 void QuitCurrentThread() {
58 base::MessageLoop::current()->PostTask(FROM_HERE
,
59 base::MessageLoop::QuitClosure());
66 ACTION_P(QuitThreadOnCounter
, counter
) {
68 EXPECT_GE(*counter
, 0);
73 class MockSessionManagerListener
: public SessionManager::Listener
{
75 MOCK_METHOD0(OnSessionManagerReady
, void());
76 MOCK_METHOD2(OnIncomingSession
,
78 SessionManager::IncomingSessionResponse
*));
81 class MockSessionEventHandler
: public Session::EventHandler
{
83 MOCK_METHOD1(OnSessionStateChange
, void(Session::State
));
84 MOCK_METHOD2(OnSessionRouteChange
, void(const std::string
& channel_name
,
85 const TransportRoute
& route
));
88 class MockChannelCreatedCallback
{
90 MOCK_METHOD1(OnDone
, void(net::StreamSocket
* socket
));
95 class JingleSessionTest
: public testing::Test
{
98 message_loop_
.reset(new base::MessageLoopForIO());
99 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
102 // Helper method that handles OnIncomingSession().
103 void SetHostSession(Session
* session
) {
105 host_session_
.reset(session
);
106 host_session_
->SetEventHandler(&host_session_event_handler_
);
108 session
->set_config(SessionConfig::ForTest());
111 void DeleteSession() {
112 host_session_
.reset();
115 void OnClientChannelCreated(scoped_ptr
<net::StreamSocket
> socket
) {
116 client_channel_callback_
.OnDone(socket
.get());
117 client_socket_
= socket
.Pass();
120 void OnHostChannelCreated(scoped_ptr
<net::StreamSocket
> socket
) {
121 host_channel_callback_
.OnDone(socket
.get());
122 host_socket_
= socket
.Pass();
126 void SetUp() override
{}
128 void TearDown() override
{
130 CloseSessionManager();
131 base::RunLoop().RunUntilIdle();
134 void CloseSessions() {
135 host_socket_
.reset();
136 host_session_
.reset();
137 client_socket_
.reset();
138 client_session_
.reset();
141 void CreateSessionManagers(int auth_round_trips
, int messages_till_start
,
142 FakeAuthenticator::Action auth_action
) {
143 host_signal_strategy_
.reset(new FakeSignalStrategy(kHostJid
));
144 client_signal_strategy_
.reset(new FakeSignalStrategy(kClientJid
));
145 FakeSignalStrategy::Connect(host_signal_strategy_
.get(),
146 client_signal_strategy_
.get());
148 EXPECT_CALL(host_server_listener_
, OnSessionManagerReady())
151 NetworkSettings
network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING
);
153 scoped_ptr
<TransportFactory
> host_transport(new LibjingleTransportFactory(
155 ChromiumPortAllocator::Create(nullptr, network_settings
).Pass(),
157 host_server_
.reset(new JingleSessionManager(host_transport
.Pass()));
158 host_server_
->Init(host_signal_strategy_
.get(), &host_server_listener_
);
160 scoped_ptr
<AuthenticatorFactory
> factory(
161 new FakeHostAuthenticatorFactory(auth_round_trips
,
162 messages_till_start
, auth_action
, true));
163 host_server_
->set_authenticator_factory(factory
.Pass());
165 EXPECT_CALL(client_server_listener_
, OnSessionManagerReady())
167 scoped_ptr
<TransportFactory
> client_transport(new LibjingleTransportFactory(
169 ChromiumPortAllocator::Create(nullptr, network_settings
).Pass(),
171 client_server_
.reset(
172 new JingleSessionManager(client_transport
.Pass()));
173 client_server_
->Init(client_signal_strategy_
.get(),
174 &client_server_listener_
);
177 void CreateSessionManagers(int auth_round_trips
,
178 FakeAuthenticator::Action auth_action
) {
179 CreateSessionManagers(auth_round_trips
, 0, auth_action
);
182 void CloseSessionManager() {
183 if (host_server_
.get()) {
184 host_server_
->Close();
185 host_server_
.reset();
187 if (client_server_
.get()) {
188 client_server_
->Close();
189 client_server_
.reset();
191 host_signal_strategy_
.reset();
192 client_signal_strategy_
.reset();
195 void InitiateConnection(int auth_round_trips
,
196 FakeAuthenticator::Action auth_action
,
198 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
200 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
201 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
206 EXPECT_CALL(host_session_event_handler_
,
207 OnSessionStateChange(Session::CONNECTED
))
209 EXPECT_CALL(host_session_event_handler_
,
210 OnSessionStateChange(Session::AUTHENTICATING
))
213 EXPECT_CALL(host_session_event_handler_
,
214 OnSessionStateChange(Session::FAILED
))
217 EXPECT_CALL(host_session_event_handler_
,
218 OnSessionStateChange(Session::AUTHENTICATED
))
220 // Expect that the connection will be closed eventually.
221 EXPECT_CALL(host_session_event_handler_
,
222 OnSessionStateChange(Session::CLOSED
))
230 EXPECT_CALL(client_session_event_handler_
,
231 OnSessionStateChange(Session::CONNECTED
))
233 EXPECT_CALL(client_session_event_handler_
,
234 OnSessionStateChange(Session::AUTHENTICATING
))
237 EXPECT_CALL(client_session_event_handler_
,
238 OnSessionStateChange(Session::FAILED
))
241 EXPECT_CALL(client_session_event_handler_
,
242 OnSessionStateChange(Session::AUTHENTICATED
))
244 // Expect that the connection will be closed eventually.
245 EXPECT_CALL(client_session_event_handler_
,
246 OnSessionStateChange(Session::CLOSED
))
251 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
252 FakeAuthenticator::CLIENT
, auth_round_trips
, auth_action
, true));
254 client_session_
= client_server_
->Connect(
255 kHostJid
, authenticator
.Pass(),
256 CandidateSessionConfig::CreateDefault());
257 client_session_
->SetEventHandler(&client_session_event_handler_
);
259 base::RunLoop().RunUntilIdle();
262 void CreateChannel() {
263 client_session_
->GetTransportChannelFactory()->CreateChannel(
264 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
265 base::Unretained(this)));
266 host_session_
->GetTransportChannelFactory()->CreateChannel(
267 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
268 base::Unretained(this)));
271 ExpectRouteChange(kChannelName
);
272 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
273 .WillOnce(QuitThreadOnCounter(&counter
));
274 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
275 .WillOnce(QuitThreadOnCounter(&counter
));
276 message_loop_
->Run();
278 EXPECT_TRUE(client_socket_
.get());
279 EXPECT_TRUE(host_socket_
.get());
282 void ExpectRouteChange(const std::string
& channel_name
) {
283 EXPECT_CALL(host_session_event_handler_
,
284 OnSessionRouteChange(channel_name
, _
))
286 EXPECT_CALL(client_session_event_handler_
,
287 OnSessionRouteChange(channel_name
, _
))
291 scoped_ptr
<base::MessageLoopForIO
> message_loop_
;
293 scoped_ptr
<FakeSignalStrategy
> host_signal_strategy_
;
294 scoped_ptr
<FakeSignalStrategy
> client_signal_strategy_
;
296 scoped_ptr
<JingleSessionManager
> host_server_
;
297 MockSessionManagerListener host_server_listener_
;
298 scoped_ptr
<JingleSessionManager
> client_server_
;
299 MockSessionManagerListener client_server_listener_
;
301 scoped_ptr
<Session
> host_session_
;
302 MockSessionEventHandler host_session_event_handler_
;
303 scoped_ptr
<Session
> client_session_
;
304 MockSessionEventHandler client_session_event_handler_
;
306 MockChannelCreatedCallback client_channel_callback_
;
307 MockChannelCreatedCallback host_channel_callback_
;
309 scoped_ptr
<net::StreamSocket
> client_socket_
;
310 scoped_ptr
<net::StreamSocket
> host_socket_
;
314 // Verify that we can create and destroy session managers without a
316 TEST_F(JingleSessionTest
, CreateAndDestoy
) {
317 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
320 // Verify that an incoming session can be rejected, and that the
321 // status of the connection is set to FAILED in this case.
322 TEST_F(JingleSessionTest
, RejectConnection
) {
323 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
325 // Reject incoming session.
326 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
327 .WillOnce(SetArgumentPointee
<1>(protocol::SessionManager::DECLINE
));
331 EXPECT_CALL(client_session_event_handler_
,
332 OnSessionStateChange(Session::FAILED
))
336 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
337 FakeAuthenticator::CLIENT
, 1, FakeAuthenticator::ACCEPT
, true));
338 client_session_
= client_server_
->Connect(
339 kHostJid
, authenticator
.Pass(), CandidateSessionConfig::CreateDefault());
340 client_session_
->SetEventHandler(&client_session_event_handler_
);
342 base::RunLoop().RunUntilIdle();
345 // Verify that we can connect two endpoints with single-step authentication.
346 TEST_F(JingleSessionTest
, Connect
) {
347 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
348 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false);
350 // Verify that the client specified correct initiator value.
351 ASSERT_GT(host_signal_strategy_
->received_messages().size(), 0U);
352 const buzz::XmlElement
* initiate_xml
=
353 host_signal_strategy_
->received_messages().front();
354 const buzz::XmlElement
* jingle_element
=
355 initiate_xml
->FirstNamed(buzz::QName(kJingleNamespace
, "jingle"));
356 ASSERT_TRUE(jingle_element
);
357 ASSERT_EQ(kClientJid
,
358 jingle_element
->Attr(buzz::QName(std::string(), "initiator")));
361 // Verify that we can connect two endpoints with multi-step authentication.
362 TEST_F(JingleSessionTest
, ConnectWithMultistep
) {
363 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
364 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false);
367 // Verify that connection is terminated when single-step auth fails.
368 TEST_F(JingleSessionTest
, ConnectWithBadAuth
) {
369 CreateSessionManagers(1, FakeAuthenticator::REJECT
);
370 InitiateConnection(1, FakeAuthenticator::ACCEPT
, true);
373 // Verify that connection is terminated when multi-step auth fails.
374 TEST_F(JingleSessionTest
, ConnectWithBadMultistepAuth
) {
375 CreateSessionManagers(3, FakeAuthenticator::REJECT
);
376 InitiateConnection(3, FakeAuthenticator::ACCEPT
, true);
379 // Verify that data can be sent over stream channel.
380 TEST_F(JingleSessionTest
, TestStreamChannel
) {
381 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
382 ASSERT_NO_FATAL_FAILURE(
383 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
385 ASSERT_NO_FATAL_FAILURE(CreateChannel());
387 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
388 kMessageSize
, kMessages
);
390 message_loop_
->Run();
391 tester
.CheckResults();
394 TEST_F(JingleSessionTest
, DeleteSessionOnIncomingConnection
) {
395 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
397 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
399 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
400 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
402 EXPECT_CALL(host_session_event_handler_
,
403 OnSessionStateChange(Session::CONNECTED
))
406 EXPECT_CALL(host_session_event_handler_
,
407 OnSessionStateChange(Session::AUTHENTICATING
))
408 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession
));
410 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
411 FakeAuthenticator::CLIENT
, 3, FakeAuthenticator::ACCEPT
, true));
413 client_session_
= client_server_
->Connect(
414 kHostJid
, authenticator
.Pass(),
415 CandidateSessionConfig::CreateDefault());
417 base::RunLoop().RunUntilIdle();
420 TEST_F(JingleSessionTest
, DeleteSessionOnAuth
) {
421 // Same as the previous test, but set messages_till_started to 2 in
422 // CreateSessionManagers so that the session will goes into the
423 // AUTHENTICATING state after two message exchanges.
424 CreateSessionManagers(3, 2, FakeAuthenticator::ACCEPT
);
426 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
428 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
429 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
431 EXPECT_CALL(host_session_event_handler_
,
432 OnSessionStateChange(Session::CONNECTED
))
435 EXPECT_CALL(host_session_event_handler_
,
436 OnSessionStateChange(Session::AUTHENTICATING
))
437 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession
));
439 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
440 FakeAuthenticator::CLIENT
, 3, FakeAuthenticator::ACCEPT
, true));
442 client_session_
= client_server_
->Connect(
443 kHostJid
, authenticator
.Pass(),
444 CandidateSessionConfig::CreateDefault());
445 base::RunLoop().RunUntilIdle();
448 // Verify that data can be sent over a multiplexed channel.
449 TEST_F(JingleSessionTest
, TestMuxStreamChannel
) {
450 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
451 ASSERT_NO_FATAL_FAILURE(
452 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
454 client_session_
->GetMultiplexedChannelFactory()->CreateChannel(
455 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
456 base::Unretained(this)));
457 host_session_
->GetMultiplexedChannelFactory()->CreateChannel(
458 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
459 base::Unretained(this)));
462 ExpectRouteChange("mux");
463 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
464 .WillOnce(QuitThreadOnCounter(&counter
));
465 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
466 .WillOnce(QuitThreadOnCounter(&counter
));
467 message_loop_
->Run();
469 EXPECT_TRUE(client_socket_
.get());
470 EXPECT_TRUE(host_socket_
.get());
472 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
473 kMessageSize
, kMessages
);
475 message_loop_
->Run();
476 tester
.CheckResults();
479 // Verify that we can connect channels with multistep auth.
480 TEST_F(JingleSessionTest
, TestMultistepAuthStreamChannel
) {
481 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
482 ASSERT_NO_FATAL_FAILURE(
483 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false));
485 ASSERT_NO_FATAL_FAILURE(CreateChannel());
487 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
488 kMessageSize
, kMessages
);
490 message_loop_
->Run();
491 tester
.CheckResults();
494 // Verify that we shutdown properly when channel authentication fails.
495 TEST_F(JingleSessionTest
, TestFailedChannelAuth
) {
496 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL
);
497 ASSERT_NO_FATAL_FAILURE(
498 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
500 client_session_
->GetTransportChannelFactory()->CreateChannel(
501 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
502 base::Unretained(this)));
503 host_session_
->GetTransportChannelFactory()->CreateChannel(
504 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
505 base::Unretained(this)));
507 // Terminate the message loop when we get rejection notification
509 EXPECT_CALL(host_channel_callback_
, OnDone(nullptr))
510 .WillOnce(QuitThread());
511 ExpectRouteChange(kChannelName
);
513 message_loop_
->Run();
515 client_session_
->GetTransportChannelFactory()->CancelChannelCreation(
518 EXPECT_TRUE(!host_socket_
.get());
521 TEST_F(JingleSessionTest
, TestCancelChannelCreation
) {
522 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL
);
523 ASSERT_NO_FATAL_FAILURE(
524 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
526 client_session_
->GetTransportChannelFactory()->CreateChannel(
527 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
528 base::Unretained(this)));
529 client_session_
->GetTransportChannelFactory()->CancelChannelCreation(
532 EXPECT_TRUE(!client_socket_
.get());
535 } // namespace protocol
536 } // namespace remoting