- add sources.
[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/test/test_timeouts.h"
10 #include "base/time/time.h"
11 #include "net/socket/socket.h"
12 #include "net/socket/stream_socket.h"
13 #include "remoting/base/constants.h"
14 #include "remoting/jingle_glue/fake_signal_strategy.h"
15 #include "remoting/protocol/authenticator.h"
16 #include "remoting/protocol/channel_authenticator.h"
17 #include "remoting/protocol/connection_tester.h"
18 #include "remoting/protocol/fake_authenticator.h"
19 #include "remoting/protocol/jingle_session_manager.h"
20 #include "remoting/protocol/libjingle_transport_factory.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using testing::_;
25 using testing::AtLeast;
26 using testing::AtMost;
27 using testing::DeleteArg;
28 using testing::DoAll;
29 using testing::InSequence;
30 using testing::Invoke;
31 using testing::InvokeWithoutArgs;
32 using testing::Return;
33 using testing::SaveArg;
34 using testing::SetArgumentPointee;
35 using testing::WithArg;
36
37 namespace remoting {
38 namespace protocol {
39
40 namespace {
41
42 const char kHostJid[] = "host1@gmail.com/123";
43 const char kClientJid[] = "host2@gmail.com/321";
44
45 // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
46 // between messages (about 1 second for 100 messages).
47 const int kMessageSize = 1024;
48 const int kMessages = 100;
49 const char kChannelName[] = "test_channel";
50
51 void QuitCurrentThread() {
52   base::MessageLoop::current()->PostTask(FROM_HERE,
53                                          base::MessageLoop::QuitClosure());
54 }
55
56 ACTION(QuitThread) {
57   QuitCurrentThread();
58 }
59
60 ACTION_P(QuitThreadOnCounter, counter) {
61   --(*counter);
62   EXPECT_GE(*counter, 0);
63   if (*counter == 0)
64     QuitCurrentThread();
65 }
66
67 class MockSessionManagerListener : public SessionManager::Listener {
68  public:
69   MOCK_METHOD0(OnSessionManagerReady, void());
70   MOCK_METHOD2(OnIncomingSession,
71                void(Session*,
72                     SessionManager::IncomingSessionResponse*));
73 };
74
75 class MockSessionEventHandler : public Session::EventHandler {
76  public:
77   MOCK_METHOD1(OnSessionStateChange, void(Session::State));
78   MOCK_METHOD2(OnSessionRouteChange, void(const std::string& channel_name,
79                                           const TransportRoute& route));
80 };
81
82 class MockStreamChannelCallback {
83  public:
84   MOCK_METHOD1(OnDone, void(net::StreamSocket* socket));
85 };
86
87 }  // namespace
88
89 class JingleSessionTest : public testing::Test {
90  public:
91   JingleSessionTest() {
92     message_loop_.reset(new base::MessageLoopForIO());
93   }
94
95   // Helper method that handles OnIncomingSession().
96   void SetHostSession(Session* session) {
97     DCHECK(session);
98     host_session_.reset(session);
99     host_session_->SetEventHandler(&host_session_event_handler_);
100
101     session->set_config(SessionConfig::ForTest());
102   }
103
104   void OnClientChannelCreated(scoped_ptr<net::StreamSocket> socket) {
105     client_channel_callback_.OnDone(socket.get());
106     client_socket_ = socket.Pass();
107   }
108
109   void OnHostChannelCreated(scoped_ptr<net::StreamSocket> socket) {
110     host_channel_callback_.OnDone(socket.get());
111     host_socket_ = socket.Pass();
112   }
113
114  protected:
115   virtual void SetUp() {
116   }
117
118   virtual void TearDown() {
119     CloseSessions();
120     CloseSessionManager();
121     message_loop_->RunUntilIdle();
122   }
123
124   void CloseSessions() {
125     host_socket_.reset();
126     host_session_.reset();
127     client_socket_.reset();
128     client_session_.reset();
129   }
130
131   void CreateSessionManagers(int auth_round_trips,
132                         FakeAuthenticator::Action auth_action) {
133     host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
134     client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
135     FakeSignalStrategy::Connect(host_signal_strategy_.get(),
136                                 client_signal_strategy_.get());
137
138     EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
139         .Times(1);
140     host_server_.reset(new JingleSessionManager(
141         scoped_ptr<TransportFactory>(new LibjingleTransportFactory()),
142         false));
143     host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
144
145     scoped_ptr<AuthenticatorFactory> factory(
146         new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true));
147     host_server_->set_authenticator_factory(factory.Pass());
148
149     EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
150         .Times(1);
151     client_server_.reset(new JingleSessionManager(
152         scoped_ptr<TransportFactory>(new LibjingleTransportFactory()), false));
153     client_server_->Init(client_signal_strategy_.get(),
154                          &client_server_listener_);
155   }
156
157   void CloseSessionManager() {
158     if (host_server_.get()) {
159       host_server_->Close();
160       host_server_.reset();
161     }
162     if (client_server_.get()) {
163       client_server_->Close();
164       client_server_.reset();
165     }
166     host_signal_strategy_.reset();
167     client_signal_strategy_.reset();
168   }
169
170   void InitiateConnection(int auth_round_trips,
171                           FakeAuthenticator::Action auth_action,
172                           bool expect_fail) {
173     EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
174         .WillOnce(DoAll(
175             WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
176             SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
177
178     {
179       InSequence dummy;
180
181       EXPECT_CALL(host_session_event_handler_,
182                   OnSessionStateChange(Session::CONNECTED))
183           .Times(AtMost(1));
184       if (expect_fail) {
185         EXPECT_CALL(host_session_event_handler_,
186                     OnSessionStateChange(Session::FAILED))
187             .Times(1);
188       } else {
189         EXPECT_CALL(host_session_event_handler_,
190                     OnSessionStateChange(Session::AUTHENTICATED))
191             .Times(1);
192         // Expect that the connection will be closed eventually.
193         EXPECT_CALL(host_session_event_handler_,
194                     OnSessionStateChange(Session::CLOSED))
195             .Times(AtMost(1));
196       }
197     }
198
199     {
200       InSequence dummy;
201
202       EXPECT_CALL(client_session_event_handler_,
203                   OnSessionStateChange(Session::CONNECTED))
204           .Times(AtMost(1));
205       if (expect_fail) {
206         EXPECT_CALL(client_session_event_handler_,
207                     OnSessionStateChange(Session::FAILED))
208             .Times(1);
209       } else {
210         EXPECT_CALL(client_session_event_handler_,
211                     OnSessionStateChange(Session::AUTHENTICATED))
212             .Times(1);
213         // Expect that the connection will be closed eventually.
214         EXPECT_CALL(client_session_event_handler_,
215                     OnSessionStateChange(Session::CLOSED))
216             .Times(AtMost(1));
217       }
218     }
219
220     scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
221         FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true));
222
223     client_session_ = client_server_->Connect(
224         kHostJid, authenticator.Pass(),
225         CandidateSessionConfig::CreateDefault());
226     client_session_->SetEventHandler(&client_session_event_handler_);
227
228     message_loop_->RunUntilIdle();
229   }
230
231   void CreateChannel() {
232     client_session_->GetTransportChannelFactory()->CreateStreamChannel(
233         kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
234                                  base::Unretained(this)));
235     host_session_->GetTransportChannelFactory()->CreateStreamChannel(
236         kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
237                                  base::Unretained(this)));
238
239     int counter = 2;
240     ExpectRouteChange(kChannelName);
241     EXPECT_CALL(client_channel_callback_, OnDone(_))
242         .WillOnce(QuitThreadOnCounter(&counter));
243     EXPECT_CALL(host_channel_callback_, OnDone(_))
244         .WillOnce(QuitThreadOnCounter(&counter));
245     message_loop_->Run();
246
247     EXPECT_TRUE(client_socket_.get());
248     EXPECT_TRUE(host_socket_.get());
249   }
250
251   void ExpectRouteChange(const std::string& channel_name) {
252     EXPECT_CALL(host_session_event_handler_,
253                 OnSessionRouteChange(channel_name, _))
254         .Times(AtLeast(1));
255     EXPECT_CALL(client_session_event_handler_,
256                 OnSessionRouteChange(channel_name, _))
257         .Times(AtLeast(1));
258   }
259
260   scoped_ptr<base::MessageLoopForIO> message_loop_;
261
262   scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
263   scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
264
265   scoped_ptr<JingleSessionManager> host_server_;
266   MockSessionManagerListener host_server_listener_;
267   scoped_ptr<JingleSessionManager> client_server_;
268   MockSessionManagerListener client_server_listener_;
269
270   scoped_ptr<Session> host_session_;
271   MockSessionEventHandler host_session_event_handler_;
272   scoped_ptr<Session> client_session_;
273   MockSessionEventHandler client_session_event_handler_;
274
275   MockStreamChannelCallback client_channel_callback_;
276   MockStreamChannelCallback host_channel_callback_;
277
278   scoped_ptr<net::StreamSocket> client_socket_;
279   scoped_ptr<net::StreamSocket> host_socket_;
280 };
281
282
283 // Verify that we can create and destroy session managers without a
284 // connection.
285 TEST_F(JingleSessionTest, CreateAndDestoy) {
286   CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
287 }
288
289 // Verify that an incoming session can be rejected, and that the
290 // status of the connection is set to FAILED in this case.
291 TEST_F(JingleSessionTest, RejectConnection) {
292   CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
293
294   // Reject incoming session.
295   EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
296       .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
297
298   {
299     InSequence dummy;
300     EXPECT_CALL(client_session_event_handler_,
301                 OnSessionStateChange(Session::FAILED))
302         .Times(1);
303   }
304
305   scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
306       FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true));
307   client_session_ = client_server_->Connect(
308       kHostJid, authenticator.Pass(), CandidateSessionConfig::CreateDefault());
309   client_session_->SetEventHandler(&client_session_event_handler_);
310
311   message_loop_->RunUntilIdle();
312 }
313
314 // Verify that we can connect two endpoints with single-step authentication.
315 TEST_F(JingleSessionTest, Connect) {
316   CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
317   InitiateConnection(1, FakeAuthenticator::ACCEPT, false);
318
319   // Verify that the client specified correct initiator value.
320   ASSERT_GT(host_signal_strategy_->received_messages().size(), 0U);
321   const buzz::XmlElement* initiate_xml =
322       host_signal_strategy_->received_messages().front();
323   const buzz::XmlElement* jingle_element =
324       initiate_xml->FirstNamed(buzz::QName(kJingleNamespace, "jingle"));
325   ASSERT_TRUE(jingle_element);
326   ASSERT_EQ(kClientJid,
327             jingle_element->Attr(buzz::QName(std::string(), "initiator")));
328 }
329
330 // Verify that we can connect two endpoints with multi-step authentication.
331 TEST_F(JingleSessionTest, ConnectWithMultistep) {
332   CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
333   InitiateConnection(3, FakeAuthenticator::ACCEPT, false);
334 }
335
336 // Verify that connection is terminated when single-step auth fails.
337 TEST_F(JingleSessionTest, ConnectWithBadAuth) {
338   CreateSessionManagers(1, FakeAuthenticator::REJECT);
339   InitiateConnection(1, FakeAuthenticator::ACCEPT, true);
340 }
341
342 // Verify that connection is terminated when multi-step auth fails.
343 TEST_F(JingleSessionTest, ConnectWithBadMultistepAuth) {
344   CreateSessionManagers(3, FakeAuthenticator::REJECT);
345   InitiateConnection(3, FakeAuthenticator::ACCEPT, true);
346 }
347
348 // Verify that data can be sent over stream channel.
349 TEST_F(JingleSessionTest, TestStreamChannel) {
350   CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
351   ASSERT_NO_FATAL_FAILURE(
352       InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
353
354   ASSERT_NO_FATAL_FAILURE(CreateChannel());
355
356   StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
357                                 kMessageSize, kMessages);
358   tester.Start();
359   message_loop_->Run();
360   tester.CheckResults();
361 }
362
363 // Verify that data can be sent over a multiplexed channel.
364 TEST_F(JingleSessionTest, TestMuxStreamChannel) {
365   CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
366   ASSERT_NO_FATAL_FAILURE(
367       InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
368
369   client_session_->GetMultiplexedChannelFactory()->CreateStreamChannel(
370       kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
371                                base::Unretained(this)));
372   host_session_->GetMultiplexedChannelFactory()->CreateStreamChannel(
373       kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
374                                base::Unretained(this)));
375
376   int counter = 2;
377   ExpectRouteChange("mux");
378   EXPECT_CALL(client_channel_callback_, OnDone(_))
379       .WillOnce(QuitThreadOnCounter(&counter));
380   EXPECT_CALL(host_channel_callback_, OnDone(_))
381       .WillOnce(QuitThreadOnCounter(&counter));
382   message_loop_->Run();
383
384   EXPECT_TRUE(client_socket_.get());
385   EXPECT_TRUE(host_socket_.get());
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 // Verify that we can connect channels with multistep auth.
395 TEST_F(JingleSessionTest, TestMultistepAuthStreamChannel) {
396   CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
397   ASSERT_NO_FATAL_FAILURE(
398       InitiateConnection(3, FakeAuthenticator::ACCEPT, false));
399
400   ASSERT_NO_FATAL_FAILURE(CreateChannel());
401
402   StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
403                                 kMessageSize, kMessages);
404   tester.Start();
405   message_loop_->Run();
406   tester.CheckResults();
407 }
408
409 // Verify that we shutdown properly when channel authentication fails.
410 TEST_F(JingleSessionTest, TestFailedChannelAuth) {
411   CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL);
412   ASSERT_NO_FATAL_FAILURE(
413       InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
414
415   client_session_->GetTransportChannelFactory()->CreateStreamChannel(
416       kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
417                                base::Unretained(this)));
418   host_session_->GetTransportChannelFactory()->CreateStreamChannel(
419       kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
420                                base::Unretained(this)));
421
422   // Terminate the message loop when we get rejection notification
423   // from the host.
424   EXPECT_CALL(host_channel_callback_, OnDone(NULL))
425       .WillOnce(QuitThread());
426   EXPECT_CALL(client_channel_callback_, OnDone(_))
427       .Times(AtMost(1));
428   ExpectRouteChange(kChannelName);
429
430   message_loop_->Run();
431
432   EXPECT_TRUE(!host_socket_.get());
433 }
434
435 }  // namespace protocol
436 }  // namespace remoting