Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / remoting / protocol / jingle_session_unittest.cc
blobd6553861e506cc9212a8162429f4a07cf1b609d9
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"
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/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/protocol/p2p_stream_socket.h"
26 #include "remoting/protocol/stream_channel_factory.h"
27 #include "remoting/signaling/fake_signal_strategy.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 using testing::_;
32 using testing::AtLeast;
33 using testing::AtMost;
34 using testing::DeleteArg;
35 using testing::DoAll;
36 using testing::InSequence;
37 using testing::Invoke;
38 using testing::InvokeWithoutArgs;
39 using testing::Return;
40 using testing::SaveArg;
41 using testing::SetArgumentPointee;
42 using testing::WithArg;
44 namespace remoting {
45 namespace protocol {
47 namespace {
49 const char kHostJid[] = "host1@gmail.com/123";
50 const char kClientJid[] = "host2@gmail.com/321";
52 // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
53 // between messages (about 1 second for 100 messages).
54 const int kMessageSize = 1024;
55 const int kMessages = 100;
56 const char kChannelName[] = "test_channel";
58 void QuitCurrentThread() {
59 base::MessageLoop::current()->PostTask(FROM_HERE,
60 base::MessageLoop::QuitClosure());
63 ACTION(QuitThread) {
64 QuitCurrentThread();
67 ACTION_P(QuitThreadOnCounter, counter) {
68 --(*counter);
69 EXPECT_GE(*counter, 0);
70 if (*counter == 0)
71 QuitCurrentThread();
74 class MockSessionManagerListener : public SessionManager::Listener {
75 public:
76 MOCK_METHOD0(OnSessionManagerReady, void());
77 MOCK_METHOD2(OnIncomingSession,
78 void(Session*,
79 SessionManager::IncomingSessionResponse*));
82 class MockSessionEventHandler : public Session::EventHandler {
83 public:
84 MOCK_METHOD1(OnSessionStateChange, void(Session::State));
85 MOCK_METHOD2(OnSessionRouteChange, void(const std::string& channel_name,
86 const TransportRoute& route));
89 class MockChannelCreatedCallback {
90 public:
91 MOCK_METHOD1(OnDone, void(P2PStreamSocket* socket));
94 } // namespace
96 class JingleSessionTest : public testing::Test {
97 public:
98 JingleSessionTest() {
99 message_loop_.reset(new base::MessageLoopForIO());
100 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
103 // Helper method that handles OnIncomingSession().
104 void SetHostSession(Session* session) {
105 DCHECK(session);
106 host_session_.reset(session);
107 host_session_->SetEventHandler(&host_session_event_handler_);
109 session->set_config(standard_ice_ ? SessionConfig::ForTest()
110 : SessionConfig::WithLegacyIceForTest());
113 void DeleteSession() {
114 host_session_.reset();
117 void OnClientChannelCreated(scoped_ptr<P2PStreamSocket> socket) {
118 client_channel_callback_.OnDone(socket.get());
119 client_socket_ = socket.Pass();
122 void OnHostChannelCreated(scoped_ptr<P2PStreamSocket> socket) {
123 host_channel_callback_.OnDone(socket.get());
124 host_socket_ = socket.Pass();
127 protected:
128 void SetUp() override {}
130 void TearDown() override {
131 CloseSessions();
132 CloseSessionManager();
133 base::RunLoop().RunUntilIdle();
136 void CloseSessions() {
137 host_socket_.reset();
138 host_session_.reset();
139 client_socket_.reset();
140 client_session_.reset();
143 void CreateSessionManagers(int auth_round_trips, int messages_till_start,
144 FakeAuthenticator::Action auth_action) {
145 host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
146 client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
147 FakeSignalStrategy::Connect(host_signal_strategy_.get(),
148 client_signal_strategy_.get());
150 EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
151 .Times(1);
153 NetworkSettings network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
155 scoped_ptr<TransportFactory> host_transport(new LibjingleTransportFactory(
156 nullptr,
157 ChromiumPortAllocator::Create(nullptr, network_settings).Pass(),
158 network_settings, TransportRole::SERVER));
159 host_server_.reset(new JingleSessionManager(host_transport.Pass()));
160 host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
162 scoped_ptr<AuthenticatorFactory> factory(
163 new FakeHostAuthenticatorFactory(auth_round_trips,
164 messages_till_start, auth_action, true));
165 host_server_->set_authenticator_factory(factory.Pass());
167 EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
168 .Times(1);
169 scoped_ptr<TransportFactory> client_transport(new LibjingleTransportFactory(
170 nullptr,
171 ChromiumPortAllocator::Create(nullptr, network_settings).Pass(),
172 network_settings, TransportRole::CLIENT));
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,
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)));
206 InSequence dummy;
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));
230 InSequence dummy;
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));
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()->CreateChannel(
266 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
267 base::Unretained(this)));
268 host_session_->GetTransportChannelFactory()->CreateChannel(
269 kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
270 base::Unretained(this)));
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();
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, _))
287 .Times(AtLeast(1));
288 EXPECT_CALL(client_session_event_handler_,
289 OnSessionRouteChange(channel_name, _))
290 .Times(AtLeast(1));
293 scoped_ptr<base::MessageLoopForIO> message_loop_;
295 bool standard_ice_ = true;
297 scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
298 scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
300 scoped_ptr<JingleSessionManager> host_server_;
301 MockSessionManagerListener host_server_listener_;
302 scoped_ptr<JingleSessionManager> client_server_;
303 MockSessionManagerListener client_server_listener_;
305 scoped_ptr<Session> host_session_;
306 MockSessionEventHandler host_session_event_handler_;
307 scoped_ptr<Session> client_session_;
308 MockSessionEventHandler client_session_event_handler_;
310 MockChannelCreatedCallback client_channel_callback_;
311 MockChannelCreatedCallback host_channel_callback_;
313 scoped_ptr<P2PStreamSocket> client_socket_;
314 scoped_ptr<P2PStreamSocket> host_socket_;
318 // Verify that we can create and destroy session managers without a
319 // connection.
320 TEST_F(JingleSessionTest, CreateAndDestoy) {
321 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
324 // Verify that an incoming session can be rejected, and that the
325 // status of the connection is set to FAILED in this case.
326 TEST_F(JingleSessionTest, RejectConnection) {
327 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
329 // Reject incoming session.
330 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
331 .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
334 InSequence dummy;
335 EXPECT_CALL(client_session_event_handler_,
336 OnSessionStateChange(Session::FAILED))
337 .Times(1);
340 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
341 FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true));
342 client_session_ = client_server_->Connect(
343 kHostJid, authenticator.Pass(), CandidateSessionConfig::CreateDefault());
344 client_session_->SetEventHandler(&client_session_event_handler_);
346 base::RunLoop().RunUntilIdle();
349 // Verify that we can connect two endpoints with single-step authentication.
350 TEST_F(JingleSessionTest, Connect) {
351 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
352 InitiateConnection(1, FakeAuthenticator::ACCEPT, false);
354 // Verify that the client specified correct initiator value.
355 ASSERT_GT(host_signal_strategy_->received_messages().size(), 0U);
356 const buzz::XmlElement* initiate_xml =
357 host_signal_strategy_->received_messages().front();
358 const buzz::XmlElement* jingle_element =
359 initiate_xml->FirstNamed(buzz::QName("urn:xmpp:jingle:1", "jingle"));
360 ASSERT_TRUE(jingle_element);
361 ASSERT_EQ(kClientJid,
362 jingle_element->Attr(buzz::QName(std::string(), "initiator")));
365 // Verify that we can connect two endpoints with multi-step authentication.
366 TEST_F(JingleSessionTest, ConnectWithMultistep) {
367 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
368 InitiateConnection(3, FakeAuthenticator::ACCEPT, false);
371 // Verify that connection is terminated when single-step auth fails.
372 TEST_F(JingleSessionTest, ConnectWithBadAuth) {
373 CreateSessionManagers(1, FakeAuthenticator::REJECT);
374 InitiateConnection(1, FakeAuthenticator::ACCEPT, true);
377 // Verify that connection is terminated when multi-step auth fails.
378 TEST_F(JingleSessionTest, ConnectWithBadMultistepAuth) {
379 CreateSessionManagers(3, FakeAuthenticator::REJECT);
380 InitiateConnection(3, FakeAuthenticator::ACCEPT, true);
383 // Verify that data can be sent over stream channel.
384 TEST_F(JingleSessionTest, TestStreamChannel) {
385 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
386 ASSERT_NO_FATAL_FAILURE(
387 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
389 ASSERT_NO_FATAL_FAILURE(CreateChannel());
391 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
392 kMessageSize, kMessages);
393 tester.Start();
394 message_loop_->Run();
395 tester.CheckResults();
398 // Verify that we can still connect using legacy GICE transport.
399 TEST_F(JingleSessionTest, TestLegacyIceConnection) {
400 standard_ice_ = false;
402 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
403 ASSERT_NO_FATAL_FAILURE(
404 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
406 ASSERT_NO_FATAL_FAILURE(CreateChannel());
408 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
409 kMessageSize, kMessages);
410 tester.Start();
411 message_loop_->Run();
412 tester.CheckResults();
415 TEST_F(JingleSessionTest, DeleteSessionOnIncomingConnection) {
416 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
418 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
419 .WillOnce(DoAll(
420 WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
421 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
423 EXPECT_CALL(host_session_event_handler_,
424 OnSessionStateChange(Session::CONNECTED))
425 .Times(AtMost(1));
427 EXPECT_CALL(host_session_event_handler_,
428 OnSessionStateChange(Session::AUTHENTICATING))
429 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession));
431 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
432 FakeAuthenticator::CLIENT, 3, FakeAuthenticator::ACCEPT, true));
434 client_session_ = client_server_->Connect(
435 kHostJid, authenticator.Pass(),
436 CandidateSessionConfig::CreateDefault());
438 base::RunLoop().RunUntilIdle();
441 TEST_F(JingleSessionTest, DeleteSessionOnAuth) {
442 // Same as the previous test, but set messages_till_started to 2 in
443 // CreateSessionManagers so that the session will goes into the
444 // AUTHENTICATING state after two message exchanges.
445 CreateSessionManagers(3, 2, FakeAuthenticator::ACCEPT);
447 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
448 .WillOnce(DoAll(
449 WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
450 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
452 EXPECT_CALL(host_session_event_handler_,
453 OnSessionStateChange(Session::CONNECTED))
454 .Times(AtMost(1));
456 EXPECT_CALL(host_session_event_handler_,
457 OnSessionStateChange(Session::AUTHENTICATING))
458 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession));
460 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
461 FakeAuthenticator::CLIENT, 3, FakeAuthenticator::ACCEPT, true));
463 client_session_ = client_server_->Connect(
464 kHostJid, authenticator.Pass(),
465 CandidateSessionConfig::CreateDefault());
466 base::RunLoop().RunUntilIdle();
469 // Verify that data can be sent over a multiplexed channel.
470 TEST_F(JingleSessionTest, TestMuxStreamChannel) {
471 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
472 ASSERT_NO_FATAL_FAILURE(
473 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
475 client_session_->GetMultiplexedChannelFactory()->CreateChannel(
476 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
477 base::Unretained(this)));
478 host_session_->GetMultiplexedChannelFactory()->CreateChannel(
479 kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
480 base::Unretained(this)));
482 int counter = 2;
483 ExpectRouteChange("mux");
484 EXPECT_CALL(client_channel_callback_, OnDone(_))
485 .WillOnce(QuitThreadOnCounter(&counter));
486 EXPECT_CALL(host_channel_callback_, OnDone(_))
487 .WillOnce(QuitThreadOnCounter(&counter));
488 message_loop_->Run();
490 EXPECT_TRUE(client_socket_.get());
491 EXPECT_TRUE(host_socket_.get());
493 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
494 kMessageSize, kMessages);
495 tester.Start();
496 message_loop_->Run();
497 tester.CheckResults();
500 // Verify that we can connect channels with multistep auth.
501 TEST_F(JingleSessionTest, TestMultistepAuthStreamChannel) {
502 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
503 ASSERT_NO_FATAL_FAILURE(
504 InitiateConnection(3, FakeAuthenticator::ACCEPT, false));
506 ASSERT_NO_FATAL_FAILURE(CreateChannel());
508 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
509 kMessageSize, kMessages);
510 tester.Start();
511 message_loop_->Run();
512 tester.CheckResults();
515 // Verify that we shutdown properly when channel authentication fails.
516 TEST_F(JingleSessionTest, TestFailedChannelAuth) {
517 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL);
518 ASSERT_NO_FATAL_FAILURE(
519 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
521 client_session_->GetTransportChannelFactory()->CreateChannel(
522 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
523 base::Unretained(this)));
524 host_session_->GetTransportChannelFactory()->CreateChannel(
525 kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
526 base::Unretained(this)));
528 // Terminate the message loop when we get rejection notification
529 // from the host.
530 EXPECT_CALL(host_channel_callback_, OnDone(nullptr))
531 .WillOnce(QuitThread());
532 ExpectRouteChange(kChannelName);
534 message_loop_->Run();
536 client_session_->GetTransportChannelFactory()->CancelChannelCreation(
537 kChannelName);
539 EXPECT_TRUE(!host_socket_.get());
542 TEST_F(JingleSessionTest, TestCancelChannelCreation) {
543 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL);
544 ASSERT_NO_FATAL_FAILURE(
545 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
547 client_session_->GetTransportChannelFactory()->CreateChannel(
548 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
549 base::Unretained(this)));
550 client_session_->GetTransportChannelFactory()->CancelChannelCreation(
551 kChannelName);
553 EXPECT_TRUE(!client_socket_.get());
556 // Verify that we can still connect even when there is a delay in signaling
557 // messages delivery.
558 TEST_F(JingleSessionTest, TestDelayedSignaling) {
559 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
560 ASSERT_NO_FATAL_FAILURE(
561 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
563 host_signal_strategy_->set_send_delay(
564 base::TimeDelta::FromMilliseconds(100));
566 ASSERT_NO_FATAL_FAILURE(CreateChannel());
568 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
569 kMessageSize, 1);
570 tester.Start();
571 message_loop_->Run();
572 tester.CheckResults();
575 } // namespace protocol
576 } // namespace remoting