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())
173 // Helper method to pretend a client is connected to ChromotingHost.
174 void SimulateClientConnection(int connection_index
, bool authenticate
,
176 scoped_ptr
<protocol::ConnectionToClient
> connection
=
177 ((connection_index
== 0) ? owned_connection1_
: owned_connection2_
)
179 protocol::ConnectionToClient
* connection_ptr
= connection
.get();
180 scoped_ptr
<ClientSession
> client(new ClientSession(
182 task_runner_
, // Audio
183 task_runner_
, // Input
184 task_runner_
, // Video capture
185 task_runner_
, // Video encode
186 task_runner_
, // Network
189 desktop_environment_factory_
.get(),
192 std::vector
<HostExtension
*>()));
194 connection_ptr
->set_host_stub(client
.get());
197 task_runner_
->PostTask(
199 base::Bind(&ClientSession::OnConnectionAuthenticated
,
200 base::Unretained(client
.get()), connection_ptr
));
202 task_runner_
->PostTask(
204 base::Bind(&ClientSession::OnConnectionChannelsConnected
,
205 base::Unretained(client
.get()), connection_ptr
));
208 task_runner_
->PostTask(
209 FROM_HERE
, base::Bind(&ClientSession::OnConnectionClosed
,
210 base::Unretained(client
.get()), connection_ptr
,
211 protocol::AUTHENTICATION_FAILED
));
214 get_client(connection_index
) = client
.get();
216 // |host| is responsible for deleting |client| from now on.
217 host_
->clients_
.push_back(client
.release());
220 void TearDown() override
{
221 // Make sure that the host has been properly deleted.
222 DCHECK(host_
.get() == nullptr);
225 // Change the session route for |client1_|.
226 void ChangeSessionRoute(const std::string
& channel_name
,
227 const protocol::TransportRoute
& route
) {
228 host_
->OnSessionRouteChange(get_client(0), channel_name
, route
);
231 // Creates a DesktopEnvironment with a fake webrtc::DesktopCapturer, to mock
232 // DesktopEnvironmentFactory::Create().
233 DesktopEnvironment
* CreateDesktopEnvironment() {
234 MockDesktopEnvironment
* desktop_environment
= new MockDesktopEnvironment();
235 EXPECT_CALL(*desktop_environment
, CreateAudioCapturerPtr())
237 EXPECT_CALL(*desktop_environment
, CreateInputInjectorPtr())
239 .WillOnce(Invoke(this, &ChromotingHostTest::CreateInputInjector
));
240 EXPECT_CALL(*desktop_environment
, CreateScreenControlsPtr())
242 EXPECT_CALL(*desktop_environment
, CreateVideoCapturerPtr())
244 .WillOnce(Invoke(this, &ChromotingHostTest::CreateVideoCapturer
));
245 EXPECT_CALL(*desktop_environment
, CreateMouseCursorMonitorPtr())
247 .WillOnce(Invoke(this, &ChromotingHostTest::CreateMouseCursorMonitor
));
248 EXPECT_CALL(*desktop_environment
, GetCapabilities())
250 EXPECT_CALL(*desktop_environment
, SetCapabilities(_
))
253 return desktop_environment
;
256 // Creates a dummy InputInjector, to mock
257 // DesktopEnvironment::CreateInputInjector().
258 InputInjector
* CreateInputInjector() {
259 MockInputInjector
* input_injector
= new MockInputInjector();
260 EXPECT_CALL(*input_injector
, StartPtr(_
));
261 return input_injector
;
264 // Creates a fake webrtc::DesktopCapturer, to mock
265 // DesktopEnvironment::CreateVideoCapturer().
266 webrtc::DesktopCapturer
* CreateVideoCapturer() {
267 return new FakeDesktopCapturer();
270 // Creates a MockMouseCursorMonitor, to mock
271 // DesktopEnvironment::CreateMouseCursorMonitor().
272 webrtc::MouseCursorMonitor
* CreateMouseCursorMonitor() {
273 return new FakeMouseCursorMonitor();
276 void DisconnectAllClients() {
277 host_
->DisconnectAllClients();
280 // Helper method to disconnect client 1 from the host.
281 void DisconnectClient1() {
282 NotifyClientSessionClosed(0);
285 // Notify |host_| that the authenticating client has been rejected.
286 void RejectAuthenticatingClient() {
287 host_
->RejectAuthenticatingClient();
290 // Notify |host_| that a client session has closed.
291 void NotifyClientSessionClosed(int connection_index
) {
292 get_client(connection_index
)->OnConnectionClosed(
293 get_connection(connection_index
), protocol::OK
);
296 void NotifyConnectionClosed1() {
297 if (session_unowned1_event_handler_
) {
298 session_unowned1_event_handler_
->OnSessionStateChange(Session::CLOSED
);
302 void NotifyConnectionClosed2() {
303 if (session_unowned2_event_handler_
) {
304 session_unowned2_event_handler_
->OnSessionStateChange(Session::CLOSED
);
308 void ShutdownHost() {
309 task_runner_
->PostTask(
311 base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner
,
312 base::Unretained(this)));
315 void StopAndReleaseTaskRunner() {
317 task_runner_
= nullptr;
318 desktop_environment_factory_
.reset();
321 void QuitMainMessageLoop() {
322 PostQuitTask(&message_loop_
);
325 // Expect the host and session manager to start, and return the expectation
326 // that the session manager has started.
327 Expectation
ExpectHostAndSessionManagerStart() {
328 EXPECT_CALL(host_status_observer_
, OnStart(xmpp_login_
));
329 return EXPECT_CALL(*session_manager_
, Init(_
, host_
.get()));
332 // Expect a client to connect.
333 // Return an expectation that a session has started, and that the first
334 // video packet has been sent to the client.
335 // Do |action| when that happens.
337 Expectation
ExpectClientConnected(int connection_index
, A action
) {
338 const std::string
& session_jid
= get_session_jid(connection_index
);
339 MockVideoStub
& video_stub
= get_video_stub(connection_index
);
341 Expectation client_authenticated
=
342 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid
));
343 EXPECT_CALL(host_status_observer_
, OnClientConnected(session_jid
))
344 .After(client_authenticated
);
345 Expectation video_packet_sent
=
346 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
347 .After(client_authenticated
)
351 .RetiresOnSaturation();
352 EXPECT_CALL(video_stub
, ProcessVideoPacketPtr(_
, _
))
354 .After(video_packet_sent
)
355 .WillRepeatedly(RunDoneTask());
356 return video_packet_sent
;
359 // Return an expectation that a client will disconnect after a given
360 // expectation. The given action will be done after the event executor is
361 // notified that the session has finished.
363 Expectation
ExpectClientDisconnected(int connection_index
,
364 bool expect_host_status_change
,
367 MockConnectionToClient
* connection
= get_connection(connection_index
);
369 Expectation client_disconnected
=
370 EXPECT_CALL(*connection
, Disconnect())
372 .WillOnce(InvokeWithoutArgs(CreateFunctor(
373 this, &ChromotingHostTest::NotifyClientSessionClosed
,
375 .RetiresOnSaturation();
376 ExpectClientDisconnectEffects(connection_index
,
377 expect_host_status_change
,
380 return client_disconnected
;
383 // Expect the side-effects of a client disconnection, after a given
384 // expectation. The given action will be done after the event executor is
385 // notifed that the session has finished.
387 void ExpectClientDisconnectEffects(int connection_index
,
388 bool expect_host_status_change
,
391 const std::string
& session_jid
= get_session_jid(connection_index
);
393 if (expect_host_status_change
) {
394 EXPECT_CALL(host_status_observer_
, OnClientDisconnected(session_jid
))
397 .RetiresOnSaturation();
402 base::MessageLoop message_loop_
;
403 scoped_refptr
<AutoThreadTaskRunner
> task_runner_
;
404 MockConnectionToClientEventHandler handler_
;
405 MockSignalStrategy signal_strategy_
;
406 scoped_ptr
<MockDesktopEnvironmentFactory
> desktop_environment_factory_
;
407 scoped_ptr
<ChromotingHost
> host_
;
408 MockHostStatusObserver host_status_observer_
;
409 protocol::MockSessionManager
* session_manager_
;
410 std::string xmpp_login_
;
411 MockConnectionToClient
* connection1_
;
412 scoped_ptr
<MockConnectionToClient
> owned_connection1_
;
413 ClientSession
* client1_
;
414 std::string session_jid1_
;
415 MockSession
* session1_
; // Owned by |connection_|.
416 scoped_ptr
<SessionConfig
> session_config1_
;
417 MockVideoStub video_stub1_
;
418 MockClientStub client_stub1_
;
419 MockHostStub host_stub1_
;
420 MockConnectionToClient
* connection2_
;
421 scoped_ptr
<MockConnectionToClient
> owned_connection2_
;
422 ClientSession
* client2_
;
423 std::string session_jid2_
;
424 MockSession
* session2_
; // Owned by |connection2_|.
425 scoped_ptr
<SessionConfig
> session_config2_
;
426 MockVideoStub video_stub2_
;
427 MockClientStub client_stub2_
;
428 MockHostStub host_stub2_
;
429 scoped_ptr
<MockSession
> session_unowned1_
; // Not owned by a connection.
430 std::string session_unowned_jid1_
;
431 scoped_ptr
<MockSession
> session_unowned2_
; // Not owned by a connection.
432 std::string session_unowned_jid2_
;
433 protocol::Session::EventHandler
* session_unowned1_event_handler_
;
434 protocol::Session::EventHandler
* session_unowned2_event_handler_
;
436 MockConnectionToClient
*& get_connection(int connection_index
) {
437 return (connection_index
== 0) ? connection1_
: connection2_
;
440 // Returns the cached client pointers client1_ or client2_.
441 ClientSession
*& get_client(int connection_index
) {
442 return (connection_index
== 0) ? client1_
: client2_
;
445 // Returns the list of clients of the host_.
446 std::list
<ClientSession
*>& get_clients_from_host() {
447 return host_
->clients_
;
450 const std::string
& get_session_jid(int connection_index
) {
451 return (connection_index
== 0) ? session_jid1_
: session_jid2_
;
454 MockVideoStub
& get_video_stub(int connection_index
) {
455 return (connection_index
== 0) ? video_stub1_
: video_stub2_
;
459 TEST_F(ChromotingHostTest
, StartAndShutdown
) {
460 Expectation start
= ExpectHostAndSessionManagerStart();
461 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(start
);
463 host_
->Start(xmpp_login_
);
468 TEST_F(ChromotingHostTest
, Connect
) {
469 ExpectHostAndSessionManagerStart();
471 // Shut down the host when the first video packet is received.
472 Expectation video_packet_sent
= ExpectClientConnected(
473 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
474 Expectation client_disconnected
= ExpectClientDisconnected(
475 0, true, video_packet_sent
, InvokeWithoutArgs(base::DoNothing
));
476 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected
);
478 host_
->Start(xmpp_login_
);
479 SimulateClientConnection(0, true, false);
483 TEST_F(ChromotingHostTest
, RejectAuthenticatingClient
) {
484 Expectation start
= ExpectHostAndSessionManagerStart();
485 EXPECT_CALL(host_status_observer_
, OnClientAuthenticated(session_jid1_
))
486 .WillOnce(InvokeWithoutArgs(
487 this, &ChromotingHostTest::RejectAuthenticatingClient
));
488 ExpectClientDisconnected(
490 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
491 EXPECT_CALL(host_status_observer_
, OnShutdown());
493 host_
->Start(xmpp_login_
);
494 SimulateClientConnection(0, true, true);
498 TEST_F(ChromotingHostTest
, AuthenticationFailed
) {
499 ExpectHostAndSessionManagerStart();
500 EXPECT_CALL(host_status_observer_
, OnAccessDenied(session_jid1_
))
501 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
502 EXPECT_CALL(host_status_observer_
, OnShutdown());
504 host_
->Start(xmpp_login_
);
505 SimulateClientConnection(0, false, false);
509 TEST_F(ChromotingHostTest
, Reconnect
) {
510 ExpectHostAndSessionManagerStart();
512 // When a video packet is received on the first connection, disconnect it,
513 // then quit the message loop.
514 Expectation video_packet_sent1
= ExpectClientConnected(0, DoAll(
515 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1
),
516 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop
)));
517 ExpectClientDisconnectEffects(
518 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
520 // When a video packet is received on the second connection, shut down the
522 Expectation video_packet_sent2
= ExpectClientConnected(
523 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
524 Expectation client_disconnected2
= ExpectClientDisconnected(
525 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
526 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
528 host_
->Start(xmpp_login_
);
529 SimulateClientConnection(0, true, false);
531 SimulateClientConnection(1, true, false);
535 TEST_F(ChromotingHostTest
, ConnectWhenAnotherClientIsConnected
) {
536 ExpectHostAndSessionManagerStart();
538 // When a video packet is received, connect the second connection.
539 // This should disconnect the first connection.
540 Expectation video_packet_sent1
= ExpectClientConnected(
545 &ChromotingHostTest::SimulateClientConnection
, 1, true, false)));
546 ExpectClientDisconnected(
547 0, true, video_packet_sent1
, InvokeWithoutArgs(base::DoNothing
));
548 Expectation video_packet_sent2
= ExpectClientConnected(
549 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
550 Expectation client_disconnected2
= ExpectClientDisconnected(
551 1, true, video_packet_sent2
, InvokeWithoutArgs(base::DoNothing
));
552 EXPECT_CALL(host_status_observer_
, OnShutdown()).After(client_disconnected2
);
554 host_
->Start(xmpp_login_
);
555 SimulateClientConnection(0, true, false);
559 TEST_F(ChromotingHostTest
, IncomingSessionDeclined
) {
560 protocol::SessionManager::IncomingSessionResponse response
=
561 protocol::SessionManager::ACCEPT
;
562 host_
->OnIncomingSession(session1_
, &response
);
563 EXPECT_EQ(protocol::SessionManager::DECLINE
, response
);
569 TEST_F(ChromotingHostTest
, IncomingSessionAccepted
) {
570 ExpectHostAndSessionManagerStart();
571 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(InvokeWithoutArgs(
572 this, &ChromotingHostTest::NotifyConnectionClosed1
));
573 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
574 EXPECT_CALL(host_status_observer_
, OnShutdown());
576 host_
->Start(xmpp_login_
);
578 protocol::SessionManager::IncomingSessionResponse response
=
579 protocol::SessionManager::DECLINE
;
580 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
581 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
587 TEST_F(ChromotingHostTest
, LoginBackOffUponConnection
) {
588 ExpectHostAndSessionManagerStart();
589 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
590 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
591 EXPECT_CALL(host_status_observer_
, OnAccessDenied(_
));
592 EXPECT_CALL(host_status_observer_
, OnShutdown());
594 host_
->Start(xmpp_login_
);
596 protocol::SessionManager::IncomingSessionResponse response
=
597 protocol::SessionManager::DECLINE
;
599 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
600 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
602 host_
->OnSessionAuthenticating(get_clients_from_host().front());
603 host_
->OnIncomingSession(session_unowned2_
.get(), &response
);
604 EXPECT_EQ(protocol::SessionManager::OVERLOAD
, response
);
610 TEST_F(ChromotingHostTest
, LoginBackOffUponAuthenticating
) {
611 Expectation start
= ExpectHostAndSessionManagerStart();
612 EXPECT_CALL(*session_unowned1_
, Close()).WillOnce(
613 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed1
));
615 EXPECT_CALL(*session_unowned2_
, Close()).WillOnce(
616 InvokeWithoutArgs(this, &ChromotingHostTest::NotifyConnectionClosed2
));
618 EXPECT_CALL(host_status_observer_
, OnShutdown());
620 host_
->Start(xmpp_login_
);
622 protocol::SessionManager::IncomingSessionResponse response
=
623 protocol::SessionManager::DECLINE
;
625 host_
->OnIncomingSession(session_unowned1_
.release(), &response
);
626 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
628 host_
->OnIncomingSession(session_unowned2_
.release(), &response
);
629 EXPECT_EQ(protocol::SessionManager::ACCEPT
, response
);
631 // This will set the backoff.
632 host_
->OnSessionAuthenticating(get_clients_from_host().front());
634 // This should disconnect client2.
635 host_
->OnSessionAuthenticating(get_clients_from_host().back());
637 // Verify that the host only has 1 client at this point.
638 EXPECT_EQ(get_clients_from_host().size(), 1U);
644 TEST_F(ChromotingHostTest
, OnSessionRouteChange
) {
645 std::string
channel_name("ChannelName");
646 protocol::TransportRoute route
;
648 ExpectHostAndSessionManagerStart();
649 Expectation video_packet_sent
= ExpectClientConnected(
650 0, InvokeWithoutArgs(CreateFunctor(
651 this, &ChromotingHostTest::ChangeSessionRoute
, channel_name
, route
)));
652 Expectation route_change
=
653 EXPECT_CALL(host_status_observer_
, OnClientRouteChange(
654 session_jid1_
, channel_name
, _
))
655 .After(video_packet_sent
)
656 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
657 ExpectClientDisconnected(0, true, route_change
,
658 InvokeWithoutArgs(base::DoNothing
));
659 EXPECT_CALL(host_status_observer_
, OnShutdown());
661 host_
->Start(xmpp_login_
);
662 SimulateClientConnection(0, true, false);
666 TEST_F(ChromotingHostTest
, DisconnectAllClients
) {
667 ExpectHostAndSessionManagerStart();
668 Expectation video_packet_sent
= ExpectClientConnected(
669 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients
));
670 ExpectClientDisconnected(0, true, video_packet_sent
,
671 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost
));
672 EXPECT_CALL(host_status_observer_
, OnShutdown());
674 host_
->Start(xmpp_login_
);
675 SimulateClientConnection(0, true, false);
679 } // namespace remoting