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"
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"
25 using testing::AtLeast;
26 using testing::AtMost;
27 using testing::DeleteArg;
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;
42 const char kHostJid[] = "host1@gmail.com/123";
43 const char kClientJid[] = "host2@gmail.com/321";
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";
51 void QuitCurrentThread() {
52 base::MessageLoop::current()->PostTask(FROM_HERE,
53 base::MessageLoop::QuitClosure());
60 ACTION_P(QuitThreadOnCounter, counter) {
62 EXPECT_GE(*counter, 0);
67 class MockSessionManagerListener : public SessionManager::Listener {
69 MOCK_METHOD0(OnSessionManagerReady, void());
70 MOCK_METHOD2(OnIncomingSession,
72 SessionManager::IncomingSessionResponse*));
75 class MockSessionEventHandler : public Session::EventHandler {
77 MOCK_METHOD1(OnSessionStateChange, void(Session::State));
78 MOCK_METHOD2(OnSessionRouteChange, void(const std::string& channel_name,
79 const TransportRoute& route));
82 class MockStreamChannelCallback {
84 MOCK_METHOD1(OnDone, void(net::StreamSocket* socket));
89 class JingleSessionTest : public testing::Test {
92 message_loop_.reset(new base::MessageLoopForIO());
95 // Helper method that handles OnIncomingSession().
96 void SetHostSession(Session* session) {
98 host_session_.reset(session);
99 host_session_->SetEventHandler(&host_session_event_handler_);
101 session->set_config(SessionConfig::ForTest());
104 void OnClientChannelCreated(scoped_ptr<net::StreamSocket> socket) {
105 client_channel_callback_.OnDone(socket.get());
106 client_socket_ = socket.Pass();
109 void OnHostChannelCreated(scoped_ptr<net::StreamSocket> socket) {
110 host_channel_callback_.OnDone(socket.get());
111 host_socket_ = socket.Pass();
115 virtual void SetUp() {
118 virtual void TearDown() {
120 CloseSessionManager();
121 message_loop_->RunUntilIdle();
124 void CloseSessions() {
125 host_socket_.reset();
126 host_session_.reset();
127 client_socket_.reset();
128 client_session_.reset();
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());
138 EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
140 host_server_.reset(new JingleSessionManager(
141 scoped_ptr<TransportFactory>(new LibjingleTransportFactory()),
143 host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
145 scoped_ptr<AuthenticatorFactory> factory(
146 new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true));
147 host_server_->set_authenticator_factory(factory.Pass());
149 EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
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_);
157 void CloseSessionManager() {
158 if (host_server_.get()) {
159 host_server_->Close();
160 host_server_.reset();
162 if (client_server_.get()) {
163 client_server_->Close();
164 client_server_.reset();
166 host_signal_strategy_.reset();
167 client_signal_strategy_.reset();
170 void InitiateConnection(int auth_round_trips,
171 FakeAuthenticator::Action auth_action,
173 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
175 WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)),
176 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
181 EXPECT_CALL(host_session_event_handler_,
182 OnSessionStateChange(Session::CONNECTED))
185 EXPECT_CALL(host_session_event_handler_,
186 OnSessionStateChange(Session::FAILED))
189 EXPECT_CALL(host_session_event_handler_,
190 OnSessionStateChange(Session::AUTHENTICATED))
192 // Expect that the connection will be closed eventually.
193 EXPECT_CALL(host_session_event_handler_,
194 OnSessionStateChange(Session::CLOSED))
202 EXPECT_CALL(client_session_event_handler_,
203 OnSessionStateChange(Session::CONNECTED))
206 EXPECT_CALL(client_session_event_handler_,
207 OnSessionStateChange(Session::FAILED))
210 EXPECT_CALL(client_session_event_handler_,
211 OnSessionStateChange(Session::AUTHENTICATED))
213 // Expect that the connection will be closed eventually.
214 EXPECT_CALL(client_session_event_handler_,
215 OnSessionStateChange(Session::CLOSED))
220 scoped_ptr<Authenticator> authenticator(new FakeAuthenticator(
221 FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true));
223 client_session_ = client_server_->Connect(
224 kHostJid, authenticator.Pass(),
225 CandidateSessionConfig::CreateDefault());
226 client_session_->SetEventHandler(&client_session_event_handler_);
228 message_loop_->RunUntilIdle();
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)));
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();
247 EXPECT_TRUE(client_socket_.get());
248 EXPECT_TRUE(host_socket_.get());
251 void ExpectRouteChange(const std::string& channel_name) {
252 EXPECT_CALL(host_session_event_handler_,
253 OnSessionRouteChange(channel_name, _))
255 EXPECT_CALL(client_session_event_handler_,
256 OnSessionRouteChange(channel_name, _))
260 scoped_ptr<base::MessageLoopForIO> message_loop_;
262 scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
263 scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
265 scoped_ptr<JingleSessionManager> host_server_;
266 MockSessionManagerListener host_server_listener_;
267 scoped_ptr<JingleSessionManager> client_server_;
268 MockSessionManagerListener client_server_listener_;
270 scoped_ptr<Session> host_session_;
271 MockSessionEventHandler host_session_event_handler_;
272 scoped_ptr<Session> client_session_;
273 MockSessionEventHandler client_session_event_handler_;
275 MockStreamChannelCallback client_channel_callback_;
276 MockStreamChannelCallback host_channel_callback_;
278 scoped_ptr<net::StreamSocket> client_socket_;
279 scoped_ptr<net::StreamSocket> host_socket_;
283 // Verify that we can create and destroy session managers without a
285 TEST_F(JingleSessionTest, CreateAndDestoy) {
286 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
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);
294 // Reject incoming session.
295 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
296 .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
300 EXPECT_CALL(client_session_event_handler_,
301 OnSessionStateChange(Session::FAILED))
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_);
311 message_loop_->RunUntilIdle();
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);
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")));
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);
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);
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);
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));
354 ASSERT_NO_FATAL_FAILURE(CreateChannel());
356 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
357 kMessageSize, kMessages);
359 message_loop_->Run();
360 tester.CheckResults();
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));
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)));
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();
384 EXPECT_TRUE(client_socket_.get());
385 EXPECT_TRUE(host_socket_.get());
387 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
388 kMessageSize, kMessages);
390 message_loop_->Run();
391 tester.CheckResults();
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));
400 ASSERT_NO_FATAL_FAILURE(CreateChannel());
402 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
403 kMessageSize, kMessages);
405 message_loop_->Run();
406 tester.CheckResults();
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));
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)));
422 // Terminate the message loop when we get rejection notification
424 EXPECT_CALL(host_channel_callback_, OnDone(NULL))
425 .WillOnce(QuitThread());
426 EXPECT_CALL(client_channel_callback_, OnDone(_))
428 ExpectRouteChange(kChannelName);
430 message_loop_->Run();
432 EXPECT_TRUE(!host_socket_.get());
435 } // namespace protocol
436 } // namespace remoting