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