Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / remoting / protocol / jingle_session_unittest.cc
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.
4
5 #include "remoting/protocol/jingle_session.h"
6
7 #include "base/bind.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/jingle_glue/chromium_port_allocator.h"
18 #include "remoting/jingle_glue/fake_signal_strategy.h"
19 #include "remoting/jingle_glue/network_settings.h"
20 #include "remoting/protocol/authenticator.h"
21 #include "remoting/protocol/channel_authenticator.h"
22 #include "remoting/protocol/connection_tester.h"
23 #include "remoting/protocol/fake_authenticator.h"
24 #include "remoting/protocol/jingle_session_manager.h"
25 #include "remoting/protocol/libjingle_transport_factory.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 using testing::_;
30 using testing::AtLeast;
31 using testing::AtMost;
32 using testing::DeleteArg;
33 using testing::DoAll;
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;
41
42 namespace remoting {
43 namespace protocol {
44
45 namespace {
46
47 const char kHostJid[] = "host1@gmail.com/123";
48 const char kClientJid[] = "host2@gmail.com/321";
49
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";
55
56 void QuitCurrentThread() {
57   base::MessageLoop::current()->PostTask(FROM_HERE,
58                                          base::MessageLoop::QuitClosure());
59 }
60
61 ACTION(QuitThread) {
62   QuitCurrentThread();
63 }
64
65 ACTION_P(QuitThreadOnCounter, counter) {
66   --(*counter);
67   EXPECT_GE(*counter, 0);
68   if (*counter == 0)
69     QuitCurrentThread();
70 }
71
72 class MockSessionManagerListener : public SessionManager::Listener {
73  public:
74   MOCK_METHOD0(OnSessionManagerReady, void());
75   MOCK_METHOD2(OnIncomingSession,
76                void(Session*,
77                     SessionManager::IncomingSessionResponse*));
78 };
79
80 class MockSessionEventHandler : public Session::EventHandler {
81  public:
82   MOCK_METHOD1(OnSessionStateChange, void(Session::State));
83   MOCK_METHOD2(OnSessionRouteChange, void(const std::string& channel_name,
84                                           const TransportRoute& route));
85 };
86
87 class MockStreamChannelCallback {
88  public:
89   MOCK_METHOD1(OnDone, void(net::StreamSocket* socket));
90 };
91
92 }  // namespace
93
94 class JingleSessionTest : public testing::Test {
95  public:
96   JingleSessionTest() {
97     message_loop_.reset(new base::MessageLoopForIO());
98     jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
99   }
100
101   // Helper method that handles OnIncomingSession().
102   void SetHostSession(Session* session) {
103     DCHECK(session);
104     host_session_.reset(session);
105     host_session_->SetEventHandler(&host_session_event_handler_);
106
107     session->set_config(SessionConfig::ForTest());
108   }
109
110   void DeleteSession() {
111     host_session_.reset();
112   }
113
114   void OnClientChannelCreated(scoped_ptr<net::StreamSocket> socket) {
115     client_channel_callback_.OnDone(socket.get());
116     client_socket_ = socket.Pass();
117   }
118
119   void OnHostChannelCreated(scoped_ptr<net::StreamSocket> socket) {
120     host_channel_callback_.OnDone(socket.get());
121     host_socket_ = socket.Pass();
122   }
123
124  protected:
125   virtual void SetUp() {
126   }
127
128   virtual void TearDown() {
129     CloseSessions();
130     CloseSessionManager();
131     base::RunLoop().RunUntilIdle();
132   }
133
134   void CloseSessions() {
135     host_socket_.reset();
136     host_session_.reset();
137     client_socket_.reset();
138     client_session_.reset();
139   }
140
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());
147
148     EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
149         .Times(1);
150
151     NetworkSettings network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
152
153     scoped_ptr<TransportFactory> host_transport(new LibjingleTransportFactory(
154         NULL,
155         ChromiumPortAllocator::Create(NULL, network_settings)
156             .PassAs<cricket::HttpPortAllocatorBase>(),
157         network_settings));
158     host_server_.reset(new JingleSessionManager(host_transport.Pass()));
159     host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
160
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());
165
166     EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
167         .Times(1);
168     scoped_ptr<TransportFactory> client_transport(new LibjingleTransportFactory(
169         NULL,
170         ChromiumPortAllocator::Create(NULL, network_settings)
171             .PassAs<cricket::HttpPortAllocatorBase>(),
172         network_settings));
173     client_server_.reset(
174         new JingleSessionManager(client_transport.Pass()));
175     client_server_->Init(client_signal_strategy_.get(),
176                          &client_server_listener_);
177   }
178
179   void CreateSessionManagers(int auth_round_trips,
180                              FakeAuthenticator::Action auth_action) {
181     CreateSessionManagers(auth_round_trips, 0, auth_action);
182   }
183
184   void CloseSessionManager() {
185     if (host_server_.get()) {
186       host_server_->Close();
187       host_server_.reset();
188     }
189     if (client_server_.get()) {
190       client_server_->Close();
191       client_server_.reset();
192     }
193     host_signal_strategy_.reset();
194     client_signal_strategy_.reset();
195   }
196
197   void InitiateConnection(int auth_round_trips,
198                           FakeAuthenticator::Action auth_action,
199                           bool expect_fail) {
200     EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
201         .WillOnce(DoAll(
202             WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
203             SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
204
205     {
206       InSequence dummy;
207
208       EXPECT_CALL(host_session_event_handler_,
209                   OnSessionStateChange(Session::CONNECTED))
210           .Times(AtMost(1));
211       EXPECT_CALL(host_session_event_handler_,
212                   OnSessionStateChange(Session::AUTHENTICATING))
213           .Times(AtMost(1));
214       if (expect_fail) {
215         EXPECT_CALL(host_session_event_handler_,
216                     OnSessionStateChange(Session::FAILED))
217             .Times(1);
218       } else {
219         EXPECT_CALL(host_session_event_handler_,
220                     OnSessionStateChange(Session::AUTHENTICATED))
221             .Times(1);
222         // Expect that the connection will be closed eventually.
223         EXPECT_CALL(host_session_event_handler_,
224                     OnSessionStateChange(Session::CLOSED))
225             .Times(AtMost(1));
226       }
227     }
228
229     {
230       InSequence dummy;
231
232       EXPECT_CALL(client_session_event_handler_,
233                   OnSessionStateChange(Session::CONNECTED))
234           .Times(AtMost(1));
235       EXPECT_CALL(client_session_event_handler_,
236                   OnSessionStateChange(Session::AUTHENTICATING))
237           .Times(AtMost(1));
238       if (expect_fail) {
239         EXPECT_CALL(client_session_event_handler_,
240                     OnSessionStateChange(Session::FAILED))
241             .Times(1);
242       } else {
243         EXPECT_CALL(client_session_event_handler_,
244                     OnSessionStateChange(Session::AUTHENTICATED))
245             .Times(1);
246         // Expect that the connection will be closed eventually.
247         EXPECT_CALL(client_session_event_handler_,
248                     OnSessionStateChange(Session::CLOSED))
249             .Times(AtMost(1));
250       }
251     }
252
253     scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
254         FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true));
255
256     client_session_ = client_server_->Connect(
257         kHostJid, authenticator.Pass(),
258         CandidateSessionConfig::CreateDefault());
259     client_session_->SetEventHandler(&client_session_event_handler_);
260
261     base::RunLoop().RunUntilIdle();
262   }
263
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)));
271
272     int counter = 2;
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();
279
280     EXPECT_TRUE(client_socket_.get());
281     EXPECT_TRUE(host_socket_.get());
282   }
283
284   void ExpectRouteChange(const std::string& channel_name) {
285     EXPECT_CALL(host_session_event_handler_,
286                 OnSessionRouteChange(channel_name, _))
287         .Times(AtLeast(1));
288     EXPECT_CALL(client_session_event_handler_,
289                 OnSessionRouteChange(channel_name, _))
290         .Times(AtLeast(1));
291   }
292
293   scoped_ptr<base::MessageLoopForIO> message_loop_;
294
295   scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
296   scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
297
298   scoped_ptr<JingleSessionManager> host_server_;
299   MockSessionManagerListener host_server_listener_;
300   scoped_ptr<JingleSessionManager> client_server_;
301   MockSessionManagerListener client_server_listener_;
302
303   scoped_ptr<Session> host_session_;
304   MockSessionEventHandler host_session_event_handler_;
305   scoped_ptr<Session> client_session_;
306   MockSessionEventHandler client_session_event_handler_;
307
308   MockStreamChannelCallback client_channel_callback_;
309   MockStreamChannelCallback host_channel_callback_;
310
311   scoped_ptr<net::StreamSocket> client_socket_;
312   scoped_ptr<net::StreamSocket> host_socket_;
313 };
314
315
316 // Verify that we can create and destroy session managers without a
317 // connection.
318 TEST_F(JingleSessionTest, CreateAndDestoy) {
319   CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
320 }
321
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);
326
327   // Reject incoming session.
328   EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
329       .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
330
331   {
332     InSequence dummy;
333     EXPECT_CALL(client_session_event_handler_,
334                 OnSessionStateChange(Session::FAILED))
335         .Times(1);
336   }
337
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_);
343
344   base::RunLoop().RunUntilIdle();
345 }
346
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);
351
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")));
361 }
362
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);
367 }
368
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);
373 }
374
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);
379 }
380
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));
386
387   ASSERT_NO_FATAL_FAILURE(CreateChannel());
388
389   StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
390                                 kMessageSize, kMessages);
391   tester.Start();
392   message_loop_->Run();
393   tester.CheckResults();
394 }
395
396 TEST_F(JingleSessionTest, DeleteSessionOnIncomingConnection) {
397   CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
398
399   EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
400       .WillOnce(DoAll(
401           WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
402           SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
403
404   EXPECT_CALL(host_session_event_handler_,
405       OnSessionStateChange(Session::CONNECTED))
406       .Times(AtMost(1));
407
408   EXPECT_CALL(host_session_event_handler_,
409       OnSessionStateChange(Session::AUTHENTICATING))
410       .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession));
411
412   scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
413       FakeAuthenticator::CLIENT, 3, FakeAuthenticator::ACCEPT, true));
414
415   client_session_ = client_server_->Connect(
416       kHostJid, authenticator.Pass(),
417       CandidateSessionConfig::CreateDefault());
418
419   base::RunLoop().RunUntilIdle();
420 }
421
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);
427
428   EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
429       .WillOnce(DoAll(
430           WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
431           SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
432
433   EXPECT_CALL(host_session_event_handler_,
434       OnSessionStateChange(Session::CONNECTED))
435       .Times(AtMost(1));
436
437   EXPECT_CALL(host_session_event_handler_,
438       OnSessionStateChange(Session::AUTHENTICATING))
439       .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession));
440
441   scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
442       FakeAuthenticator::CLIENT, 3, FakeAuthenticator::ACCEPT, true));
443
444   client_session_ = client_server_->Connect(
445       kHostJid, authenticator.Pass(),
446       CandidateSessionConfig::CreateDefault());
447   base::RunLoop().RunUntilIdle();
448 }
449
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));
455
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)));
462
463   int counter = 2;
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();
470
471   EXPECT_TRUE(client_socket_.get());
472   EXPECT_TRUE(host_socket_.get());
473
474   StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
475                                 kMessageSize, kMessages);
476   tester.Start();
477   message_loop_->Run();
478   tester.CheckResults();
479 }
480
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));
486
487   ASSERT_NO_FATAL_FAILURE(CreateChannel());
488
489   StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
490                                 kMessageSize, kMessages);
491   tester.Start();
492   message_loop_->Run();
493   tester.CheckResults();
494 }
495
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));
501
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)));
508
509   // Terminate the message loop when we get rejection notification
510   // from the host.
511   EXPECT_CALL(host_channel_callback_, OnDone(NULL))
512       .WillOnce(QuitThread());
513   EXPECT_CALL(client_channel_callback_, OnDone(_))
514       .Times(AtMost(1));
515   ExpectRouteChange(kChannelName);
516
517   message_loop_->Run();
518
519   EXPECT_TRUE(!host_socket_.get());
520 }
521
522 }  // namespace protocol
523 }  // namespace remoting