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 "base/message_loop/message_loop_proxy.h"
9 #include "remoting/base/auto_thread_task_runner.h"
10 #include "remoting/host/audio_capturer.h"
11 #include "remoting/host/chromoting_host.h"
12 #include "remoting/host/chromoting_host_context.h"
13 #include "remoting/host/desktop_environment.h"
14 #include "remoting/host/fake_desktop_capturer.h"
15 #include "remoting/host/fake_mouse_cursor_monitor.h"
16 #include "remoting/host/host_mock_objects.h"
17 #include "remoting/proto/video.pb.h"
18 #include "remoting/protocol/errors.h"
19 #include "remoting/protocol/protocol_mock_objects.h"
20 #include "remoting/protocol/session_config.h"
21 #include "remoting/signaling/mock_signal_strategy.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gmock_mutant.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using ::remoting::protocol::MockClientStub
;
27 using ::remoting::protocol::MockConnectionToClient
;
28 using ::remoting::protocol::MockConnectionToClientEventHandler
;
29 using ::remoting::protocol::MockHostStub
;
30 using ::remoting::protocol::MockSession
;
31 using ::remoting::protocol::MockVideoStub
;
32 using ::remoting::protocol::Session
;
33 using ::remoting::protocol::SessionConfig
;
36 using testing::AnyNumber
;
37 using testing::AtLeast
;
38 using testing::AtMost
;
39 using testing::CreateFunctor
;
40 using testing::DeleteArg
;
42 using testing::Expectation
;
43 using testing::InSequence
;
44 using testing::Invoke
;
45 using testing::InvokeArgument
;
46 using testing::InvokeWithoutArgs
;
47 using testing::Return
;
48 using testing::ReturnRef
;
49 using testing::SaveArg
;
50 using testing::Sequence
;
56 void PostQuitTask(base::MessageLoop
* message_loop
) {
57 message_loop
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
60 // Run the task and delete it afterwards. This action is used to deal with
68 class ChromotingHostTest
: public testing::Test
{
70 ChromotingHostTest() {
73 void SetUp() override
{
74 task_runner_
= new AutoThreadTaskRunner(
75 message_loop_
.message_loop_proxy(),
76 base::Bind(&ChromotingHostTest::QuitMainMessageLoop
,
77 base::Unretained(this)));
79 desktop_environment_factory_
.reset(new MockDesktopEnvironmentFactory());
80 EXPECT_CALL(*desktop_environment_factory_
, CreatePtr())
82 .WillRepeatedly(Invoke(this,
83 &ChromotingHostTest::CreateDesktopEnvironment
));
84 EXPECT_CALL(*desktop_environment_factory_
, SupportsAudioCapture())
86 .WillRepeatedly(Return(false));
88 session_manager_
= new protocol::MockSessionManager();
90 host_
.reset(new ChromotingHost(
92 desktop_environment_factory_
.get(),
93 make_scoped_ptr(session_manager_
),
94 task_runner_
, // Audio
95 task_runner_
, // Input
96 task_runner_
, // Video capture
97 task_runner_
, // Video encode
98 task_runner_
, // Network
100 host_
->AddStatusObserver(&host_status_observer_
);
102 xmpp_login_
= "host@domain";
103 session1_
= new MockSession();
104 session2_
= new MockSession();
105 session_unowned1_
.reset(new MockSession());
106 session_unowned2_
.reset(new MockSession());
107 session_config1_
= SessionConfig::ForTest();
108 session_jid1_
= "user@domain/rest-of-jid";
109 session_config2_
= SessionConfig::ForTest();
110 session_jid2_
= "user2@domain/rest-of-jid";
111 session_unowned_jid1_
= "user3@doman/rest-of-jid";
112 session_unowned_jid2_
= "user4@doman/rest-of-jid";
114 EXPECT_CALL(*session1_
, jid())
115 .WillRepeatedly(ReturnRef(session_jid1_
));
116 EXPECT_CALL(*session2_
, jid())
117 .WillRepeatedly(ReturnRef(session_jid2_
));
118 EXPECT_CALL(*session_unowned1_
, jid())
119 .WillRepeatedly(ReturnRef(session_unowned_jid1_
));
120 EXPECT_CALL(*session_unowned2_
, jid())
121 .WillRepeatedly(ReturnRef(session_unowned_jid2_
));
122 EXPECT_CALL(*session1_
, SetEventHandler(_
))
124 EXPECT_CALL(*session2_
, SetEventHandler(_
))
126 EXPECT_CALL(*session_unowned1_
, SetEventHandler(_
))
128 .WillRepeatedly(SaveArg
<0>(&session_unowned1_event_handler_
));
129 EXPECT_CALL(*session_unowned2_
, SetEventHandler(_
))
131 .WillRepeatedly(SaveArg
<0>(&session_unowned2_event_handler_
));
132 EXPECT_CALL(*session1_
, config())
133 .WillRepeatedly(ReturnRef(*session_config1_
));
134 EXPECT_CALL(*session2_
, config())
135 .WillRepeatedly(ReturnRef(*session_config2_
));
137 owned_connection1_
.reset(new MockConnectionToClient(session1_
,
139 connection1_
= owned_connection1_
.get();
140 owned_connection2_
.reset(new MockConnectionToClient(session2_
,
142 connection2_
= owned_connection2_
.get();
144 ON_CALL(video_stub1_
, ProcessVideoPacketPtr(_
, _
))
145 .WillByDefault(DeleteArg
<0>());
146 ON_CALL(video_stub2_
, ProcessVideoPacketPtr(_
, _
))
147 .WillByDefault(DeleteArg
<0>());
148 ON_CALL(*connection1_
, video_stub())
149 .WillByDefault(Return(&video_stub1_
));
150 ON_CALL(*connection1_
, client_stub())
151 .WillByDefault(Return(&client_stub1_
));
152 ON_CALL(*connection1_
, session())
153 .WillByDefault(Return(session1_
));
154 ON_CALL(*connection2_
, video_stub())
155 .WillByDefault(Return(&video_stub2_
));
156 ON_CALL(*connection2_
, client_stub())
157 .WillByDefault(Return(&client_stub2_
));
158 ON_CALL(*connection2_
, session())
159 .WillByDefault(Return(session2_
));
160 EXPECT_CALL(*connection1_
, video_stub())
162 EXPECT_CALL(*connection1_
, client_stub())
164 EXPECT_CALL(*connection1_
, session())
166 EXPECT_CALL(*connection2_
, video_stub())
168 EXPECT_CALL(*connection2_
, client_stub())
170 EXPECT_CALL(*connection2_
, session())
173 empty_candidate_config_
=
174 protocol::CandidateSessionConfig::CreateEmpty();
175 default_candidate_config_
=
176 protocol::CandidateSessionConfig::CreateDefault();
179 // Helper method to pretend a client is connected to ChromotingHost.
180 void SimulateClientConnection(int connection_index
, bool authenticate
,
182 scoped_ptr
<protocol::ConnectionToClient
> connection
=
183 ((connection_index
== 0) ? owned_connection1_
: owned_connection2_
)
185 protocol::ConnectionToClient
* connection_ptr
= connection
.get();
186 scoped_ptr
<ClientSession
> client(new ClientSession(
188 task_runner_
, // Audio
189 task_runner_
, // Input
190 task_runner_
, // Video capture
191 task_runner_
, // Video encode
192 task_runner_
, // Network
195 desktop_environment_factory_
.get(),
198 std::vector
<HostExtension
*>()));
200 connection_ptr
->set_host_stub(client
.get());
203 task_runner_
->PostTask(
205 base::Bind(&ClientSession::OnConnectionAuthenticated
,
206 base::Unretained(client
.get()), connection_ptr
));
208 task_runner_
->PostTask(
210 base::Bind(&ClientSession::OnConnectionChannelsConnected
,
211 base::Unretained(client
.get()), connection_ptr
));
214 task_runner_
->PostTask(
215 FROM_HERE
, base::Bind(&ClientSession::OnConnectionClosed
,
216 base::Unretained(client
.get()), connection_ptr
,
217 protocol::AUTHENTICATION_FAILED
));
220 get_client(connection_index
) = client
.get();
222 // |host| is responsible for deleting |client| from now on.
223 host_
->clients_
.push_back(client
.release());
226 void TearDown() override
{
227 // Make sure that the host has been properly deleted.
228 DCHECK(host_
.get() == nullptr);
231 // Change the session route for |client1_|.
232 void ChangeSessionRoute(const std::string
& channel_name
,
233 const protocol::TransportRoute
& route
) {
234 host_
->OnSessionRouteChange(get_client(0), channel_name
, route
);
237 // Creates a DesktopEnvironment with a fake webrtc::DesktopCapturer, to mock
238 // DesktopEnvironmentFactory::Create().
239 DesktopEnvironment
* CreateDesktopEnvironment() {
240 MockDesktopEnvironment
* desktop_environment
= new MockDesktopEnvironment();
241 EXPECT_CALL(*desktop_environment
, CreateAudioCapturerPtr())
243 EXPECT_CALL(*desktop_environment
, CreateInputInjectorPtr())
245 .WillOnce(Invoke(this, &ChromotingHostTest::CreateInputInjector
));
246 EXPECT_CALL(*desktop_environment
, CreateScreenControlsPtr())
248 EXPECT_CALL(*desktop_environment
, CreateVideoCapturerPtr())
250 .WillOnce(Invoke(this, &ChromotingHostTest::CreateVideoCapturer
));
251 EXPECT_CALL(*desktop_environment
, CreateMouseCursorMonitorPtr())
253 .WillOnce(Invoke(this, &ChromotingHostTest::CreateMouseCursorMonitor
));
254 EXPECT_CALL(*desktop_environment
, GetCapabilities())
256 EXPECT_CALL(*desktop_environment
, SetCapabilities(_
))
259 return desktop_environment
;
262 // Creates a dummy InputInjector, to mock
263 // DesktopEnvironment::CreateInputInjector().
264 InputInjector
* CreateInputInjector() {
265 MockInputInjector
* input_injector
= new MockInputInjector();
266 EXPECT_CALL(*input_injector
, StartPtr(_
));
267 return input_injector
;
270 // Creates a fake webrtc::DesktopCapturer, to mock
271 // DesktopEnvironment::CreateVideoCapturer().
272 webrtc::DesktopCapturer
* CreateVideoCapturer() {
273 return new FakeDesktopCapturer();
276 // Creates a MockMouseCursorMonitor, to mock
277 // DesktopEnvironment::CreateMouseCursorMonitor().
278 webrtc::MouseCursorMonitor
* CreateMouseCursorMonitor() {
279 return new FakeMouseCursorMonitor();
282 void DisconnectAllClients() {
283 host_
->DisconnectAllClients();
286 // Helper method to disconnect client 1 from the host.
287 void DisconnectClient1() {
288 NotifyClientSessionClosed(0);
291 // Notify |host_| that the authenticating client has been rejected.
292 void RejectAuthenticatingClient() {
293 host_
->RejectAuthenticatingClient();
296 // Notify |host_| that a client session has closed.
297 void NotifyClientSessionClosed(int connection_index
) {
298 get_client(connection_index
)->OnConnectionClosed(
299 get_connection(connection_index
), protocol::OK
);
302 void NotifyConnectionClosed1() {
303 if (session_unowned1_event_handler_
) {
304 session_unowned1_event_handler_
->OnSessionStateChange(Session::CLOSED
);
308 void NotifyConnectionClosed2() {
309 if (session_unowned2_event_handler_
) {
310 session_unowned2_event_handler_
->OnSessionStateChange(Session::CLOSED
);
314 void ShutdownHost() {
315 task_runner_
->PostTask(
317 base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner
,
318 base::Unretained(this)));
321 void StopAndReleaseTaskRunner() {
323 task_runner_
= nullptr;
324 desktop_environment_factory_
.reset();
327 void QuitMainMessageLoop() {
328 PostQuitTask(&message_loop_
);
331 // Expect the host and session manager to start, and return the expectation
332 // that the session manager has started.
333 Expectation
ExpectHostAndSessionManagerStart() {
334 EXPECT_CALL(host_status_observer_
, OnStart(xmpp_login_
));
335 return EXPECT_CALL(*session_manager_
, Init(_
, host_
.get()));
338 // Expect a client to connect.
339 // Return an expectation that a session has started, and that the first
340 // video packet has been sent to the client.
341 // Do |action| when that happens.
343 Expectation
ExpectClientConnected(int connection_index
, A action
) {
344 const std::string
& session_jid
= get_session_jid(connection_index
);
345 MockVideoStub
& video_stub
= get_video_stub(connection_index
);
347 Expectation client_authenticated
=
348 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid
));
349 EXPECT_CALL(host_status_observer_
, OnClientConnected(session_jid
))
350 .After(client_authenticated
);
351 Expectation video_packet_sent
=
352 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
353 .After(client_authenticated
)
357 .RetiresOnSaturation();
358 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
360 .After(video_packet_sent
)
361 .WillRepeatedly(RunDoneTask());
362 return video_packet_sent
;
365 // Return an expectation that a client will disconnect after a given
366 // expectation. The given action will be done after the event executor is
367 // notified that the session has finished.
369 Expectation
ExpectClientDisconnected(int connection_index
,
370 bool expect_host_status_change
,
373 MockConnectionToClient
* connection
= get_connection(connection_index
);
375 Expectation client_disconnected
=
376 EXPECT_CALL(*connection
, Disconnect())
378 .WillOnce(InvokeWithoutArgs(CreateFunctor(
379 this, &ChromotingHostTest::NotifyClientSessionClosed
,
381 .RetiresOnSaturation();
382 ExpectClientDisconnectEffects(connection_index
,
383 expect_host_status_change
,
386 return client_disconnected
;
389 // Expect the side-effects of a client disconnection, after a given
390 // expectation. The given action will be done after the event executor is
391 // notifed that the session has finished.
393 void ExpectClientDisconnectEffects(int connection_index
,
394 bool expect_host_status_change
,
397 const std::string
& session_jid
= get_session_jid(connection_index
);
399 if (expect_host_status_change
) {
400 EXPECT_CALL(host_status_observer_
, OnClientDisconnected(session_jid
))
403 .RetiresOnSaturation();
408 base::MessageLoop message_loop_
;
409 scoped_refptr
<AutoThreadTaskRunner
> task_runner_
;
410 MockConnectionToClientEventHandler handler_
;
411 MockSignalStrategy signal_strategy_
;
412 scoped_ptr
<MockDesktopEnvironmentFactory
> desktop_environment_factory_
;
413 scoped_ptr
<ChromotingHost
> host_
;
414 MockHostStatusObserver host_status_observer_
;
415 protocol::MockSessionManager
* session_manager_
;
416 std::string xmpp_login_
;
417 MockConnectionToClient
* connection1_
;
418 scoped_ptr
<MockConnectionToClient
> owned_connection1_
;
419 ClientSession
* client1_
;
420 std::string session_jid1_
;
421 MockSession
* session1_
; // Owned by |connection_|.
422 scoped_ptr
<SessionConfig
> session_config1_
;
423 MockVideoStub video_stub1_
;
424 MockClientStub client_stub1_
;
425 MockHostStub host_stub1_
;
426 MockConnectionToClient
* connection2_
;
427 scoped_ptr
<MockConnectionToClient
> owned_connection2_
;
428 ClientSession
* client2_
;
429 std::string session_jid2_
;
430 MockSession
* session2_
; // Owned by |connection2_|.
431 scoped_ptr
<SessionConfig
> session_config2_
;
432 MockVideoStub video_stub2_
;
433 MockClientStub client_stub2_
;
434 MockHostStub host_stub2_
;
435 scoped_ptr
<MockSession
> session_unowned1_
; // Not owned by a connection.
436 std::string session_unowned_jid1_
;
437 scoped_ptr
<MockSession
> session_unowned2_
; // Not owned by a connection.
438 std::string session_unowned_jid2_
;
439 protocol::Session::EventHandler
* session_unowned1_event_handler_
;
440 protocol::Session::EventHandler
* session_unowned2_event_handler_
;
441 scoped_ptr
<protocol::CandidateSessionConfig
> empty_candidate_config_
;
442 scoped_ptr
<protocol::CandidateSessionConfig
> default_candidate_config_
;
444 MockConnectionToClient
*& get_connection(int connection_index
) {
445 return (connection_index
== 0) ? connection1_
: connection2_
;
448 // Returns the cached client pointers client1_ or client2_.
449 ClientSession
*& get_client(int connection_index
) {
450 return (connection_index
== 0) ? client1_
: client2_
;
453 // Returns the list of clients of the host_.
454 std::list
<ClientSession
*>& get_clients_from_host() {
455 return host_
->clients_
;
458 const std::string
& get_session_jid(int connection_index
) {
459 return (connection_index
== 0) ? session_jid1_
: session_jid2_
;
462 MockVideoStub
& get_video_stub(int connection_index
) {
463 return (connection_index
== 0) ? video_stub1_
: video_stub2_
;
467 TEST_F(ChromotingHostTest
, StartAndShutdown
) {
468 Expectation start
= ExpectHostAndSessionManagerStart();
469 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(start
);
471 host_
->Start(xmpp_login_
);
476 TEST_F(ChromotingHostTest
, Connect
) {
477 ExpectHostAndSessionManagerStart();
479 // Shut down the host when the first video packet is received.
480 Expectation video_packet_sent
= ExpectClientConnected(
481 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
482 Expectation client_disconnected
= ExpectClientDisconnected(
483 0, true, video_packet_sent
, InvokeWithoutArgs(base::DoNothing
));
484 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected
);
486 host_
->Start(xmpp_login_
);
487 SimulateClientConnection(0, true, false);
491 TEST_F(ChromotingHostTest
, RejectAuthenticatingClient
) {
492 Expectation start
= ExpectHostAndSessionManagerStart();
493 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid1_
))
494 .WillOnce(InvokeWithoutArgs(
495 this, &ChromotingHostTest::RejectAuthenticatingClient
));
496 ExpectClientDisconnected(
498 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
499 EXPECT_CALL(host_status_observer_
, OnShutdown());
501 host_
->Start(xmpp_login_
);
502 SimulateClientConnection(0, true, true);
506 TEST_F(ChromotingHostTest
, AuthenticationFailed
) {
507 ExpectHostAndSessionManagerStart();
508 EXPECT_CALL(host_status_observer_
, OnAccessDenied(session_jid1_
))
509 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
510 EXPECT_CALL(host_status_observer_
, OnShutdown());
512 host_
->Start(xmpp_login_
);
513 SimulateClientConnection(0, false, false);
517 TEST_F(ChromotingHostTest
, Reconnect
) {
518 ExpectHostAndSessionManagerStart();
520 // When a video packet is received on the first connection, disconnect it,
521 // then quit the message loop.
522 Expectation video_packet_sent1
= ExpectClientConnected(0, DoAll(
523 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1
),
524 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop
)));
525 ExpectClientDisconnectEffects(
526 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
528 // When a video packet is received on the second connection, shut down the
530 Expectation video_packet_sent2
= ExpectClientConnected(
531 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
532 Expectation client_disconnected2
= ExpectClientDisconnected(
533 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
534 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
536 host_
->Start(xmpp_login_
);
537 SimulateClientConnection(0, true, false);
539 SimulateClientConnection(1, true, false);
543 TEST_F(ChromotingHostTest
, ConnectWhenAnotherClientIsConnected
) {
544 ExpectHostAndSessionManagerStart();
546 // When a video packet is received, connect the second connection.
547 // This should disconnect the first connection.
548 Expectation video_packet_sent1
= ExpectClientConnected(
553 &ChromotingHostTest::SimulateClientConnection
, 1, true, false)));
554 ExpectClientDisconnected(
555 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
556 Expectation video_packet_sent2
= ExpectClientConnected(
557 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
558 Expectation client_disconnected2
= ExpectClientDisconnected(
559 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
560 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
562 host_
->Start(xmpp_login_
);
563 SimulateClientConnection(0, true, false);
567 TEST_F(ChromotingHostTest
, IncomingSessionDeclined
) {
568 protocol::SessionManager::IncomingSessionResponse response
=
569 protocol::SessionManager::ACCEPT
;
570 host_
->OnIncomingSession(session1_
, &response
);
571 EXPECT_EQ(protocol::SessionManager::DECLINE
, response
);
577 TEST_F(ChromotingHostTest
, IncomingSessionIncompatible
) {
578 ExpectHostAndSessionManagerStart();
579 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
580 empty_candidate_config_
.get()));
581 EXPECT_CALL(host_status_observer_
, OnShutdown());
583 host_
->Start(xmpp_login_
);
585 protocol::SessionManager::IncomingSessionResponse response
=
586 protocol::SessionManager::ACCEPT
;
587 host_
->OnIncomingSession(session_unowned1_
.get(), &response
);
588 EXPECT_EQ(protocol::SessionManager::INCOMPATIBLE
, response
);
594 TEST_F(ChromotingHostTest
, IncomingSessionAccepted
) {
595 ExpectHostAndSessionManagerStart();
596 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
597 default_candidate_config_
.get()));
598 EXPECT_CALL(*session_unowned1_
, set_config_ptr(_
));
599 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(InvokeWithoutArgs(
600 this, &ChromotingHostTest::NotifyConnectionClosed1
));
601 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
602 EXPECT_CALL(host_status_observer_
, OnShutdown());
604 host_
->Start(xmpp_login_
);
606 protocol::SessionManager::IncomingSessionResponse response
=
607 protocol::SessionManager::DECLINE
;
608 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
609 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
615 TEST_F(ChromotingHostTest
, LoginBackOffUponConnection
) {
616 ExpectHostAndSessionManagerStart();
617 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
618 Return(default_candidate_config_
.get()));
619 EXPECT_CALL(*session_unowned1_
, set_config_ptr(_
));
620 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
621 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
622 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
623 EXPECT_CALL(host_status_observer_
, OnShutdown());
625 host_
->Start(xmpp_login_
);
627 protocol::SessionManager::IncomingSessionResponse response
=
628 protocol::SessionManager::DECLINE
;
630 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
631 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
633 host_
->OnSessionAuthenticating(get_clients_from_host().front());
634 host_
->OnIncomingSession(session_unowned2_
.get(), &response
);
635 EXPECT_EQ(protocol::SessionManager::OVERLOAD
, response
);
641 TEST_F(ChromotingHostTest
, LoginBackOffUponAuthenticating
) {
642 Expectation start
= ExpectHostAndSessionManagerStart();
643 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
644 Return(default_candidate_config_
.get()));
645 EXPECT_CALL(*session_unowned1_
, set_config_ptr(_
));
646 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
647 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
649 EXPECT_CALL(*session_unowned2_
, candidate_config()).WillOnce(
650 Return(default_candidate_config_
.get()));
651 EXPECT_CALL(*session_unowned2_
, set_config_ptr(_
));
652 EXPECT_CALL(*session_unowned2_
, Close()).WillOnce(
653 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed2
));
655 EXPECT_CALL(host_status_observer_
, OnShutdown());
657 host_
->Start(xmpp_login_
);
659 protocol::SessionManager::IncomingSessionResponse response
=
660 protocol::SessionManager::DECLINE
;
662 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
663 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
665 host_
->OnIncomingSession(session_unowned2_
.release(), &response
);
666 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
668 // This will set the backoff.
669 host_
->OnSessionAuthenticating(get_clients_from_host().front());
671 // This should disconnect client2.
672 host_
->OnSessionAuthenticating(get_clients_from_host().back());
674 // Verify that the host only has 1 client at this point.
675 EXPECT_EQ(get_clients_from_host().size(), 1U);
681 TEST_F(ChromotingHostTest
, OnSessionRouteChange
) {
682 std::string
channel_name("ChannelName");
683 protocol::TransportRoute route
;
685 ExpectHostAndSessionManagerStart();
686 Expectation video_packet_sent
= ExpectClientConnected(
687 0, InvokeWithoutArgs(CreateFunctor(
688 this, &ChromotingHostTest::ChangeSessionRoute
, channel_name
, route
)));
689 Expectation route_change
=
690 EXPECT_CALL(host_status_observer_
, OnClientRouteChange(
691 session_jid1_
, channel_name
, _
))
692 .After(video_packet_sent
)
693 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
694 ExpectClientDisconnected(0, true, route_change
,
695 InvokeWithoutArgs(base::DoNothing
));
696 EXPECT_CALL(host_status_observer_
, OnShutdown());
698 host_
->Start(xmpp_login_
);
699 SimulateClientConnection(0, true, false);
703 TEST_F(ChromotingHostTest
, DisconnectAllClients
) {
704 ExpectHostAndSessionManagerStart();
705 Expectation video_packet_sent
= ExpectClientConnected(
706 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients
));
707 ExpectClientDisconnected(0, true, video_packet_sent
,
708 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
709 EXPECT_CALL(host_status_observer_
, OnShutdown());
711 host_
->Start(xmpp_login_
);
712 SimulateClientConnection(0, true, false);
716 } // namespace remoting