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_config1_
= SessionConfig::ForTest();
112 session_unowned_jid1_
= "user3@doman/rest-of-jid";
113 session_unowned_config2_
= SessionConfig::ForTest();
114 session_unowned_jid2_
= "user4@doman/rest-of-jid";
116 EXPECT_CALL(*session1_
, jid())
117 .WillRepeatedly(ReturnRef(session_jid1_
));
118 EXPECT_CALL(*session2_
, jid())
119 .WillRepeatedly(ReturnRef(session_jid2_
));
120 EXPECT_CALL(*session_unowned1_
, jid())
121 .WillRepeatedly(ReturnRef(session_unowned_jid1_
));
122 EXPECT_CALL(*session_unowned2_
, jid())
123 .WillRepeatedly(ReturnRef(session_unowned_jid2_
));
124 EXPECT_CALL(*session1_
, SetEventHandler(_
))
126 EXPECT_CALL(*session2_
, SetEventHandler(_
))
128 EXPECT_CALL(*session_unowned1_
, SetEventHandler(_
))
130 .WillRepeatedly(SaveArg
<0>(&session_unowned1_event_handler_
));
131 EXPECT_CALL(*session_unowned2_
, SetEventHandler(_
))
133 .WillRepeatedly(SaveArg
<0>(&session_unowned2_event_handler_
));
134 EXPECT_CALL(*session1_
, config())
135 .WillRepeatedly(ReturnRef(session_config1_
));
136 EXPECT_CALL(*session2_
, config())
137 .WillRepeatedly(ReturnRef(session_config2_
));
139 owned_connection1_
.reset(new MockConnectionToClient(session1_
,
141 connection1_
= owned_connection1_
.get();
142 owned_connection2_
.reset(new MockConnectionToClient(session2_
,
144 connection2_
= owned_connection2_
.get();
146 ON_CALL(video_stub1_
, ProcessVideoPacketPtr(_
, _
))
147 .WillByDefault(DeleteArg
<0>());
148 ON_CALL(video_stub2_
, ProcessVideoPacketPtr(_
, _
))
149 .WillByDefault(DeleteArg
<0>());
150 ON_CALL(*connection1_
, video_stub())
151 .WillByDefault(Return(&video_stub1_
));
152 ON_CALL(*connection1_
, client_stub())
153 .WillByDefault(Return(&client_stub1_
));
154 ON_CALL(*connection1_
, session())
155 .WillByDefault(Return(session1_
));
156 ON_CALL(*connection2_
, video_stub())
157 .WillByDefault(Return(&video_stub2_
));
158 ON_CALL(*connection2_
, client_stub())
159 .WillByDefault(Return(&client_stub2_
));
160 ON_CALL(*connection2_
, session())
161 .WillByDefault(Return(session2_
));
162 EXPECT_CALL(*connection1_
, video_stub())
164 EXPECT_CALL(*connection1_
, client_stub())
166 EXPECT_CALL(*connection1_
, session())
168 EXPECT_CALL(*connection2_
, video_stub())
170 EXPECT_CALL(*connection2_
, client_stub())
172 EXPECT_CALL(*connection2_
, session())
175 empty_candidate_config_
=
176 protocol::CandidateSessionConfig::CreateEmpty();
177 default_candidate_config_
=
178 protocol::CandidateSessionConfig::CreateDefault();
181 // Helper method to pretend a client is connected to ChromotingHost.
182 void SimulateClientConnection(int connection_index
, bool authenticate
,
184 scoped_ptr
<protocol::ConnectionToClient
> connection
=
185 ((connection_index
== 0) ? owned_connection1_
: owned_connection2_
)
187 protocol::ConnectionToClient
* connection_ptr
= connection
.get();
188 scoped_ptr
<ClientSession
> client(new ClientSession(
190 task_runner_
, // Audio
191 task_runner_
, // Input
192 task_runner_
, // Video capture
193 task_runner_
, // Video encode
194 task_runner_
, // Network
197 desktop_environment_factory_
.get(),
200 std::vector
<HostExtension
*>()));
202 connection_ptr
->set_host_stub(client
.get());
205 task_runner_
->PostTask(
207 base::Bind(&ClientSession::OnConnectionAuthenticated
,
208 base::Unretained(client
.get()), connection_ptr
));
210 task_runner_
->PostTask(
212 base::Bind(&ClientSession::OnConnectionChannelsConnected
,
213 base::Unretained(client
.get()), connection_ptr
));
216 task_runner_
->PostTask(
217 FROM_HERE
, base::Bind(&ClientSession::OnConnectionClosed
,
218 base::Unretained(client
.get()), connection_ptr
,
219 protocol::AUTHENTICATION_FAILED
));
222 get_client(connection_index
) = client
.get();
224 // |host| is responsible for deleting |client| from now on.
225 host_
->clients_
.push_back(client
.release());
228 void TearDown() override
{
229 // Make sure that the host has been properly deleted.
230 DCHECK(host_
.get() == nullptr);
233 // Change the session route for |client1_|.
234 void ChangeSessionRoute(const std::string
& channel_name
,
235 const protocol::TransportRoute
& route
) {
236 host_
->OnSessionRouteChange(get_client(0), channel_name
, route
);
239 // Creates a DesktopEnvironment with a fake webrtc::DesktopCapturer, to mock
240 // DesktopEnvironmentFactory::Create().
241 DesktopEnvironment
* CreateDesktopEnvironment() {
242 MockDesktopEnvironment
* desktop_environment
= new MockDesktopEnvironment();
243 EXPECT_CALL(*desktop_environment
, CreateAudioCapturerPtr())
245 EXPECT_CALL(*desktop_environment
, CreateInputInjectorPtr())
247 .WillOnce(Invoke(this, &ChromotingHostTest::CreateInputInjector
));
248 EXPECT_CALL(*desktop_environment
, CreateScreenControlsPtr())
250 EXPECT_CALL(*desktop_environment
, CreateVideoCapturerPtr())
252 .WillOnce(Invoke(this, &ChromotingHostTest::CreateVideoCapturer
));
253 EXPECT_CALL(*desktop_environment
, CreateMouseCursorMonitorPtr())
255 .WillOnce(Invoke(this, &ChromotingHostTest::CreateMouseCursorMonitor
));
256 EXPECT_CALL(*desktop_environment
, GetCapabilities())
258 EXPECT_CALL(*desktop_environment
, SetCapabilities(_
))
261 return desktop_environment
;
264 // Creates a dummy InputInjector, to mock
265 // DesktopEnvironment::CreateInputInjector().
266 InputInjector
* CreateInputInjector() {
267 MockInputInjector
* input_injector
= new MockInputInjector();
268 EXPECT_CALL(*input_injector
, StartPtr(_
));
269 return input_injector
;
272 // Creates a fake webrtc::DesktopCapturer, to mock
273 // DesktopEnvironment::CreateVideoCapturer().
274 webrtc::DesktopCapturer
* CreateVideoCapturer() {
275 return new FakeDesktopCapturer();
278 // Creates a MockMouseCursorMonitor, to mock
279 // DesktopEnvironment::CreateMouseCursorMonitor().
280 webrtc::MouseCursorMonitor
* CreateMouseCursorMonitor() {
281 return new FakeMouseCursorMonitor();
284 void DisconnectAllClients() {
285 host_
->DisconnectAllClients();
288 // Helper method to disconnect client 1 from the host.
289 void DisconnectClient1() {
290 NotifyClientSessionClosed(0);
293 // Notify |host_| that the authenticating client has been rejected.
294 void RejectAuthenticatingClient() {
295 host_
->RejectAuthenticatingClient();
298 // Notify |host_| that a client session has closed.
299 void NotifyClientSessionClosed(int connection_index
) {
300 get_client(connection_index
)->OnConnectionClosed(
301 get_connection(connection_index
), protocol::OK
);
304 void NotifyConnectionClosed1() {
305 if (session_unowned1_event_handler_
) {
306 session_unowned1_event_handler_
->OnSessionStateChange(Session::CLOSED
);
310 void NotifyConnectionClosed2() {
311 if (session_unowned2_event_handler_
) {
312 session_unowned2_event_handler_
->OnSessionStateChange(Session::CLOSED
);
316 void ShutdownHost() {
317 task_runner_
->PostTask(
319 base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner
,
320 base::Unretained(this)));
323 void StopAndReleaseTaskRunner() {
325 task_runner_
= nullptr;
326 desktop_environment_factory_
.reset();
329 void QuitMainMessageLoop() {
330 PostQuitTask(&message_loop_
);
333 // Expect the host and session manager to start, and return the expectation
334 // that the session manager has started.
335 Expectation
ExpectHostAndSessionManagerStart() {
336 EXPECT_CALL(host_status_observer_
, OnStart(xmpp_login_
));
337 return EXPECT_CALL(*session_manager_
, Init(_
, host_
.get()));
340 // Expect a client to connect.
341 // Return an expectation that a session has started, and that the first
342 // video packet has been sent to the client.
343 // Do |action| when that happens.
345 Expectation
ExpectClientConnected(int connection_index
, A action
) {
346 const std::string
& session_jid
= get_session_jid(connection_index
);
347 MockVideoStub
& video_stub
= get_video_stub(connection_index
);
349 Expectation client_authenticated
=
350 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid
));
351 EXPECT_CALL(host_status_observer_
, OnClientConnected(session_jid
))
352 .After(client_authenticated
);
353 Expectation video_packet_sent
=
354 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
355 .After(client_authenticated
)
359 .RetiresOnSaturation();
360 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
362 .After(video_packet_sent
)
363 .WillRepeatedly(RunDoneTask());
364 return video_packet_sent
;
367 // Return an expectation that a client will disconnect after a given
368 // expectation. The given action will be done after the event executor is
369 // notified that the session has finished.
371 Expectation
ExpectClientDisconnected(int connection_index
,
372 bool expect_host_status_change
,
375 MockConnectionToClient
* connection
= get_connection(connection_index
);
377 Expectation client_disconnected
=
378 EXPECT_CALL(*connection
, Disconnect())
380 .WillOnce(InvokeWithoutArgs(CreateFunctor(
381 this, &ChromotingHostTest::NotifyClientSessionClosed
,
383 .RetiresOnSaturation();
384 ExpectClientDisconnectEffects(connection_index
,
385 expect_host_status_change
,
388 return client_disconnected
;
391 // Expect the side-effects of a client disconnection, after a given
392 // expectation. The given action will be done after the event executor is
393 // notifed that the session has finished.
395 void ExpectClientDisconnectEffects(int connection_index
,
396 bool expect_host_status_change
,
399 const std::string
& session_jid
= get_session_jid(connection_index
);
401 if (expect_host_status_change
) {
402 EXPECT_CALL(host_status_observer_
, OnClientDisconnected(session_jid
))
405 .RetiresOnSaturation();
410 base::MessageLoop message_loop_
;
411 scoped_refptr
<AutoThreadTaskRunner
> task_runner_
;
412 MockConnectionToClientEventHandler handler_
;
413 MockSignalStrategy signal_strategy_
;
414 scoped_ptr
<MockDesktopEnvironmentFactory
> desktop_environment_factory_
;
415 scoped_ptr
<ChromotingHost
> host_
;
416 MockHostStatusObserver host_status_observer_
;
417 protocol::MockSessionManager
* session_manager_
;
418 std::string xmpp_login_
;
419 MockConnectionToClient
* connection1_
;
420 scoped_ptr
<MockConnectionToClient
> owned_connection1_
;
421 ClientSession
* client1_
;
422 std::string session_jid1_
;
423 MockSession
* session1_
; // Owned by |connection_|.
424 SessionConfig session_config1_
;
425 MockVideoStub video_stub1_
;
426 MockClientStub client_stub1_
;
427 MockHostStub host_stub1_
;
428 MockConnectionToClient
* connection2_
;
429 scoped_ptr
<MockConnectionToClient
> owned_connection2_
;
430 ClientSession
* client2_
;
431 std::string session_jid2_
;
432 MockSession
* session2_
; // Owned by |connection2_|.
433 SessionConfig session_config2_
;
434 MockVideoStub video_stub2_
;
435 MockClientStub client_stub2_
;
436 MockHostStub host_stub2_
;
437 scoped_ptr
<MockSession
> session_unowned1_
; // Not owned by a connection.
438 SessionConfig session_unowned_config1_
;
439 std::string session_unowned_jid1_
;
440 scoped_ptr
<MockSession
> session_unowned2_
; // Not owned by a connection.
441 SessionConfig session_unowned_config2_
;
442 std::string session_unowned_jid2_
;
443 protocol::Session::EventHandler
* session_unowned1_event_handler_
;
444 protocol::Session::EventHandler
* session_unowned2_event_handler_
;
445 scoped_ptr
<protocol::CandidateSessionConfig
> empty_candidate_config_
;
446 scoped_ptr
<protocol::CandidateSessionConfig
> default_candidate_config_
;
448 MockConnectionToClient
*& get_connection(int connection_index
) {
449 return (connection_index
== 0) ? connection1_
: connection2_
;
452 // Returns the cached client pointers client1_ or client2_.
453 ClientSession
*& get_client(int connection_index
) {
454 return (connection_index
== 0) ? client1_
: client2_
;
457 // Returns the list of clients of the host_.
458 std::list
<ClientSession
*>& get_clients_from_host() {
459 return host_
->clients_
;
462 const std::string
& get_session_jid(int connection_index
) {
463 return (connection_index
== 0) ? session_jid1_
: session_jid2_
;
466 MockVideoStub
& get_video_stub(int connection_index
) {
467 return (connection_index
== 0) ? video_stub1_
: video_stub2_
;
471 TEST_F(ChromotingHostTest
, StartAndShutdown
) {
472 Expectation start
= ExpectHostAndSessionManagerStart();
473 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(start
);
475 host_
->Start(xmpp_login_
);
480 TEST_F(ChromotingHostTest
, Connect
) {
481 ExpectHostAndSessionManagerStart();
483 // Shut down the host when the first video packet is received.
484 Expectation video_packet_sent
= ExpectClientConnected(
485 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
486 Expectation client_disconnected
= ExpectClientDisconnected(
487 0, true, video_packet_sent
, InvokeWithoutArgs(base::DoNothing
));
488 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected
);
490 host_
->Start(xmpp_login_
);
491 SimulateClientConnection(0, true, false);
495 TEST_F(ChromotingHostTest
, RejectAuthenticatingClient
) {
496 Expectation start
= ExpectHostAndSessionManagerStart();
497 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid1_
))
498 .WillOnce(InvokeWithoutArgs(
499 this, &ChromotingHostTest::RejectAuthenticatingClient
));
500 ExpectClientDisconnected(
502 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
503 EXPECT_CALL(host_status_observer_
, OnShutdown());
505 host_
->Start(xmpp_login_
);
506 SimulateClientConnection(0, true, true);
510 TEST_F(ChromotingHostTest
, AuthenticationFailed
) {
511 ExpectHostAndSessionManagerStart();
512 EXPECT_CALL(host_status_observer_
, OnAccessDenied(session_jid1_
))
513 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
514 EXPECT_CALL(host_status_observer_
, OnShutdown());
516 host_
->Start(xmpp_login_
);
517 SimulateClientConnection(0, false, false);
521 TEST_F(ChromotingHostTest
, Reconnect
) {
522 ExpectHostAndSessionManagerStart();
524 // When a video packet is received on the first connection, disconnect it,
525 // then quit the message loop.
526 Expectation video_packet_sent1
= ExpectClientConnected(0, DoAll(
527 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1
),
528 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop
)));
529 ExpectClientDisconnectEffects(
530 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
532 // When a video packet is received on the second connection, shut down the
534 Expectation video_packet_sent2
= ExpectClientConnected(
535 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
536 Expectation client_disconnected2
= ExpectClientDisconnected(
537 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
538 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
540 host_
->Start(xmpp_login_
);
541 SimulateClientConnection(0, true, false);
543 SimulateClientConnection(1, true, false);
547 TEST_F(ChromotingHostTest
, ConnectWhenAnotherClientIsConnected
) {
548 ExpectHostAndSessionManagerStart();
550 // When a video packet is received, connect the second connection.
551 // This should disconnect the first connection.
552 Expectation video_packet_sent1
= ExpectClientConnected(
557 &ChromotingHostTest::SimulateClientConnection
, 1, true, false)));
558 ExpectClientDisconnected(
559 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
560 Expectation video_packet_sent2
= ExpectClientConnected(
561 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
562 Expectation client_disconnected2
= ExpectClientDisconnected(
563 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
564 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
566 host_
->Start(xmpp_login_
);
567 SimulateClientConnection(0, true, false);
571 TEST_F(ChromotingHostTest
, IncomingSessionDeclined
) {
572 protocol::SessionManager::IncomingSessionResponse response
=
573 protocol::SessionManager::ACCEPT
;
574 host_
->OnIncomingSession(session1_
, &response
);
575 EXPECT_EQ(protocol::SessionManager::DECLINE
, response
);
581 TEST_F(ChromotingHostTest
, IncomingSessionIncompatible
) {
582 ExpectHostAndSessionManagerStart();
583 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
584 empty_candidate_config_
.get()));
585 EXPECT_CALL(host_status_observer_
, OnShutdown());
587 host_
->Start(xmpp_login_
);
589 protocol::SessionManager::IncomingSessionResponse response
=
590 protocol::SessionManager::ACCEPT
;
591 host_
->OnIncomingSession(session_unowned1_
.get(), &response
);
592 EXPECT_EQ(protocol::SessionManager::INCOMPATIBLE
, response
);
598 TEST_F(ChromotingHostTest
, IncomingSessionAccepted
) {
599 ExpectHostAndSessionManagerStart();
600 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
601 default_candidate_config_
.get()));
602 EXPECT_CALL(*session_unowned1_
, set_config(_
));
603 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(InvokeWithoutArgs(
604 this, &ChromotingHostTest::NotifyConnectionClosed1
));
605 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
606 EXPECT_CALL(host_status_observer_
, OnShutdown());
608 host_
->Start(xmpp_login_
);
610 protocol::SessionManager::IncomingSessionResponse response
=
611 protocol::SessionManager::DECLINE
;
612 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
613 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
619 TEST_F(ChromotingHostTest
, LoginBackOffUponConnection
) {
620 ExpectHostAndSessionManagerStart();
621 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
622 Return(default_candidate_config_
.get()));
623 EXPECT_CALL(*session_unowned1_
, set_config(_
));
624 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
625 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
626 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
627 EXPECT_CALL(host_status_observer_
, OnShutdown());
629 host_
->Start(xmpp_login_
);
631 protocol::SessionManager::IncomingSessionResponse response
=
632 protocol::SessionManager::DECLINE
;
634 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
635 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
637 host_
->OnSessionAuthenticating(get_clients_from_host().front());
638 host_
->OnIncomingSession(session_unowned2_
.get(), &response
);
639 EXPECT_EQ(protocol::SessionManager::OVERLOAD
, response
);
645 TEST_F(ChromotingHostTest
, LoginBackOffUponAuthenticating
) {
646 Expectation start
= ExpectHostAndSessionManagerStart();
647 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
648 Return(default_candidate_config_
.get()));
649 EXPECT_CALL(*session_unowned1_
, set_config(_
));
650 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
651 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
653 EXPECT_CALL(*session_unowned2_
, candidate_config()).WillOnce(
654 Return(default_candidate_config_
.get()));
655 EXPECT_CALL(*session_unowned2_
, set_config(_
));
656 EXPECT_CALL(*session_unowned2_
, Close()).WillOnce(
657 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed2
));
659 EXPECT_CALL(host_status_observer_
, OnShutdown());
661 host_
->Start(xmpp_login_
);
663 protocol::SessionManager::IncomingSessionResponse response
=
664 protocol::SessionManager::DECLINE
;
666 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
667 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
669 host_
->OnIncomingSession(session_unowned2_
.release(), &response
);
670 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
672 // This will set the backoff.
673 host_
->OnSessionAuthenticating(get_clients_from_host().front());
675 // This should disconnect client2.
676 host_
->OnSessionAuthenticating(get_clients_from_host().back());
678 // Verify that the host only has 1 client at this point.
679 EXPECT_EQ(get_clients_from_host().size(), 1U);
685 TEST_F(ChromotingHostTest
, OnSessionRouteChange
) {
686 std::string
channel_name("ChannelName");
687 protocol::TransportRoute route
;
689 ExpectHostAndSessionManagerStart();
690 Expectation video_packet_sent
= ExpectClientConnected(
691 0, InvokeWithoutArgs(CreateFunctor(
692 this, &ChromotingHostTest::ChangeSessionRoute
, channel_name
, route
)));
693 Expectation route_change
=
694 EXPECT_CALL(host_status_observer_
, OnClientRouteChange(
695 session_jid1_
, channel_name
, _
))
696 .After(video_packet_sent
)
697 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
698 ExpectClientDisconnected(0, true, route_change
,
699 InvokeWithoutArgs(base::DoNothing
));
700 EXPECT_CALL(host_status_observer_
, OnShutdown());
702 host_
->Start(xmpp_login_
);
703 SimulateClientConnection(0, true, false);
707 TEST_F(ChromotingHostTest
, DisconnectAllClients
) {
708 ExpectHostAndSessionManagerStart();
709 Expectation video_packet_sent
= ExpectClientConnected(
710 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients
));
711 ExpectClientDisconnected(0, true, video_packet_sent
,
712 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
713 EXPECT_CALL(host_status_observer_
, OnShutdown());
715 host_
->Start(xmpp_login_
);
716 SimulateClientConnection(0, true, false);
720 } // namespace remoting