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.
6 #include "base/bind_helpers.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "remoting/base/auto_thread_task_runner.h"
9 #include "remoting/host/audio_capturer.h"
10 #include "remoting/host/chromoting_host.h"
11 #include "remoting/host/chromoting_host_context.h"
12 #include "remoting/host/desktop_environment.h"
13 #include "remoting/host/fake_desktop_capturer.h"
14 #include "remoting/host/fake_mouse_cursor_monitor.h"
15 #include "remoting/host/host_mock_objects.h"
16 #include "remoting/proto/video.pb.h"
17 #include "remoting/protocol/errors.h"
18 #include "remoting/protocol/protocol_mock_objects.h"
19 #include "remoting/protocol/session_config.h"
20 #include "remoting/signaling/mock_signal_strategy.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gmock_mutant.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using ::remoting::protocol::MockClientStub
;
26 using ::remoting::protocol::MockConnectionToClient
;
27 using ::remoting::protocol::MockConnectionToClientEventHandler
;
28 using ::remoting::protocol::MockHostStub
;
29 using ::remoting::protocol::MockSession
;
30 using ::remoting::protocol::MockVideoStub
;
31 using ::remoting::protocol::Session
;
32 using ::remoting::protocol::SessionConfig
;
35 using testing::AnyNumber
;
36 using testing::AtLeast
;
37 using testing::AtMost
;
38 using testing::CreateFunctor
;
39 using testing::DeleteArg
;
41 using testing::Expectation
;
42 using testing::InSequence
;
43 using testing::Invoke
;
44 using testing::InvokeArgument
;
45 using testing::InvokeWithoutArgs
;
46 using testing::Return
;
47 using testing::ReturnRef
;
48 using testing::SaveArg
;
49 using testing::Sequence
;
55 void PostQuitTask(base::MessageLoop
* message_loop
) {
56 message_loop
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
59 // Run the task and delete it afterwards. This action is used to deal with
67 class ChromotingHostTest
: public testing::Test
{
69 ChromotingHostTest() {
72 void SetUp() override
{
73 task_runner_
= new AutoThreadTaskRunner(
74 message_loop_
.task_runner(),
75 base::Bind(&ChromotingHostTest::QuitMainMessageLoop
,
76 base::Unretained(this)));
78 desktop_environment_factory_
.reset(new MockDesktopEnvironmentFactory());
79 EXPECT_CALL(*desktop_environment_factory_
, CreatePtr())
81 .WillRepeatedly(Invoke(this,
82 &ChromotingHostTest::CreateDesktopEnvironment
));
83 EXPECT_CALL(*desktop_environment_factory_
, SupportsAudioCapture())
85 .WillRepeatedly(Return(false));
87 session_manager_
= new protocol::MockSessionManager();
89 host_
.reset(new ChromotingHost(
91 desktop_environment_factory_
.get(),
92 make_scoped_ptr(session_manager_
),
93 task_runner_
, // Audio
94 task_runner_
, // Input
95 task_runner_
, // Video capture
96 task_runner_
, // Video encode
97 task_runner_
, // Network
99 host_
->AddStatusObserver(&host_status_observer_
);
101 xmpp_login_
= "host@domain";
102 session1_
= new MockSession();
103 session2_
= new MockSession();
104 session_unowned1_
.reset(new MockSession());
105 session_unowned2_
.reset(new MockSession());
106 session_config1_
= SessionConfig::ForTest();
107 session_jid1_
= "user@domain/rest-of-jid";
108 session_config2_
= SessionConfig::ForTest();
109 session_jid2_
= "user2@domain/rest-of-jid";
110 session_unowned_jid1_
= "user3@doman/rest-of-jid";
111 session_unowned_jid2_
= "user4@doman/rest-of-jid";
113 EXPECT_CALL(*session1_
, jid())
114 .WillRepeatedly(ReturnRef(session_jid1_
));
115 EXPECT_CALL(*session2_
, jid())
116 .WillRepeatedly(ReturnRef(session_jid2_
));
117 EXPECT_CALL(*session_unowned1_
, jid())
118 .WillRepeatedly(ReturnRef(session_unowned_jid1_
));
119 EXPECT_CALL(*session_unowned2_
, jid())
120 .WillRepeatedly(ReturnRef(session_unowned_jid2_
));
121 EXPECT_CALL(*session1_
, SetEventHandler(_
))
123 EXPECT_CALL(*session2_
, SetEventHandler(_
))
125 EXPECT_CALL(*session_unowned1_
, SetEventHandler(_
))
127 .WillRepeatedly(SaveArg
<0>(&session_unowned1_event_handler_
));
128 EXPECT_CALL(*session_unowned2_
, SetEventHandler(_
))
130 .WillRepeatedly(SaveArg
<0>(&session_unowned2_event_handler_
));
131 EXPECT_CALL(*session1_
, config())
132 .WillRepeatedly(ReturnRef(*session_config1_
));
133 EXPECT_CALL(*session2_
, config())
134 .WillRepeatedly(ReturnRef(*session_config2_
));
136 owned_connection1_
.reset(new MockConnectionToClient(session1_
,
138 connection1_
= owned_connection1_
.get();
139 owned_connection2_
.reset(new MockConnectionToClient(session2_
,
141 connection2_
= owned_connection2_
.get();
143 ON_CALL(video_stub1_
, ProcessVideoPacketPtr(_
, _
))
144 .WillByDefault(DeleteArg
<0>());
145 ON_CALL(video_stub2_
, ProcessVideoPacketPtr(_
, _
))
146 .WillByDefault(DeleteArg
<0>());
147 ON_CALL(*connection1_
, video_stub())
148 .WillByDefault(Return(&video_stub1_
));
149 ON_CALL(*connection1_
, client_stub())
150 .WillByDefault(Return(&client_stub1_
));
151 ON_CALL(*connection1_
, session())
152 .WillByDefault(Return(session1_
));
153 ON_CALL(*connection2_
, video_stub())
154 .WillByDefault(Return(&video_stub2_
));
155 ON_CALL(*connection2_
, client_stub())
156 .WillByDefault(Return(&client_stub2_
));
157 ON_CALL(*connection2_
, session())
158 .WillByDefault(Return(session2_
));
159 EXPECT_CALL(*connection1_
, video_stub())
161 EXPECT_CALL(*connection1_
, client_stub())
163 EXPECT_CALL(*connection1_
, session())
165 EXPECT_CALL(*connection2_
, video_stub())
167 EXPECT_CALL(*connection2_
, client_stub())
169 EXPECT_CALL(*connection2_
, session())
172 empty_candidate_config_
=
173 protocol::CandidateSessionConfig::CreateEmpty();
174 default_candidate_config_
=
175 protocol::CandidateSessionConfig::CreateDefault();
178 // Helper method to pretend a client is connected to ChromotingHost.
179 void SimulateClientConnection(int connection_index
, bool authenticate
,
181 scoped_ptr
<protocol::ConnectionToClient
> connection
=
182 ((connection_index
== 0) ? owned_connection1_
: owned_connection2_
)
184 protocol::ConnectionToClient
* connection_ptr
= connection
.get();
185 scoped_ptr
<ClientSession
> client(new ClientSession(
187 task_runner_
, // Audio
188 task_runner_
, // Input
189 task_runner_
, // Video capture
190 task_runner_
, // Video encode
191 task_runner_
, // Network
194 desktop_environment_factory_
.get(),
197 std::vector
<HostExtension
*>()));
199 connection_ptr
->set_host_stub(client
.get());
202 task_runner_
->PostTask(
204 base::Bind(&ClientSession::OnConnectionAuthenticated
,
205 base::Unretained(client
.get()), connection_ptr
));
207 task_runner_
->PostTask(
209 base::Bind(&ClientSession::OnConnectionChannelsConnected
,
210 base::Unretained(client
.get()), connection_ptr
));
213 task_runner_
->PostTask(
214 FROM_HERE
, base::Bind(&ClientSession::OnConnectionClosed
,
215 base::Unretained(client
.get()), connection_ptr
,
216 protocol::AUTHENTICATION_FAILED
));
219 get_client(connection_index
) = client
.get();
221 // |host| is responsible for deleting |client| from now on.
222 host_
->clients_
.push_back(client
.release());
225 void TearDown() override
{
226 // Make sure that the host has been properly deleted.
227 DCHECK(host_
.get() == nullptr);
230 // Change the session route for |client1_|.
231 void ChangeSessionRoute(const std::string
& channel_name
,
232 const protocol::TransportRoute
& route
) {
233 host_
->OnSessionRouteChange(get_client(0), channel_name
, route
);
236 // Creates a DesktopEnvironment with a fake webrtc::DesktopCapturer, to mock
237 // DesktopEnvironmentFactory::Create().
238 DesktopEnvironment
* CreateDesktopEnvironment() {
239 MockDesktopEnvironment
* desktop_environment
= new MockDesktopEnvironment();
240 EXPECT_CALL(*desktop_environment
, CreateAudioCapturerPtr())
242 EXPECT_CALL(*desktop_environment
, CreateInputInjectorPtr())
244 .WillOnce(Invoke(this, &ChromotingHostTest::CreateInputInjector
));
245 EXPECT_CALL(*desktop_environment
, CreateScreenControlsPtr())
247 EXPECT_CALL(*desktop_environment
, CreateVideoCapturerPtr())
249 .WillOnce(Invoke(this, &ChromotingHostTest::CreateVideoCapturer
));
250 EXPECT_CALL(*desktop_environment
, CreateMouseCursorMonitorPtr())
252 .WillOnce(Invoke(this, &ChromotingHostTest::CreateMouseCursorMonitor
));
253 EXPECT_CALL(*desktop_environment
, GetCapabilities())
255 EXPECT_CALL(*desktop_environment
, SetCapabilities(_
))
258 return desktop_environment
;
261 // Creates a dummy InputInjector, to mock
262 // DesktopEnvironment::CreateInputInjector().
263 InputInjector
* CreateInputInjector() {
264 MockInputInjector
* input_injector
= new MockInputInjector();
265 EXPECT_CALL(*input_injector
, StartPtr(_
));
266 return input_injector
;
269 // Creates a fake webrtc::DesktopCapturer, to mock
270 // DesktopEnvironment::CreateVideoCapturer().
271 webrtc::DesktopCapturer
* CreateVideoCapturer() {
272 return new FakeDesktopCapturer();
275 // Creates a MockMouseCursorMonitor, to mock
276 // DesktopEnvironment::CreateMouseCursorMonitor().
277 webrtc::MouseCursorMonitor
* CreateMouseCursorMonitor() {
278 return new FakeMouseCursorMonitor();
281 void DisconnectAllClients() {
282 host_
->DisconnectAllClients();
285 // Helper method to disconnect client 1 from the host.
286 void DisconnectClient1() {
287 NotifyClientSessionClosed(0);
290 // Notify |host_| that the authenticating client has been rejected.
291 void RejectAuthenticatingClient() {
292 host_
->RejectAuthenticatingClient();
295 // Notify |host_| that a client session has closed.
296 void NotifyClientSessionClosed(int connection_index
) {
297 get_client(connection_index
)->OnConnectionClosed(
298 get_connection(connection_index
), protocol::OK
);
301 void NotifyConnectionClosed1() {
302 if (session_unowned1_event_handler_
) {
303 session_unowned1_event_handler_
->OnSessionStateChange(Session::CLOSED
);
307 void NotifyConnectionClosed2() {
308 if (session_unowned2_event_handler_
) {
309 session_unowned2_event_handler_
->OnSessionStateChange(Session::CLOSED
);
313 void ShutdownHost() {
314 task_runner_
->PostTask(
316 base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner
,
317 base::Unretained(this)));
320 void StopAndReleaseTaskRunner() {
322 task_runner_
= nullptr;
323 desktop_environment_factory_
.reset();
326 void QuitMainMessageLoop() {
327 PostQuitTask(&message_loop_
);
330 // Expect the host and session manager to start, and return the expectation
331 // that the session manager has started.
332 Expectation
ExpectHostAndSessionManagerStart() {
333 EXPECT_CALL(host_status_observer_
, OnStart(xmpp_login_
));
334 return EXPECT_CALL(*session_manager_
, Init(_
, host_
.get()));
337 // Expect a client to connect.
338 // Return an expectation that a session has started, and that the first
339 // video packet has been sent to the client.
340 // Do |action| when that happens.
342 Expectation
ExpectClientConnected(int connection_index
, A action
) {
343 const std::string
& session_jid
= get_session_jid(connection_index
);
344 MockVideoStub
& video_stub
= get_video_stub(connection_index
);
346 Expectation client_authenticated
=
347 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid
));
348 EXPECT_CALL(host_status_observer_
, OnClientConnected(session_jid
))
349 .After(client_authenticated
);
350 Expectation video_packet_sent
=
351 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
352 .After(client_authenticated
)
356 .RetiresOnSaturation();
357 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
359 .After(video_packet_sent
)
360 .WillRepeatedly(RunDoneTask());
361 return video_packet_sent
;
364 // Return an expectation that a client will disconnect after a given
365 // expectation. The given action will be done after the event executor is
366 // notified that the session has finished.
368 Expectation
ExpectClientDisconnected(int connection_index
,
369 bool expect_host_status_change
,
372 MockConnectionToClient
* connection
= get_connection(connection_index
);
374 Expectation client_disconnected
=
375 EXPECT_CALL(*connection
, Disconnect())
377 .WillOnce(InvokeWithoutArgs(CreateFunctor(
378 this, &ChromotingHostTest::NotifyClientSessionClosed
,
380 .RetiresOnSaturation();
381 ExpectClientDisconnectEffects(connection_index
,
382 expect_host_status_change
,
385 return client_disconnected
;
388 // Expect the side-effects of a client disconnection, after a given
389 // expectation. The given action will be done after the event executor is
390 // notifed that the session has finished.
392 void ExpectClientDisconnectEffects(int connection_index
,
393 bool expect_host_status_change
,
396 const std::string
& session_jid
= get_session_jid(connection_index
);
398 if (expect_host_status_change
) {
399 EXPECT_CALL(host_status_observer_
, OnClientDisconnected(session_jid
))
402 .RetiresOnSaturation();
407 base::MessageLoop message_loop_
;
408 scoped_refptr
<AutoThreadTaskRunner
> task_runner_
;
409 MockConnectionToClientEventHandler handler_
;
410 MockSignalStrategy signal_strategy_
;
411 scoped_ptr
<MockDesktopEnvironmentFactory
> desktop_environment_factory_
;
412 scoped_ptr
<ChromotingHost
> host_
;
413 MockHostStatusObserver host_status_observer_
;
414 protocol::MockSessionManager
* session_manager_
;
415 std::string xmpp_login_
;
416 MockConnectionToClient
* connection1_
;
417 scoped_ptr
<MockConnectionToClient
> owned_connection1_
;
418 ClientSession
* client1_
;
419 std::string session_jid1_
;
420 MockSession
* session1_
; // Owned by |connection_|.
421 scoped_ptr
<SessionConfig
> session_config1_
;
422 MockVideoStub video_stub1_
;
423 MockClientStub client_stub1_
;
424 MockHostStub host_stub1_
;
425 MockConnectionToClient
* connection2_
;
426 scoped_ptr
<MockConnectionToClient
> owned_connection2_
;
427 ClientSession
* client2_
;
428 std::string session_jid2_
;
429 MockSession
* session2_
; // Owned by |connection2_|.
430 scoped_ptr
<SessionConfig
> session_config2_
;
431 MockVideoStub video_stub2_
;
432 MockClientStub client_stub2_
;
433 MockHostStub host_stub2_
;
434 scoped_ptr
<MockSession
> session_unowned1_
; // Not owned by a connection.
435 std::string session_unowned_jid1_
;
436 scoped_ptr
<MockSession
> session_unowned2_
; // Not owned by a connection.
437 std::string session_unowned_jid2_
;
438 protocol::Session::EventHandler
* session_unowned1_event_handler_
;
439 protocol::Session::EventHandler
* session_unowned2_event_handler_
;
440 scoped_ptr
<protocol::CandidateSessionConfig
> empty_candidate_config_
;
441 scoped_ptr
<protocol::CandidateSessionConfig
> default_candidate_config_
;
443 MockConnectionToClient
*& get_connection(int connection_index
) {
444 return (connection_index
== 0) ? connection1_
: connection2_
;
447 // Returns the cached client pointers client1_ or client2_.
448 ClientSession
*& get_client(int connection_index
) {
449 return (connection_index
== 0) ? client1_
: client2_
;
452 // Returns the list of clients of the host_.
453 std::list
<ClientSession
*>& get_clients_from_host() {
454 return host_
->clients_
;
457 const std::string
& get_session_jid(int connection_index
) {
458 return (connection_index
== 0) ? session_jid1_
: session_jid2_
;
461 MockVideoStub
& get_video_stub(int connection_index
) {
462 return (connection_index
== 0) ? video_stub1_
: video_stub2_
;
466 TEST_F(ChromotingHostTest
, StartAndShutdown
) {
467 Expectation start
= ExpectHostAndSessionManagerStart();
468 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(start
);
470 host_
->Start(xmpp_login_
);
475 TEST_F(ChromotingHostTest
, Connect
) {
476 ExpectHostAndSessionManagerStart();
478 // Shut down the host when the first video packet is received.
479 Expectation video_packet_sent
= ExpectClientConnected(
480 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
481 Expectation client_disconnected
= ExpectClientDisconnected(
482 0, true, video_packet_sent
, InvokeWithoutArgs(base::DoNothing
));
483 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected
);
485 host_
->Start(xmpp_login_
);
486 SimulateClientConnection(0, true, false);
490 TEST_F(ChromotingHostTest
, RejectAuthenticatingClient
) {
491 Expectation start
= ExpectHostAndSessionManagerStart();
492 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid1_
))
493 .WillOnce(InvokeWithoutArgs(
494 this, &ChromotingHostTest::RejectAuthenticatingClient
));
495 ExpectClientDisconnected(
497 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
498 EXPECT_CALL(host_status_observer_
, OnShutdown());
500 host_
->Start(xmpp_login_
);
501 SimulateClientConnection(0, true, true);
505 TEST_F(ChromotingHostTest
, AuthenticationFailed
) {
506 ExpectHostAndSessionManagerStart();
507 EXPECT_CALL(host_status_observer_
, OnAccessDenied(session_jid1_
))
508 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
509 EXPECT_CALL(host_status_observer_
, OnShutdown());
511 host_
->Start(xmpp_login_
);
512 SimulateClientConnection(0, false, false);
516 TEST_F(ChromotingHostTest
, Reconnect
) {
517 ExpectHostAndSessionManagerStart();
519 // When a video packet is received on the first connection, disconnect it,
520 // then quit the message loop.
521 Expectation video_packet_sent1
= ExpectClientConnected(0, DoAll(
522 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1
),
523 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop
)));
524 ExpectClientDisconnectEffects(
525 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
527 // When a video packet is received on the second connection, shut down the
529 Expectation video_packet_sent2
= ExpectClientConnected(
530 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
531 Expectation client_disconnected2
= ExpectClientDisconnected(
532 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
533 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
535 host_
->Start(xmpp_login_
);
536 SimulateClientConnection(0, true, false);
538 SimulateClientConnection(1, true, false);
542 TEST_F(ChromotingHostTest
, ConnectWhenAnotherClientIsConnected
) {
543 ExpectHostAndSessionManagerStart();
545 // When a video packet is received, connect the second connection.
546 // This should disconnect the first connection.
547 Expectation video_packet_sent1
= ExpectClientConnected(
552 &ChromotingHostTest::SimulateClientConnection
, 1, true, false)));
553 ExpectClientDisconnected(
554 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
555 Expectation video_packet_sent2
= ExpectClientConnected(
556 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
557 Expectation client_disconnected2
= ExpectClientDisconnected(
558 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
559 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
561 host_
->Start(xmpp_login_
);
562 SimulateClientConnection(0, true, false);
566 TEST_F(ChromotingHostTest
, IncomingSessionDeclined
) {
567 protocol::SessionManager::IncomingSessionResponse response
=
568 protocol::SessionManager::ACCEPT
;
569 host_
->OnIncomingSession(session1_
, &response
);
570 EXPECT_EQ(protocol::SessionManager::DECLINE
, response
);
576 TEST_F(ChromotingHostTest
, IncomingSessionIncompatible
) {
577 ExpectHostAndSessionManagerStart();
578 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
579 empty_candidate_config_
.get()));
580 EXPECT_CALL(host_status_observer_
, OnShutdown());
582 host_
->Start(xmpp_login_
);
584 protocol::SessionManager::IncomingSessionResponse response
=
585 protocol::SessionManager::ACCEPT
;
586 host_
->OnIncomingSession(session_unowned1_
.get(), &response
);
587 EXPECT_EQ(protocol::SessionManager::INCOMPATIBLE
, response
);
593 TEST_F(ChromotingHostTest
, IncomingSessionAccepted
) {
594 ExpectHostAndSessionManagerStart();
595 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
596 default_candidate_config_
.get()));
597 EXPECT_CALL(*session_unowned1_
, set_config_ptr(_
));
598 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(InvokeWithoutArgs(
599 this, &ChromotingHostTest::NotifyConnectionClosed1
));
600 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
601 EXPECT_CALL(host_status_observer_
, OnShutdown());
603 host_
->Start(xmpp_login_
);
605 protocol::SessionManager::IncomingSessionResponse response
=
606 protocol::SessionManager::DECLINE
;
607 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
608 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
614 TEST_F(ChromotingHostTest
, LoginBackOffUponConnection
) {
615 ExpectHostAndSessionManagerStart();
616 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
617 Return(default_candidate_config_
.get()));
618 EXPECT_CALL(*session_unowned1_
, set_config_ptr(_
));
619 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
620 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
621 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
622 EXPECT_CALL(host_status_observer_
, OnShutdown());
624 host_
->Start(xmpp_login_
);
626 protocol::SessionManager::IncomingSessionResponse response
=
627 protocol::SessionManager::DECLINE
;
629 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
630 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
632 host_
->OnSessionAuthenticating(get_clients_from_host().front());
633 host_
->OnIncomingSession(session_unowned2_
.get(), &response
);
634 EXPECT_EQ(protocol::SessionManager::OVERLOAD
, response
);
640 TEST_F(ChromotingHostTest
, LoginBackOffUponAuthenticating
) {
641 Expectation start
= ExpectHostAndSessionManagerStart();
642 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
643 Return(default_candidate_config_
.get()));
644 EXPECT_CALL(*session_unowned1_
, set_config_ptr(_
));
645 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
646 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
648 EXPECT_CALL(*session_unowned2_
, candidate_config()).WillOnce(
649 Return(default_candidate_config_
.get()));
650 EXPECT_CALL(*session_unowned2_
, set_config_ptr(_
));
651 EXPECT_CALL(*session_unowned2_
, Close()).WillOnce(
652 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed2
));
654 EXPECT_CALL(host_status_observer_
, OnShutdown());
656 host_
->Start(xmpp_login_
);
658 protocol::SessionManager::IncomingSessionResponse response
=
659 protocol::SessionManager::DECLINE
;
661 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
662 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
664 host_
->OnIncomingSession(session_unowned2_
.release(), &response
);
665 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
667 // This will set the backoff.
668 host_
->OnSessionAuthenticating(get_clients_from_host().front());
670 // This should disconnect client2.
671 host_
->OnSessionAuthenticating(get_clients_from_host().back());
673 // Verify that the host only has 1 client at this point.
674 EXPECT_EQ(get_clients_from_host().size(), 1U);
680 TEST_F(ChromotingHostTest
, OnSessionRouteChange
) {
681 std::string
channel_name("ChannelName");
682 protocol::TransportRoute route
;
684 ExpectHostAndSessionManagerStart();
685 Expectation video_packet_sent
= ExpectClientConnected(
686 0, InvokeWithoutArgs(CreateFunctor(
687 this, &ChromotingHostTest::ChangeSessionRoute
, channel_name
, route
)));
688 Expectation route_change
=
689 EXPECT_CALL(host_status_observer_
, OnClientRouteChange(
690 session_jid1_
, channel_name
, _
))
691 .After(video_packet_sent
)
692 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
693 ExpectClientDisconnected(0, true, route_change
,
694 InvokeWithoutArgs(base::DoNothing
));
695 EXPECT_CALL(host_status_observer_
, OnShutdown());
697 host_
->Start(xmpp_login_
);
698 SimulateClientConnection(0, true, false);
702 TEST_F(ChromotingHostTest
, DisconnectAllClients
) {
703 ExpectHostAndSessionManagerStart();
704 Expectation video_packet_sent
= ExpectClientConnected(
705 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients
));
706 ExpectClientDisconnected(0, true, video_packet_sent
,
707 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
708 EXPECT_CALL(host_status_observer_
, OnShutdown());
710 host_
->Start(xmpp_login_
);
711 SimulateClientConnection(0, true, false);
715 } // namespace remoting