Update WebFrameTestProxy and WebTestProxy to mostly follow Chrome style.
[chromium-blink-merge.git] / remoting / protocol / jingle_session_unittest.cc
blob2f9510070e763bdd973c2eebe100a1e41051304f
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 "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"
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;
41 namespace remoting {
42 namespace protocol {
44 namespace {
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());
60 ACTION(QuitThread) {
61 QuitCurrentThread();
64 ACTION_P(QuitThreadOnCounter, counter) {
65 --(*counter);
66 EXPECT_GE(*counter, 0);
67 if (*counter == 0)
68 QuitCurrentThread();
71 class MockSessionManagerListener : public SessionManager::Listener {
72 public:
73 MOCK_METHOD0(OnSessionManagerReady, void());
74 MOCK_METHOD2(OnIncomingSession,
75 void(Session*,
76 SessionManager::IncomingSessionResponse*));
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));
86 class MockStreamChannelCallback {
87 public:
88 MOCK_METHOD1(OnDone, void(net::StreamSocket* socket));
91 } // namespace
93 class JingleSessionTest : public testing::Test {
94 public:
95 JingleSessionTest() {
96 message_loop_.reset(new base::MessageLoopForIO());
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_);
105 session->set_config(SessionConfig::ForTest());
108 void DeleteSession() {
109 host_session_.reset();
112 void OnClientChannelCreated(scoped_ptr<net::StreamSocket> socket) {
113 client_channel_callback_.OnDone(socket.get());
114 client_socket_ = socket.Pass();
117 void OnHostChannelCreated(scoped_ptr<net::StreamSocket> socket) {
118 host_channel_callback_.OnDone(socket.get());
119 host_socket_ = socket.Pass();
122 protected:
123 virtual void SetUp() {
126 virtual void TearDown() {
127 CloseSessions();
128 CloseSessionManager();
129 base::RunLoop().RunUntilIdle();
132 void CloseSessions() {
133 host_socket_.reset();
134 host_session_.reset();
135 client_socket_.reset();
136 client_session_.reset();
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());
146 EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
147 .Times(1);
149 NetworkSettings network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
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_);
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());
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_);
177 void CreateSessionManagers(int auth_round_trips,
178 FakeAuthenticator::Action auth_action) {
179 CreateSessionManagers(auth_round_trips, 0, auth_action);
182 void CloseSessionManager() {
183 if (host_server_.get()) {
184 host_server_->Close();
185 host_server_.reset();
187 if (client_server_.get()) {
188 client_server_->Close();
189 client_server_.reset();
191 host_signal_strategy_.reset();
192 client_signal_strategy_.reset();
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)));
204 InSequence dummy;
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));
228 InSequence dummy;
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));
251 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
252 FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true));
254 client_session_ = client_server_->Connect(
255 kHostJid, authenticator.Pass(),
256 CandidateSessionConfig::CreateDefault());
257 client_session_->SetEventHandler(&client_session_event_handler_);
259 base::RunLoop().RunUntilIdle();
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)));
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();
278 EXPECT_TRUE(client_socket_.get());
279 EXPECT_TRUE(host_socket_.get());
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));
291 scoped_ptr<base::MessageLoopForIO> message_loop_;
293 scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
294 scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
296 scoped_ptr<JingleSessionManager> host_server_;
297 MockSessionManagerListener host_server_listener_;
298 scoped_ptr<JingleSessionManager> client_server_;
299 MockSessionManagerListener client_server_listener_;
301 scoped_ptr<Session> host_session_;
302 MockSessionEventHandler host_session_event_handler_;
303 scoped_ptr<Session> client_session_;
304 MockSessionEventHandler client_session_event_handler_;
306 MockStreamChannelCallback client_channel_callback_;
307 MockStreamChannelCallback host_channel_callback_;
309 scoped_ptr<net::StreamSocket> client_socket_;
310 scoped_ptr<net::StreamSocket> host_socket_;
314 // Verify that we can create and destroy session managers without a
315 // connection.
316 TEST_F(JingleSessionTest, CreateAndDestoy) {
317 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
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);
325 // Reject incoming session.
326 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
327 .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
330 InSequence dummy;
331 EXPECT_CALL(client_session_event_handler_,
332 OnSessionStateChange(Session::FAILED))
333 .Times(1);
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_);
342 base::RunLoop().RunUntilIdle();
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);
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")));
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);
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);
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);
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));
385 ASSERT_NO_FATAL_FAILURE(CreateChannel());
387 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
388 kMessageSize, kMessages);
389 tester.Start();
390 message_loop_->Run();
391 tester.CheckResults();
394 TEST_F(JingleSessionTest, DeleteSessionOnIncomingConnection) {
395 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
397 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
398 .WillOnce(DoAll(
399 WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
400 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
402 EXPECT_CALL(host_session_event_handler_,
403 OnSessionStateChange(Session::CONNECTED))
404 .Times(AtMost(1));
406 EXPECT_CALL(host_session_event_handler_,
407 OnSessionStateChange(Session::AUTHENTICATING))
408 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession));
410 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
411 FakeAuthenticator::CLIENT, 3, FakeAuthenticator::ACCEPT, true));
413 client_session_ = client_server_->Connect(
414 kHostJid, authenticator.Pass(),
415 CandidateSessionConfig::CreateDefault());
417 base::RunLoop().RunUntilIdle();
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);
426 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
427 .WillOnce(DoAll(
428 WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
429 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
431 EXPECT_CALL(host_session_event_handler_,
432 OnSessionStateChange(Session::CONNECTED))
433 .Times(AtMost(1));
435 EXPECT_CALL(host_session_event_handler_,
436 OnSessionStateChange(Session::AUTHENTICATING))
437 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession));
439 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
440 FakeAuthenticator::CLIENT, 3, FakeAuthenticator::ACCEPT, true));
442 client_session_ = client_server_->Connect(
443 kHostJid, authenticator.Pass(),
444 CandidateSessionConfig::CreateDefault());
445 base::RunLoop().RunUntilIdle();
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));
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)));
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();
469 EXPECT_TRUE(client_socket_.get());
470 EXPECT_TRUE(host_socket_.get());
472 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
473 kMessageSize, kMessages);
474 tester.Start();
475 message_loop_->Run();
476 tester.CheckResults();
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));
485 ASSERT_NO_FATAL_FAILURE(CreateChannel());
487 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
488 kMessageSize, kMessages);
489 tester.Start();
490 message_loop_->Run();
491 tester.CheckResults();
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));
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)));
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);
515 message_loop_->Run();
517 EXPECT_TRUE(!host_socket_.get());
520 } // namespace protocol
521 } // namespace remoting