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 "net/socket/socket.h"
13 #include "net/socket/stream_socket.h"
14 #include "net/url_request/url_request_context_getter.h"
15 #include "remoting/base/constants.h"
16 #include "remoting/jingle_glue/chromium_port_allocator.h"
17 #include "remoting/jingle_glue/fake_signal_strategy.h"
18 #include "remoting/jingle_glue/network_settings.h"
19 #include "remoting/protocol/authenticator.h"
20 #include "remoting/protocol/channel_authenticator.h"
21 #include "remoting/protocol/connection_tester.h"
22 #include "remoting/protocol/fake_authenticator.h"
23 #include "remoting/protocol/jingle_session_manager.h"
24 #include "remoting/protocol/libjingle_transport_factory.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 using testing::AtLeast
;
30 using testing::AtMost
;
31 using testing::DeleteArg
;
33 using testing::InSequence
;
34 using testing::Invoke
;
35 using testing::InvokeWithoutArgs
;
36 using testing::Return
;
37 using testing::SaveArg
;
38 using testing::SetArgumentPointee
;
39 using testing::WithArg
;
46 const char kHostJid
[] = "host1@gmail.com/123";
47 const char kClientJid
[] = "host2@gmail.com/321";
49 // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
50 // between messages (about 1 second for 100 messages).
51 const int kMessageSize
= 1024;
52 const int kMessages
= 100;
53 const char kChannelName
[] = "test_channel";
55 void QuitCurrentThread() {
56 base::MessageLoop::current()->PostTask(FROM_HERE
,
57 base::MessageLoop::QuitClosure());
64 ACTION_P(QuitThreadOnCounter
, counter
) {
66 EXPECT_GE(*counter
, 0);
71 class MockSessionManagerListener
: public SessionManager::Listener
{
73 MOCK_METHOD0(OnSessionManagerReady
, void());
74 MOCK_METHOD2(OnIncomingSession
,
76 SessionManager::IncomingSessionResponse
*));
79 class MockSessionEventHandler
: public Session::EventHandler
{
81 MOCK_METHOD1(OnSessionStateChange
, void(Session::State
));
82 MOCK_METHOD2(OnSessionRouteChange
, void(const std::string
& channel_name
,
83 const TransportRoute
& route
));
86 class MockStreamChannelCallback
{
88 MOCK_METHOD1(OnDone
, void(net::StreamSocket
* socket
));
93 class JingleSessionTest
: public testing::Test
{
96 message_loop_
.reset(new base::MessageLoopForIO());
99 // Helper method that handles OnIncomingSession().
100 void SetHostSession(Session
* session
) {
102 host_session_
.reset(session
);
103 host_session_
->SetEventHandler(&host_session_event_handler_
);
105 session
->set_config(SessionConfig::ForTest());
108 void OnClientChannelCreated(scoped_ptr
<net::StreamSocket
> socket
) {
109 client_channel_callback_
.OnDone(socket
.get());
110 client_socket_
= socket
.Pass();
113 void OnHostChannelCreated(scoped_ptr
<net::StreamSocket
> socket
) {
114 host_channel_callback_
.OnDone(socket
.get());
115 host_socket_
= socket
.Pass();
119 virtual void SetUp() {
122 virtual void TearDown() {
124 CloseSessionManager();
125 base::RunLoop().RunUntilIdle();
128 void CloseSessions() {
129 host_socket_
.reset();
130 host_session_
.reset();
131 client_socket_
.reset();
132 client_session_
.reset();
135 void CreateSessionManagers(int auth_round_trips
,
136 FakeAuthenticator::Action auth_action
) {
137 host_signal_strategy_
.reset(new FakeSignalStrategy(kHostJid
));
138 client_signal_strategy_
.reset(new FakeSignalStrategy(kClientJid
));
139 FakeSignalStrategy::Connect(host_signal_strategy_
.get(),
140 client_signal_strategy_
.get());
142 EXPECT_CALL(host_server_listener_
, OnSessionManagerReady())
145 NetworkSettings
network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING
);
147 scoped_ptr
<TransportFactory
> host_transport(new LibjingleTransportFactory(
149 ChromiumPortAllocator::Create(NULL
, network_settings
)
150 .PassAs
<cricket::HttpPortAllocatorBase
>(),
152 host_server_
.reset(new JingleSessionManager(host_transport
.Pass()));
153 host_server_
->Init(host_signal_strategy_
.get(), &host_server_listener_
);
155 scoped_ptr
<AuthenticatorFactory
> factory(
156 new FakeHostAuthenticatorFactory(auth_round_trips
, auth_action
, true));
157 host_server_
->set_authenticator_factory(factory
.Pass());
159 EXPECT_CALL(client_server_listener_
, OnSessionManagerReady())
161 scoped_ptr
<TransportFactory
> client_transport(new LibjingleTransportFactory(
163 ChromiumPortAllocator::Create(NULL
, network_settings
)
164 .PassAs
<cricket::HttpPortAllocatorBase
>(),
166 client_server_
.reset(
167 new JingleSessionManager(client_transport
.Pass()));
168 client_server_
->Init(client_signal_strategy_
.get(),
169 &client_server_listener_
);
172 void CloseSessionManager() {
173 if (host_server_
.get()) {
174 host_server_
->Close();
175 host_server_
.reset();
177 if (client_server_
.get()) {
178 client_server_
->Close();
179 client_server_
.reset();
181 host_signal_strategy_
.reset();
182 client_signal_strategy_
.reset();
185 void InitiateConnection(int auth_round_trips
,
186 FakeAuthenticator::Action auth_action
,
188 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
190 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
191 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
196 EXPECT_CALL(host_session_event_handler_
,
197 OnSessionStateChange(Session::CONNECTED
))
200 EXPECT_CALL(host_session_event_handler_
,
201 OnSessionStateChange(Session::FAILED
))
204 EXPECT_CALL(host_session_event_handler_
,
205 OnSessionStateChange(Session::AUTHENTICATED
))
207 // Expect that the connection will be closed eventually.
208 EXPECT_CALL(host_session_event_handler_
,
209 OnSessionStateChange(Session::CLOSED
))
217 EXPECT_CALL(client_session_event_handler_
,
218 OnSessionStateChange(Session::CONNECTED
))
221 EXPECT_CALL(client_session_event_handler_
,
222 OnSessionStateChange(Session::FAILED
))
225 EXPECT_CALL(client_session_event_handler_
,
226 OnSessionStateChange(Session::AUTHENTICATED
))
228 // Expect that the connection will be closed eventually.
229 EXPECT_CALL(client_session_event_handler_
,
230 OnSessionStateChange(Session::CLOSED
))
235 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
236 FakeAuthenticator::CLIENT
, auth_round_trips
, auth_action
, true));
238 client_session_
= client_server_
->Connect(
239 kHostJid
, authenticator
.Pass(),
240 CandidateSessionConfig::CreateDefault());
241 client_session_
->SetEventHandler(&client_session_event_handler_
);
243 base::RunLoop().RunUntilIdle();
246 void CreateChannel() {
247 client_session_
->GetTransportChannelFactory()->CreateStreamChannel(
248 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
249 base::Unretained(this)));
250 host_session_
->GetTransportChannelFactory()->CreateStreamChannel(
251 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
252 base::Unretained(this)));
255 ExpectRouteChange(kChannelName
);
256 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
257 .WillOnce(QuitThreadOnCounter(&counter
));
258 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
259 .WillOnce(QuitThreadOnCounter(&counter
));
260 message_loop_
->Run();
262 EXPECT_TRUE(client_socket_
.get());
263 EXPECT_TRUE(host_socket_
.get());
266 void ExpectRouteChange(const std::string
& channel_name
) {
267 EXPECT_CALL(host_session_event_handler_
,
268 OnSessionRouteChange(channel_name
, _
))
270 EXPECT_CALL(client_session_event_handler_
,
271 OnSessionRouteChange(channel_name
, _
))
275 scoped_ptr
<base::MessageLoopForIO
> message_loop_
;
277 scoped_ptr
<FakeSignalStrategy
> host_signal_strategy_
;
278 scoped_ptr
<FakeSignalStrategy
> client_signal_strategy_
;
280 scoped_ptr
<JingleSessionManager
> host_server_
;
281 MockSessionManagerListener host_server_listener_
;
282 scoped_ptr
<JingleSessionManager
> client_server_
;
283 MockSessionManagerListener client_server_listener_
;
285 scoped_ptr
<Session
> host_session_
;
286 MockSessionEventHandler host_session_event_handler_
;
287 scoped_ptr
<Session
> client_session_
;
288 MockSessionEventHandler client_session_event_handler_
;
290 MockStreamChannelCallback client_channel_callback_
;
291 MockStreamChannelCallback host_channel_callback_
;
293 scoped_ptr
<net::StreamSocket
> client_socket_
;
294 scoped_ptr
<net::StreamSocket
> host_socket_
;
298 // Verify that we can create and destroy session managers without a
300 TEST_F(JingleSessionTest
, CreateAndDestoy
) {
301 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
304 // Verify that an incoming session can be rejected, and that the
305 // status of the connection is set to FAILED in this case.
306 TEST_F(JingleSessionTest
, RejectConnection
) {
307 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
309 // Reject incoming session.
310 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
311 .WillOnce(SetArgumentPointee
<1>(protocol::SessionManager::DECLINE
));
315 EXPECT_CALL(client_session_event_handler_
,
316 OnSessionStateChange(Session::FAILED
))
320 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
321 FakeAuthenticator::CLIENT
, 1, FakeAuthenticator::ACCEPT
, true));
322 client_session_
= client_server_
->Connect(
323 kHostJid
, authenticator
.Pass(), CandidateSessionConfig::CreateDefault());
324 client_session_
->SetEventHandler(&client_session_event_handler_
);
326 base::RunLoop().RunUntilIdle();
329 // Verify that we can connect two endpoints with single-step authentication.
330 TEST_F(JingleSessionTest
, Connect
) {
331 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
332 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false);
334 // Verify that the client specified correct initiator value.
335 ASSERT_GT(host_signal_strategy_
->received_messages().size(), 0U);
336 const buzz::XmlElement
* initiate_xml
=
337 host_signal_strategy_
->received_messages().front();
338 const buzz::XmlElement
* jingle_element
=
339 initiate_xml
->FirstNamed(buzz::QName(kJingleNamespace
, "jingle"));
340 ASSERT_TRUE(jingle_element
);
341 ASSERT_EQ(kClientJid
,
342 jingle_element
->Attr(buzz::QName(std::string(), "initiator")));
345 // Verify that we can connect two endpoints with multi-step authentication.
346 TEST_F(JingleSessionTest
, ConnectWithMultistep
) {
347 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
348 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false);
351 // Verify that connection is terminated when single-step auth fails.
352 TEST_F(JingleSessionTest
, ConnectWithBadAuth
) {
353 CreateSessionManagers(1, FakeAuthenticator::REJECT
);
354 InitiateConnection(1, FakeAuthenticator::ACCEPT
, true);
357 // Verify that connection is terminated when multi-step auth fails.
358 TEST_F(JingleSessionTest
, ConnectWithBadMultistepAuth
) {
359 CreateSessionManagers(3, FakeAuthenticator::REJECT
);
360 InitiateConnection(3, FakeAuthenticator::ACCEPT
, true);
363 // Verify that data can be sent over stream channel.
364 TEST_F(JingleSessionTest
, TestStreamChannel
) {
365 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
366 ASSERT_NO_FATAL_FAILURE(
367 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
369 ASSERT_NO_FATAL_FAILURE(CreateChannel());
371 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
372 kMessageSize
, kMessages
);
374 message_loop_
->Run();
375 tester
.CheckResults();
378 // Verify that data can be sent over a multiplexed channel.
379 TEST_F(JingleSessionTest
, TestMuxStreamChannel
) {
380 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
381 ASSERT_NO_FATAL_FAILURE(
382 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
384 client_session_
->GetMultiplexedChannelFactory()->CreateStreamChannel(
385 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
386 base::Unretained(this)));
387 host_session_
->GetMultiplexedChannelFactory()->CreateStreamChannel(
388 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
389 base::Unretained(this)));
392 ExpectRouteChange("mux");
393 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
394 .WillOnce(QuitThreadOnCounter(&counter
));
395 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
396 .WillOnce(QuitThreadOnCounter(&counter
));
397 message_loop_
->Run();
399 EXPECT_TRUE(client_socket_
.get());
400 EXPECT_TRUE(host_socket_
.get());
402 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
403 kMessageSize
, kMessages
);
405 message_loop_
->Run();
406 tester
.CheckResults();
409 // Verify that we can connect channels with multistep auth.
410 TEST_F(JingleSessionTest
, TestMultistepAuthStreamChannel
) {
411 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
412 ASSERT_NO_FATAL_FAILURE(
413 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false));
415 ASSERT_NO_FATAL_FAILURE(CreateChannel());
417 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
418 kMessageSize
, kMessages
);
420 message_loop_
->Run();
421 tester
.CheckResults();
424 // Verify that we shutdown properly when channel authentication fails.
425 TEST_F(JingleSessionTest
, TestFailedChannelAuth
) {
426 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL
);
427 ASSERT_NO_FATAL_FAILURE(
428 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
430 client_session_
->GetTransportChannelFactory()->CreateStreamChannel(
431 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
432 base::Unretained(this)));
433 host_session_
->GetTransportChannelFactory()->CreateStreamChannel(
434 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
435 base::Unretained(this)));
437 // Terminate the message loop when we get rejection notification
439 EXPECT_CALL(host_channel_callback_
, OnDone(NULL
))
440 .WillOnce(QuitThread());
441 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
443 ExpectRouteChange(kChannelName
);
445 message_loop_
->Run();
447 EXPECT_TRUE(!host_socket_
.get());
450 } // namespace protocol
451 } // namespace remoting