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/signaling/fake_signal_strategy.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
30 using testing::AtLeast
;
31 using testing::AtMost
;
32 using testing::DeleteArg
;
34 using testing::InSequence
;
35 using testing::Invoke
;
36 using testing::InvokeWithoutArgs
;
37 using testing::Return
;
38 using testing::SaveArg
;
39 using testing::SetArgumentPointee
;
40 using testing::WithArg
;
47 const char kHostJid
[] = "host1@gmail.com/123";
48 const char kClientJid
[] = "host2@gmail.com/321";
50 // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
51 // between messages (about 1 second for 100 messages).
52 const int kMessageSize
= 1024;
53 const int kMessages
= 100;
54 const char kChannelName
[] = "test_channel";
56 void QuitCurrentThread() {
57 base::MessageLoop::current()->PostTask(FROM_HERE
,
58 base::MessageLoop::QuitClosure());
65 ACTION_P(QuitThreadOnCounter
, counter
) {
67 EXPECT_GE(*counter
, 0);
72 class MockSessionManagerListener
: public SessionManager::Listener
{
74 MOCK_METHOD0(OnSessionManagerReady
, void());
75 MOCK_METHOD2(OnIncomingSession
,
77 SessionManager::IncomingSessionResponse
*));
80 class MockSessionEventHandler
: public Session::EventHandler
{
82 MOCK_METHOD1(OnSessionStateChange
, void(Session::State
));
83 MOCK_METHOD2(OnSessionRouteChange
, void(const std::string
& channel_name
,
84 const TransportRoute
& route
));
87 class MockStreamChannelCallback
{
89 MOCK_METHOD1(OnDone
, void(net::StreamSocket
* socket
));
94 class JingleSessionTest
: public testing::Test
{
97 message_loop_
.reset(new base::MessageLoopForIO());
98 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
101 // Helper method that handles OnIncomingSession().
102 void SetHostSession(Session
* session
) {
104 host_session_
.reset(session
);
105 host_session_
->SetEventHandler(&host_session_event_handler_
);
107 session
->set_config(SessionConfig::ForTest());
110 void DeleteSession() {
111 host_session_
.reset();
114 void OnClientChannelCreated(scoped_ptr
<net::StreamSocket
> socket
) {
115 client_channel_callback_
.OnDone(socket
.get());
116 client_socket_
= socket
.Pass();
119 void OnHostChannelCreated(scoped_ptr
<net::StreamSocket
> socket
) {
120 host_channel_callback_
.OnDone(socket
.get());
121 host_socket_
= socket
.Pass();
125 virtual void SetUp() {
128 virtual void TearDown() {
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(NULL
, network_settings
)
156 .PassAs
<cricket::HttpPortAllocatorBase
>(),
158 host_server_
.reset(new JingleSessionManager(host_transport
.Pass()));
159 host_server_
->Init(host_signal_strategy_
.get(), &host_server_listener_
);
161 scoped_ptr
<AuthenticatorFactory
> factory(
162 new FakeHostAuthenticatorFactory(auth_round_trips
,
163 messages_till_start
, auth_action
, true));
164 host_server_
->set_authenticator_factory(factory
.Pass());
166 EXPECT_CALL(client_server_listener_
, OnSessionManagerReady())
168 scoped_ptr
<TransportFactory
> client_transport(new LibjingleTransportFactory(
170 ChromiumPortAllocator::Create(NULL
, network_settings
)
171 .PassAs
<cricket::HttpPortAllocatorBase
>(),
173 client_server_
.reset(
174 new JingleSessionManager(client_transport
.Pass()));
175 client_server_
->Init(client_signal_strategy_
.get(),
176 &client_server_listener_
);
179 void CreateSessionManagers(int auth_round_trips
,
180 FakeAuthenticator::Action auth_action
) {
181 CreateSessionManagers(auth_round_trips
, 0, auth_action
);
184 void CloseSessionManager() {
185 if (host_server_
.get()) {
186 host_server_
->Close();
187 host_server_
.reset();
189 if (client_server_
.get()) {
190 client_server_
->Close();
191 client_server_
.reset();
193 host_signal_strategy_
.reset();
194 client_signal_strategy_
.reset();
197 void InitiateConnection(int auth_round_trips
,
198 FakeAuthenticator::Action auth_action
,
200 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
202 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
203 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
208 EXPECT_CALL(host_session_event_handler_
,
209 OnSessionStateChange(Session::CONNECTED
))
211 EXPECT_CALL(host_session_event_handler_
,
212 OnSessionStateChange(Session::AUTHENTICATING
))
215 EXPECT_CALL(host_session_event_handler_
,
216 OnSessionStateChange(Session::FAILED
))
219 EXPECT_CALL(host_session_event_handler_
,
220 OnSessionStateChange(Session::AUTHENTICATED
))
222 // Expect that the connection will be closed eventually.
223 EXPECT_CALL(host_session_event_handler_
,
224 OnSessionStateChange(Session::CLOSED
))
232 EXPECT_CALL(client_session_event_handler_
,
233 OnSessionStateChange(Session::CONNECTED
))
235 EXPECT_CALL(client_session_event_handler_
,
236 OnSessionStateChange(Session::AUTHENTICATING
))
239 EXPECT_CALL(client_session_event_handler_
,
240 OnSessionStateChange(Session::FAILED
))
243 EXPECT_CALL(client_session_event_handler_
,
244 OnSessionStateChange(Session::AUTHENTICATED
))
246 // Expect that the connection will be closed eventually.
247 EXPECT_CALL(client_session_event_handler_
,
248 OnSessionStateChange(Session::CLOSED
))
253 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
254 FakeAuthenticator::CLIENT
, auth_round_trips
, auth_action
, true));
256 client_session_
= client_server_
->Connect(
257 kHostJid
, authenticator
.Pass(),
258 CandidateSessionConfig::CreateDefault());
259 client_session_
->SetEventHandler(&client_session_event_handler_
);
261 base::RunLoop().RunUntilIdle();
264 void CreateChannel() {
265 client_session_
->GetTransportChannelFactory()->CreateStreamChannel(
266 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
267 base::Unretained(this)));
268 host_session_
->GetTransportChannelFactory()->CreateStreamChannel(
269 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
270 base::Unretained(this)));
273 ExpectRouteChange(kChannelName
);
274 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
275 .WillOnce(QuitThreadOnCounter(&counter
));
276 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
277 .WillOnce(QuitThreadOnCounter(&counter
));
278 message_loop_
->Run();
280 EXPECT_TRUE(client_socket_
.get());
281 EXPECT_TRUE(host_socket_
.get());
284 void ExpectRouteChange(const std::string
& channel_name
) {
285 EXPECT_CALL(host_session_event_handler_
,
286 OnSessionRouteChange(channel_name
, _
))
288 EXPECT_CALL(client_session_event_handler_
,
289 OnSessionRouteChange(channel_name
, _
))
293 scoped_ptr
<base::MessageLoopForIO
> message_loop_
;
295 scoped_ptr
<FakeSignalStrategy
> host_signal_strategy_
;
296 scoped_ptr
<FakeSignalStrategy
> client_signal_strategy_
;
298 scoped_ptr
<JingleSessionManager
> host_server_
;
299 MockSessionManagerListener host_server_listener_
;
300 scoped_ptr
<JingleSessionManager
> client_server_
;
301 MockSessionManagerListener client_server_listener_
;
303 scoped_ptr
<Session
> host_session_
;
304 MockSessionEventHandler host_session_event_handler_
;
305 scoped_ptr
<Session
> client_session_
;
306 MockSessionEventHandler client_session_event_handler_
;
308 MockStreamChannelCallback client_channel_callback_
;
309 MockStreamChannelCallback host_channel_callback_
;
311 scoped_ptr
<net::StreamSocket
> client_socket_
;
312 scoped_ptr
<net::StreamSocket
> host_socket_
;
316 // Verify that we can create and destroy session managers without a
318 TEST_F(JingleSessionTest
, CreateAndDestoy
) {
319 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
322 // Verify that an incoming session can be rejected, and that the
323 // status of the connection is set to FAILED in this case.
324 TEST_F(JingleSessionTest
, RejectConnection
) {
325 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
327 // Reject incoming session.
328 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
329 .WillOnce(SetArgumentPointee
<1>(protocol::SessionManager::DECLINE
));
333 EXPECT_CALL(client_session_event_handler_
,
334 OnSessionStateChange(Session::FAILED
))
338 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
339 FakeAuthenticator::CLIENT
, 1, FakeAuthenticator::ACCEPT
, true));
340 client_session_
= client_server_
->Connect(
341 kHostJid
, authenticator
.Pass(), CandidateSessionConfig::CreateDefault());
342 client_session_
->SetEventHandler(&client_session_event_handler_
);
344 base::RunLoop().RunUntilIdle();
347 // Verify that we can connect two endpoints with single-step authentication.
348 TEST_F(JingleSessionTest
, Connect
) {
349 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
350 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false);
352 // Verify that the client specified correct initiator value.
353 ASSERT_GT(host_signal_strategy_
->received_messages().size(), 0U);
354 const buzz::XmlElement
* initiate_xml
=
355 host_signal_strategy_
->received_messages().front();
356 const buzz::XmlElement
* jingle_element
=
357 initiate_xml
->FirstNamed(buzz::QName(kJingleNamespace
, "jingle"));
358 ASSERT_TRUE(jingle_element
);
359 ASSERT_EQ(kClientJid
,
360 jingle_element
->Attr(buzz::QName(std::string(), "initiator")));
363 // Verify that we can connect two endpoints with multi-step authentication.
364 TEST_F(JingleSessionTest
, ConnectWithMultistep
) {
365 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
366 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false);
369 // Verify that connection is terminated when single-step auth fails.
370 TEST_F(JingleSessionTest
, ConnectWithBadAuth
) {
371 CreateSessionManagers(1, FakeAuthenticator::REJECT
);
372 InitiateConnection(1, FakeAuthenticator::ACCEPT
, true);
375 // Verify that connection is terminated when multi-step auth fails.
376 TEST_F(JingleSessionTest
, ConnectWithBadMultistepAuth
) {
377 CreateSessionManagers(3, FakeAuthenticator::REJECT
);
378 InitiateConnection(3, FakeAuthenticator::ACCEPT
, true);
381 // Verify that data can be sent over stream channel.
382 TEST_F(JingleSessionTest
, TestStreamChannel
) {
383 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
384 ASSERT_NO_FATAL_FAILURE(
385 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
387 ASSERT_NO_FATAL_FAILURE(CreateChannel());
389 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
390 kMessageSize
, kMessages
);
392 message_loop_
->Run();
393 tester
.CheckResults();
396 TEST_F(JingleSessionTest
, DeleteSessionOnIncomingConnection
) {
397 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
399 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
401 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
402 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
404 EXPECT_CALL(host_session_event_handler_
,
405 OnSessionStateChange(Session::CONNECTED
))
408 EXPECT_CALL(host_session_event_handler_
,
409 OnSessionStateChange(Session::AUTHENTICATING
))
410 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession
));
412 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
413 FakeAuthenticator::CLIENT
, 3, FakeAuthenticator::ACCEPT
, true));
415 client_session_
= client_server_
->Connect(
416 kHostJid
, authenticator
.Pass(),
417 CandidateSessionConfig::CreateDefault());
419 base::RunLoop().RunUntilIdle();
422 TEST_F(JingleSessionTest
, DeleteSessionOnAuth
) {
423 // Same as the previous test, but set messages_till_started to 2 in
424 // CreateSessionManagers so that the session will goes into the
425 // AUTHENTICATING state after two message exchanges.
426 CreateSessionManagers(3, 2, FakeAuthenticator::ACCEPT
);
428 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
430 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
431 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
433 EXPECT_CALL(host_session_event_handler_
,
434 OnSessionStateChange(Session::CONNECTED
))
437 EXPECT_CALL(host_session_event_handler_
,
438 OnSessionStateChange(Session::AUTHENTICATING
))
439 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession
));
441 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
442 FakeAuthenticator::CLIENT
, 3, FakeAuthenticator::ACCEPT
, true));
444 client_session_
= client_server_
->Connect(
445 kHostJid
, authenticator
.Pass(),
446 CandidateSessionConfig::CreateDefault());
447 base::RunLoop().RunUntilIdle();
450 // Verify that data can be sent over a multiplexed channel.
451 TEST_F(JingleSessionTest
, TestMuxStreamChannel
) {
452 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
453 ASSERT_NO_FATAL_FAILURE(
454 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
456 client_session_
->GetMultiplexedChannelFactory()->CreateStreamChannel(
457 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
458 base::Unretained(this)));
459 host_session_
->GetMultiplexedChannelFactory()->CreateStreamChannel(
460 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
461 base::Unretained(this)));
464 ExpectRouteChange("mux");
465 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
466 .WillOnce(QuitThreadOnCounter(&counter
));
467 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
468 .WillOnce(QuitThreadOnCounter(&counter
));
469 message_loop_
->Run();
471 EXPECT_TRUE(client_socket_
.get());
472 EXPECT_TRUE(host_socket_
.get());
474 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
475 kMessageSize
, kMessages
);
477 message_loop_
->Run();
478 tester
.CheckResults();
481 // Verify that we can connect channels with multistep auth.
482 TEST_F(JingleSessionTest
, TestMultistepAuthStreamChannel
) {
483 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
484 ASSERT_NO_FATAL_FAILURE(
485 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false));
487 ASSERT_NO_FATAL_FAILURE(CreateChannel());
489 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
490 kMessageSize
, kMessages
);
492 message_loop_
->Run();
493 tester
.CheckResults();
496 // Verify that we shutdown properly when channel authentication fails.
497 TEST_F(JingleSessionTest
, TestFailedChannelAuth
) {
498 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL
);
499 ASSERT_NO_FATAL_FAILURE(
500 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
502 client_session_
->GetTransportChannelFactory()->CreateStreamChannel(
503 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
504 base::Unretained(this)));
505 host_session_
->GetTransportChannelFactory()->CreateStreamChannel(
506 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
507 base::Unretained(this)));
509 // Terminate the message loop when we get rejection notification
511 EXPECT_CALL(host_channel_callback_
, OnDone(NULL
))
512 .WillOnce(QuitThread());
513 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
515 ExpectRouteChange(kChannelName
);
517 message_loop_
->Run();
519 EXPECT_TRUE(!host_socket_
.get());
522 } // namespace protocol
523 } // namespace remoting