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/host_mock_objects.h"
15 #include "remoting/host/screen_capturer_fake.h"
16 #include "remoting/jingle_glue/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 "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 virtual void SetUp() OVERRIDE
{
73 task_runner_
= new AutoThreadTaskRunner(
74 message_loop_
.message_loop_proxy(),
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 scoped_ptr
<protocol::SessionManager
>(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_config1_
= SessionConfig::ForTest();
111 session_unowned_jid1_
= "user3@doman/rest-of-jid";
112 session_unowned_config2_
= SessionConfig::ForTest();
113 session_unowned_jid2_
= "user4@doman/rest-of-jid";
115 EXPECT_CALL(*session1_
, jid())
116 .WillRepeatedly(ReturnRef(session_jid1_
));
117 EXPECT_CALL(*session2_
, jid())
118 .WillRepeatedly(ReturnRef(session_jid2_
));
119 EXPECT_CALL(*session_unowned1_
, jid())
120 .WillRepeatedly(ReturnRef(session_unowned_jid1_
));
121 EXPECT_CALL(*session_unowned2_
, jid())
122 .WillRepeatedly(ReturnRef(session_unowned_jid2_
));
123 EXPECT_CALL(*session1_
, SetEventHandler(_
))
125 EXPECT_CALL(*session2_
, SetEventHandler(_
))
127 EXPECT_CALL(*session_unowned1_
, SetEventHandler(_
))
129 .WillRepeatedly(SaveArg
<0>(&session_unowned1_event_handler_
));
130 EXPECT_CALL(*session_unowned2_
, SetEventHandler(_
))
132 .WillRepeatedly(SaveArg
<0>(&session_unowned2_event_handler_
));
133 EXPECT_CALL(*session1_
, config())
134 .WillRepeatedly(ReturnRef(session_config1_
));
135 EXPECT_CALL(*session2_
, config())
136 .WillRepeatedly(ReturnRef(session_config2_
));
138 owned_connection1_
.reset(new MockConnectionToClient(session1_
,
140 connection1_
= owned_connection1_
.get();
141 owned_connection2_
.reset(new MockConnectionToClient(session2_
,
143 connection2_
= owned_connection2_
.get();
145 ON_CALL(video_stub1_
, ProcessVideoPacketPtr(_
, _
))
146 .WillByDefault(DeleteArg
<0>());
147 ON_CALL(video_stub2_
, ProcessVideoPacketPtr(_
, _
))
148 .WillByDefault(DeleteArg
<0>());
149 ON_CALL(*connection1_
, video_stub())
150 .WillByDefault(Return(&video_stub1_
));
151 ON_CALL(*connection1_
, client_stub())
152 .WillByDefault(Return(&client_stub1_
));
153 ON_CALL(*connection1_
, session())
154 .WillByDefault(Return(session1_
));
155 ON_CALL(*connection2_
, video_stub())
156 .WillByDefault(Return(&video_stub2_
));
157 ON_CALL(*connection2_
, client_stub())
158 .WillByDefault(Return(&client_stub2_
));
159 ON_CALL(*connection2_
, session())
160 .WillByDefault(Return(session2_
));
161 EXPECT_CALL(*connection1_
, video_stub())
163 EXPECT_CALL(*connection1_
, client_stub())
165 EXPECT_CALL(*connection1_
, session())
167 EXPECT_CALL(*connection2_
, video_stub())
169 EXPECT_CALL(*connection2_
, client_stub())
171 EXPECT_CALL(*connection2_
, session())
174 empty_candidate_config_
=
175 protocol::CandidateSessionConfig::CreateEmpty();
176 default_candidate_config_
=
177 protocol::CandidateSessionConfig::CreateDefault();
180 // Helper method to pretend a client is connected to ChromotingHost.
181 void SimulateClientConnection(int connection_index
, bool authenticate
,
183 scoped_ptr
<protocol::ConnectionToClient
> connection
=
184 ((connection_index
== 0) ? owned_connection1_
: owned_connection2_
).
185 PassAs
<protocol::ConnectionToClient
>();
186 protocol::ConnectionToClient
* connection_ptr
= connection
.get();
187 scoped_ptr
<ClientSession
> client(new ClientSession(
189 task_runner_
, // Audio
190 task_runner_
, // Input
191 task_runner_
, // Video capture
192 task_runner_
, // Video encode
193 task_runner_
, // Network
196 desktop_environment_factory_
.get(),
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 virtual void TearDown() OVERRIDE
{
227 // Make sure that the host has been properly deleted.
228 DCHECK(host_
.get() == NULL
);
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::ScreenCapturer, 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
, GetCapabilities())
253 EXPECT_CALL(*desktop_environment
, SetCapabilities(_
))
256 return desktop_environment
;
259 // Creates a dummy InputInjector, to mock
260 // DesktopEnvironment::CreateInputInjector().
261 InputInjector
* CreateInputInjector() {
262 MockInputInjector
* input_injector
= new MockInputInjector();
263 EXPECT_CALL(*input_injector
, StartPtr(_
));
264 return input_injector
;
267 // Creates a fake webrtc::ScreenCapturer, to mock
268 // DesktopEnvironment::CreateVideoCapturer().
269 webrtc::ScreenCapturer
* CreateVideoCapturer() {
270 return new ScreenCapturerFake();
273 void DisconnectAllClients() {
274 host_
->DisconnectAllClients();
277 // Helper method to disconnect client 1 from the host.
278 void DisconnectClient1() {
279 NotifyClientSessionClosed(0);
282 // Notify |host_| that the authenticating client has been rejected.
283 void RejectAuthenticatingClient() {
284 host_
->RejectAuthenticatingClient();
287 // Notify |host_| that a client session has closed.
288 void NotifyClientSessionClosed(int connection_index
) {
289 get_client(connection_index
)->OnConnectionClosed(
290 get_connection(connection_index
), protocol::OK
);
293 void NotifyConnectionClosed1() {
294 if (session_unowned1_event_handler_
) {
295 session_unowned1_event_handler_
->OnSessionStateChange(Session::CLOSED
);
299 void NotifyConnectionClosed2() {
300 if (session_unowned2_event_handler_
) {
301 session_unowned2_event_handler_
->OnSessionStateChange(Session::CLOSED
);
305 void ShutdownHost() {
306 task_runner_
->PostTask(
308 base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner
,
309 base::Unretained(this)));
312 void StopAndReleaseTaskRunner() {
315 desktop_environment_factory_
.reset();
318 void QuitMainMessageLoop() {
319 PostQuitTask(&message_loop_
);
322 // Expect the host and session manager to start, and return the expectation
323 // that the session manager has started.
324 Expectation
ExpectHostAndSessionManagerStart() {
325 EXPECT_CALL(host_status_observer_
, OnStart(xmpp_login_
));
326 return EXPECT_CALL(*session_manager_
, Init(_
, host_
.get()));
329 // Expect a client to connect.
330 // Return an expectation that a session has started, and that the first
331 // video packet has been sent to the client.
332 // Do |action| when that happens.
334 Expectation
ExpectClientConnected(int connection_index
, A action
) {
335 const std::string
& session_jid
= get_session_jid(connection_index
);
336 MockVideoStub
& video_stub
= get_video_stub(connection_index
);
338 Expectation client_authenticated
=
339 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid
));
340 EXPECT_CALL(host_status_observer_
, OnClientConnected(session_jid
))
341 .After(client_authenticated
);
342 Expectation video_packet_sent
=
343 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
344 .After(client_authenticated
)
348 .RetiresOnSaturation();
349 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
351 .After(video_packet_sent
)
352 .WillRepeatedly(RunDoneTask());
353 return video_packet_sent
;
356 // Return an expectation that a client will disconnect after a given
357 // expectation. The given action will be done after the event executor is
358 // notified that the session has finished.
360 Expectation
ExpectClientDisconnected(int connection_index
,
361 bool expect_host_status_change
,
364 MockConnectionToClient
* connection
= get_connection(connection_index
);
366 Expectation client_disconnected
=
367 EXPECT_CALL(*connection
, Disconnect())
369 .WillOnce(InvokeWithoutArgs(CreateFunctor(
370 this, &ChromotingHostTest::NotifyClientSessionClosed
,
372 .RetiresOnSaturation();
373 ExpectClientDisconnectEffects(connection_index
,
374 expect_host_status_change
,
377 return client_disconnected
;
380 // Expect the side-effects of a client disconnection, after a given
381 // expectation. The given action will be done after the event executor is
382 // notifed that the session has finished.
384 void ExpectClientDisconnectEffects(int connection_index
,
385 bool expect_host_status_change
,
388 const std::string
& session_jid
= get_session_jid(connection_index
);
390 if (expect_host_status_change
) {
391 EXPECT_CALL(host_status_observer_
, OnClientDisconnected(session_jid
))
394 .RetiresOnSaturation();
399 base::MessageLoop message_loop_
;
400 scoped_refptr
<AutoThreadTaskRunner
> task_runner_
;
401 MockConnectionToClientEventHandler handler_
;
402 MockSignalStrategy signal_strategy_
;
403 scoped_ptr
<MockDesktopEnvironmentFactory
> desktop_environment_factory_
;
404 scoped_ptr
<ChromotingHost
> host_
;
405 MockHostStatusObserver host_status_observer_
;
406 protocol::MockSessionManager
* session_manager_
;
407 std::string xmpp_login_
;
408 MockConnectionToClient
* connection1_
;
409 scoped_ptr
<MockConnectionToClient
> owned_connection1_
;
410 ClientSession
* client1_
;
411 std::string session_jid1_
;
412 MockSession
* session1_
; // Owned by |connection_|.
413 SessionConfig session_config1_
;
414 MockVideoStub video_stub1_
;
415 MockClientStub client_stub1_
;
416 MockHostStub host_stub1_
;
417 MockConnectionToClient
* connection2_
;
418 scoped_ptr
<MockConnectionToClient
> owned_connection2_
;
419 ClientSession
* client2_
;
420 std::string session_jid2_
;
421 MockSession
* session2_
; // Owned by |connection2_|.
422 SessionConfig session_config2_
;
423 MockVideoStub video_stub2_
;
424 MockClientStub client_stub2_
;
425 MockHostStub host_stub2_
;
426 scoped_ptr
<MockSession
> session_unowned1_
; // Not owned by a connection.
427 SessionConfig session_unowned_config1_
;
428 std::string session_unowned_jid1_
;
429 scoped_ptr
<MockSession
> session_unowned2_
; // Not owned by a connection.
430 SessionConfig session_unowned_config2_
;
431 std::string session_unowned_jid2_
;
432 protocol::Session::EventHandler
* session_unowned1_event_handler_
;
433 protocol::Session::EventHandler
* session_unowned2_event_handler_
;
434 scoped_ptr
<protocol::CandidateSessionConfig
> empty_candidate_config_
;
435 scoped_ptr
<protocol::CandidateSessionConfig
> default_candidate_config_
;
437 MockConnectionToClient
*& get_connection(int connection_index
) {
438 return (connection_index
== 0) ? connection1_
: connection2_
;
441 // Returns the cached client pointers client1_ or client2_.
442 ClientSession
*& get_client(int connection_index
) {
443 return (connection_index
== 0) ? client1_
: client2_
;
446 // Returns the list of clients of the host_.
447 std::list
<ClientSession
*>& get_clients_from_host() {
448 return host_
->clients_
;
451 const std::string
& get_session_jid(int connection_index
) {
452 return (connection_index
== 0) ? session_jid1_
: session_jid2_
;
455 MockVideoStub
& get_video_stub(int connection_index
) {
456 return (connection_index
== 0) ? video_stub1_
: video_stub2_
;
460 TEST_F(ChromotingHostTest
, StartAndShutdown
) {
461 Expectation start
= ExpectHostAndSessionManagerStart();
462 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(start
);
464 host_
->Start(xmpp_login_
);
469 TEST_F(ChromotingHostTest
, Connect
) {
470 ExpectHostAndSessionManagerStart();
472 // Shut down the host when the first video packet is received.
473 Expectation video_packet_sent
= ExpectClientConnected(
474 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
475 Expectation client_disconnected
= ExpectClientDisconnected(
476 0, true, video_packet_sent
, InvokeWithoutArgs(base::DoNothing
));
477 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected
);
479 host_
->Start(xmpp_login_
);
480 SimulateClientConnection(0, true, false);
484 TEST_F(ChromotingHostTest
, RejectAuthenticatingClient
) {
485 Expectation start
= ExpectHostAndSessionManagerStart();
486 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid1_
))
487 .WillOnce(InvokeWithoutArgs(
488 this, &ChromotingHostTest::RejectAuthenticatingClient
));
489 ExpectClientDisconnected(
491 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
492 EXPECT_CALL(host_status_observer_
, OnShutdown());
494 host_
->Start(xmpp_login_
);
495 SimulateClientConnection(0, true, true);
499 TEST_F(ChromotingHostTest
, AuthenticationFailed
) {
500 ExpectHostAndSessionManagerStart();
501 EXPECT_CALL(host_status_observer_
, OnAccessDenied(session_jid1_
))
502 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
503 EXPECT_CALL(host_status_observer_
, OnShutdown());
505 host_
->Start(xmpp_login_
);
506 SimulateClientConnection(0, false, false);
510 TEST_F(ChromotingHostTest
, Reconnect
) {
511 ExpectHostAndSessionManagerStart();
513 // When a video packet is received on the first connection, disconnect it,
514 // then quit the message loop.
515 Expectation video_packet_sent1
= ExpectClientConnected(0, DoAll(
516 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1
),
517 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop
)));
518 ExpectClientDisconnectEffects(
519 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
521 // When a video packet is received on the second connection, shut down the
523 Expectation video_packet_sent2
= ExpectClientConnected(
524 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
525 Expectation client_disconnected2
= ExpectClientDisconnected(
526 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
527 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
529 host_
->Start(xmpp_login_
);
530 SimulateClientConnection(0, true, false);
532 SimulateClientConnection(1, true, false);
536 TEST_F(ChromotingHostTest
, ConnectWhenAnotherClientIsConnected
) {
537 ExpectHostAndSessionManagerStart();
539 // When a video packet is received, connect the second connection.
540 // This should disconnect the first connection.
541 Expectation video_packet_sent1
= ExpectClientConnected(
546 &ChromotingHostTest::SimulateClientConnection
, 1, true, false)));
547 ExpectClientDisconnected(
548 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
549 Expectation video_packet_sent2
= ExpectClientConnected(
550 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
551 Expectation client_disconnected2
= ExpectClientDisconnected(
552 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
553 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
555 host_
->Start(xmpp_login_
);
556 SimulateClientConnection(0, true, false);
560 TEST_F(ChromotingHostTest
, IncomingSessionDeclined
) {
561 protocol::SessionManager::IncomingSessionResponse response
=
562 protocol::SessionManager::ACCEPT
;
563 host_
->OnIncomingSession(session1_
, &response
);
564 EXPECT_EQ(protocol::SessionManager::DECLINE
, response
);
570 TEST_F(ChromotingHostTest
, IncomingSessionIncompatible
) {
571 ExpectHostAndSessionManagerStart();
572 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
573 empty_candidate_config_
.get()));
574 EXPECT_CALL(host_status_observer_
, OnShutdown());
576 host_
->Start(xmpp_login_
);
578 protocol::SessionManager::IncomingSessionResponse response
=
579 protocol::SessionManager::ACCEPT
;
580 host_
->OnIncomingSession(session_unowned1_
.get(), &response
);
581 EXPECT_EQ(protocol::SessionManager::INCOMPATIBLE
, response
);
587 TEST_F(ChromotingHostTest
, IncomingSessionAccepted
) {
588 ExpectHostAndSessionManagerStart();
589 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(Return(
590 default_candidate_config_
.get()));
591 EXPECT_CALL(*session_unowned1_
, set_config(_
));
592 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(InvokeWithoutArgs(
593 this, &ChromotingHostTest::NotifyConnectionClosed1
));
594 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
595 EXPECT_CALL(host_status_observer_
, OnShutdown());
597 host_
->Start(xmpp_login_
);
599 protocol::SessionManager::IncomingSessionResponse response
=
600 protocol::SessionManager::DECLINE
;
601 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
602 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
608 TEST_F(ChromotingHostTest
, LoginBackOffUponConnection
) {
609 ExpectHostAndSessionManagerStart();
610 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
611 Return(default_candidate_config_
.get()));
612 EXPECT_CALL(*session_unowned1_
, set_config(_
));
613 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
614 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
615 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
616 EXPECT_CALL(host_status_observer_
, OnShutdown());
618 host_
->Start(xmpp_login_
);
620 protocol::SessionManager::IncomingSessionResponse response
=
621 protocol::SessionManager::DECLINE
;
623 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
624 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
626 host_
->OnSessionAuthenticating(get_clients_from_host().front());
627 host_
->OnIncomingSession(session_unowned2_
.get(), &response
);
628 EXPECT_EQ(protocol::SessionManager::OVERLOAD
, response
);
634 TEST_F(ChromotingHostTest
, LoginBackOffUponAuthenticating
) {
635 Expectation start
= ExpectHostAndSessionManagerStart();
636 EXPECT_CALL(*session_unowned1_
, candidate_config()).WillOnce(
637 Return(default_candidate_config_
.get()));
638 EXPECT_CALL(*session_unowned1_
, set_config(_
));
639 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
640 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
642 EXPECT_CALL(*session_unowned2_
, candidate_config()).WillOnce(
643 Return(default_candidate_config_
.get()));
644 EXPECT_CALL(*session_unowned2_
, set_config(_
));
645 EXPECT_CALL(*session_unowned2_
, Close()).WillOnce(
646 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed2
));
648 EXPECT_CALL(host_status_observer_
, OnShutdown());
650 host_
->Start(xmpp_login_
);
652 protocol::SessionManager::IncomingSessionResponse response
=
653 protocol::SessionManager::DECLINE
;
655 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
656 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
658 host_
->OnIncomingSession(session_unowned2_
.release(), &response
);
659 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
661 // This will set the backoff.
662 host_
->OnSessionAuthenticating(get_clients_from_host().front());
664 // This should disconnect client2.
665 host_
->OnSessionAuthenticating(get_clients_from_host().back());
667 // Verify that the host only has 1 client at this point.
668 EXPECT_EQ(get_clients_from_host().size(), 1U);
674 TEST_F(ChromotingHostTest
, OnSessionRouteChange
) {
675 std::string
channel_name("ChannelName");
676 protocol::TransportRoute route
;
678 ExpectHostAndSessionManagerStart();
679 Expectation video_packet_sent
= ExpectClientConnected(
680 0, InvokeWithoutArgs(CreateFunctor(
681 this, &ChromotingHostTest::ChangeSessionRoute
, channel_name
, route
)));
682 Expectation route_change
=
683 EXPECT_CALL(host_status_observer_
, OnClientRouteChange(
684 session_jid1_
, channel_name
, _
))
685 .After(video_packet_sent
)
686 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
687 ExpectClientDisconnected(0, true, route_change
,
688 InvokeWithoutArgs(base::DoNothing
));
689 EXPECT_CALL(host_status_observer_
, OnShutdown());
691 host_
->Start(xmpp_login_
);
692 SimulateClientConnection(0, true, false);
696 TEST_F(ChromotingHostTest
, DisconnectAllClients
) {
697 ExpectHostAndSessionManagerStart();
698 Expectation video_packet_sent
= ExpectClientConnected(
699 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients
));
700 ExpectClientDisconnected(0, true, video_packet_sent
,
701 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
702 EXPECT_CALL(host_status_observer_
, OnShutdown());
704 host_
->Start(xmpp_login_
);
705 SimulateClientConnection(0, true, false);
709 } // namespace remoting