Refactor SnapSizer now that the --ash-multiple-snap-window-widths flag no longer...
[chromium-blink-merge.git] / remoting / protocol / jingle_session_unittest.cc
blobdcca077221b9a8dcc5348d832cfed44195b4971a
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 OnClientChannelCreated(scoped_ptr<net::StreamSocket> socket) {
109 client_channel_callback_.OnDone(socket.get());
110 client_socket_ = socket.Pass();
113 void OnHostChannelCreated(scoped_ptr<net::StreamSocket> socket) {
114 host_channel_callback_.OnDone(socket.get());
115 host_socket_ = socket.Pass();
118 protected:
119 virtual void SetUp() {
122 virtual void TearDown() {
123 CloseSessions();
124 CloseSessionManager();
125 base::RunLoop().RunUntilIdle();
128 void CloseSessions() {
129 host_socket_.reset();
130 host_session_.reset();
131 client_socket_.reset();
132 client_session_.reset();
135 void CreateSessionManagers(int auth_round_trips,
136 FakeAuthenticator::Action auth_action) {
137 host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
138 client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
139 FakeSignalStrategy::Connect(host_signal_strategy_.get(),
140 client_signal_strategy_.get());
142 EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
143 .Times(1);
145 NetworkSettings network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
147 scoped_ptr<TransportFactory> host_transport(new LibjingleTransportFactory(
148 NULL,
149 ChromiumPortAllocator::Create(NULL, network_settings)
150 .PassAs<cricket::HttpPortAllocatorBase>(),
151 network_settings));
152 host_server_.reset(new JingleSessionManager(host_transport.Pass()));
153 host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
155 scoped_ptr<AuthenticatorFactory> factory(
156 new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true));
157 host_server_->set_authenticator_factory(factory.Pass());
159 EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
160 .Times(1);
161 scoped_ptr<TransportFactory> client_transport(new LibjingleTransportFactory(
162 NULL,
163 ChromiumPortAllocator::Create(NULL, network_settings)
164 .PassAs<cricket::HttpPortAllocatorBase>(),
165 network_settings));
166 client_server_.reset(
167 new JingleSessionManager(client_transport.Pass()));
168 client_server_->Init(client_signal_strategy_.get(),
169 &client_server_listener_);
172 void CloseSessionManager() {
173 if (host_server_.get()) {
174 host_server_->Close();
175 host_server_.reset();
177 if (client_server_.get()) {
178 client_server_->Close();
179 client_server_.reset();
181 host_signal_strategy_.reset();
182 client_signal_strategy_.reset();
185 void InitiateConnection(int auth_round_trips,
186 FakeAuthenticator::Action auth_action,
187 bool expect_fail) {
188 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
189 .WillOnce(DoAll(
190 WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
191 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
194 InSequence dummy;
196 EXPECT_CALL(host_session_event_handler_,
197 OnSessionStateChange(Session::CONNECTED))
198 .Times(AtMost(1));
199 if (expect_fail) {
200 EXPECT_CALL(host_session_event_handler_,
201 OnSessionStateChange(Session::FAILED))
202 .Times(1);
203 } else {
204 EXPECT_CALL(host_session_event_handler_,
205 OnSessionStateChange(Session::AUTHENTICATED))
206 .Times(1);
207 // Expect that the connection will be closed eventually.
208 EXPECT_CALL(host_session_event_handler_,
209 OnSessionStateChange(Session::CLOSED))
210 .Times(AtMost(1));
215 InSequence dummy;
217 EXPECT_CALL(client_session_event_handler_,
218 OnSessionStateChange(Session::CONNECTED))
219 .Times(AtMost(1));
220 if (expect_fail) {
221 EXPECT_CALL(client_session_event_handler_,
222 OnSessionStateChange(Session::FAILED))
223 .Times(1);
224 } else {
225 EXPECT_CALL(client_session_event_handler_,
226 OnSessionStateChange(Session::AUTHENTICATED))
227 .Times(1);
228 // Expect that the connection will be closed eventually.
229 EXPECT_CALL(client_session_event_handler_,
230 OnSessionStateChange(Session::CLOSED))
231 .Times(AtMost(1));
235 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
236 FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true));
238 client_session_ = client_server_->Connect(
239 kHostJid, authenticator.Pass(),
240 CandidateSessionConfig::CreateDefault());
241 client_session_->SetEventHandler(&client_session_event_handler_);
243 base::RunLoop().RunUntilIdle();
246 void CreateChannel() {
247 client_session_->GetTransportChannelFactory()->CreateStreamChannel(
248 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
249 base::Unretained(this)));
250 host_session_->GetTransportChannelFactory()->CreateStreamChannel(
251 kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
252 base::Unretained(this)));
254 int counter = 2;
255 ExpectRouteChange(kChannelName);
256 EXPECT_CALL(client_channel_callback_, OnDone(_))
257 .WillOnce(QuitThreadOnCounter(&counter));
258 EXPECT_CALL(host_channel_callback_, OnDone(_))
259 .WillOnce(QuitThreadOnCounter(&counter));
260 message_loop_->Run();
262 EXPECT_TRUE(client_socket_.get());
263 EXPECT_TRUE(host_socket_.get());
266 void ExpectRouteChange(const std::string& channel_name) {
267 EXPECT_CALL(host_session_event_handler_,
268 OnSessionRouteChange(channel_name, _))
269 .Times(AtLeast(1));
270 EXPECT_CALL(client_session_event_handler_,
271 OnSessionRouteChange(channel_name, _))
272 .Times(AtLeast(1));
275 scoped_ptr<base::MessageLoopForIO> message_loop_;
277 scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
278 scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
280 scoped_ptr<JingleSessionManager> host_server_;
281 MockSessionManagerListener host_server_listener_;
282 scoped_ptr<JingleSessionManager> client_server_;
283 MockSessionManagerListener client_server_listener_;
285 scoped_ptr<Session> host_session_;
286 MockSessionEventHandler host_session_event_handler_;
287 scoped_ptr<Session> client_session_;
288 MockSessionEventHandler client_session_event_handler_;
290 MockStreamChannelCallback client_channel_callback_;
291 MockStreamChannelCallback host_channel_callback_;
293 scoped_ptr<net::StreamSocket> client_socket_;
294 scoped_ptr<net::StreamSocket> host_socket_;
298 // Verify that we can create and destroy session managers without a
299 // connection.
300 TEST_F(JingleSessionTest, CreateAndDestoy) {
301 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
304 // Verify that an incoming session can be rejected, and that the
305 // status of the connection is set to FAILED in this case.
306 TEST_F(JingleSessionTest, RejectConnection) {
307 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
309 // Reject incoming session.
310 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
311 .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
314 InSequence dummy;
315 EXPECT_CALL(client_session_event_handler_,
316 OnSessionStateChange(Session::FAILED))
317 .Times(1);
320 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
321 FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true));
322 client_session_ = client_server_->Connect(
323 kHostJid, authenticator.Pass(), CandidateSessionConfig::CreateDefault());
324 client_session_->SetEventHandler(&client_session_event_handler_);
326 base::RunLoop().RunUntilIdle();
329 // Verify that we can connect two endpoints with single-step authentication.
330 TEST_F(JingleSessionTest, Connect) {
331 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
332 InitiateConnection(1, FakeAuthenticator::ACCEPT, false);
334 // Verify that the client specified correct initiator value.
335 ASSERT_GT(host_signal_strategy_->received_messages().size(), 0U);
336 const buzz::XmlElement* initiate_xml =
337 host_signal_strategy_->received_messages().front();
338 const buzz::XmlElement* jingle_element =
339 initiate_xml->FirstNamed(buzz::QName(kJingleNamespace, "jingle"));
340 ASSERT_TRUE(jingle_element);
341 ASSERT_EQ(kClientJid,
342 jingle_element->Attr(buzz::QName(std::string(), "initiator")));
345 // Verify that we can connect two endpoints with multi-step authentication.
346 TEST_F(JingleSessionTest, ConnectWithMultistep) {
347 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
348 InitiateConnection(3, FakeAuthenticator::ACCEPT, false);
351 // Verify that connection is terminated when single-step auth fails.
352 TEST_F(JingleSessionTest, ConnectWithBadAuth) {
353 CreateSessionManagers(1, FakeAuthenticator::REJECT);
354 InitiateConnection(1, FakeAuthenticator::ACCEPT, true);
357 // Verify that connection is terminated when multi-step auth fails.
358 TEST_F(JingleSessionTest, ConnectWithBadMultistepAuth) {
359 CreateSessionManagers(3, FakeAuthenticator::REJECT);
360 InitiateConnection(3, FakeAuthenticator::ACCEPT, true);
363 // Verify that data can be sent over stream channel.
364 TEST_F(JingleSessionTest, TestStreamChannel) {
365 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
366 ASSERT_NO_FATAL_FAILURE(
367 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
369 ASSERT_NO_FATAL_FAILURE(CreateChannel());
371 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
372 kMessageSize, kMessages);
373 tester.Start();
374 message_loop_->Run();
375 tester.CheckResults();
378 // Verify that data can be sent over a multiplexed channel.
379 TEST_F(JingleSessionTest, TestMuxStreamChannel) {
380 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
381 ASSERT_NO_FATAL_FAILURE(
382 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
384 client_session_->GetMultiplexedChannelFactory()->CreateStreamChannel(
385 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
386 base::Unretained(this)));
387 host_session_->GetMultiplexedChannelFactory()->CreateStreamChannel(
388 kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
389 base::Unretained(this)));
391 int counter = 2;
392 ExpectRouteChange("mux");
393 EXPECT_CALL(client_channel_callback_, OnDone(_))
394 .WillOnce(QuitThreadOnCounter(&counter));
395 EXPECT_CALL(host_channel_callback_, OnDone(_))
396 .WillOnce(QuitThreadOnCounter(&counter));
397 message_loop_->Run();
399 EXPECT_TRUE(client_socket_.get());
400 EXPECT_TRUE(host_socket_.get());
402 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
403 kMessageSize, kMessages);
404 tester.Start();
405 message_loop_->Run();
406 tester.CheckResults();
409 // Verify that we can connect channels with multistep auth.
410 TEST_F(JingleSessionTest, TestMultistepAuthStreamChannel) {
411 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
412 ASSERT_NO_FATAL_FAILURE(
413 InitiateConnection(3, FakeAuthenticator::ACCEPT, false));
415 ASSERT_NO_FATAL_FAILURE(CreateChannel());
417 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
418 kMessageSize, kMessages);
419 tester.Start();
420 message_loop_->Run();
421 tester.CheckResults();
424 // Verify that we shutdown properly when channel authentication fails.
425 TEST_F(JingleSessionTest, TestFailedChannelAuth) {
426 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL);
427 ASSERT_NO_FATAL_FAILURE(
428 InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
430 client_session_->GetTransportChannelFactory()->CreateStreamChannel(
431 kChannelName, base::Bind(&JingleSessionTest::OnClientChannelCreated,
432 base::Unretained(this)));
433 host_session_->GetTransportChannelFactory()->CreateStreamChannel(
434 kChannelName, base::Bind(&JingleSessionTest::OnHostChannelCreated,
435 base::Unretained(this)));
437 // Terminate the message loop when we get rejection notification
438 // from the host.
439 EXPECT_CALL(host_channel_callback_, OnDone(NULL))
440 .WillOnce(QuitThread());
441 EXPECT_CALL(client_channel_callback_, OnDone(_))
442 .Times(AtMost(1));
443 ExpectRouteChange(kChannelName);
445 message_loop_->Run();
447 EXPECT_TRUE(!host_socket_.get());
450 } // namespace protocol
451 } // namespace remoting