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.
4
5 #include "base/bind.h"
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"
24
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::SessionConfig;
32
33 using testing::_;
34 using testing::AnyNumber;
35 using testing::AtMost;
36 using testing::AtLeast;
37 using testing::CreateFunctor;
38 using testing::DeleteArg;
39 using testing::DoAll;
40 using testing::Expectation;
41 using testing::InSequence;
42 using testing::Invoke;
43 using testing::InvokeArgument;
44 using testing::InvokeWithoutArgs;
45 using testing::Return;
46 using testing::ReturnRef;
47 using testing::Sequence;
48
49 namespace remoting {
50
51 namespace {
52
PostQuitTask(base::MessageLoop * message_loop)53 void PostQuitTask(base::MessageLoop* message_loop) {
54 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
55 }
56
57 // Run the task and delete it afterwards. This action is used to deal with
58 // done callbacks.
ACTION(RunDoneTask)59 ACTION(RunDoneTask) {
60 arg1.Run();
61 }
62
63 } // namespace
64
65 class ChromotingHostTest : public testing::Test {
66 public:
ChromotingHostTest()67 ChromotingHostTest() {
68 }
69
SetUp()70 virtual void SetUp() OVERRIDE {
71 task_runner_ = new AutoThreadTaskRunner(
72 message_loop_.message_loop_proxy(),
73 base::Bind(&ChromotingHostTest::QuitMainMessageLoop,
74 base::Unretained(this)));
75
76 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory());
77 EXPECT_CALL(*desktop_environment_factory_, CreatePtr())
78 .Times(AnyNumber())
79 .WillRepeatedly(Invoke(this,
80 &ChromotingHostTest::CreateDesktopEnvironment));
81 EXPECT_CALL(*desktop_environment_factory_, SupportsAudioCapture())
82 .Times(AnyNumber())
83 .WillRepeatedly(Return(false));
84
85 session_manager_ = new protocol::MockSessionManager();
86
87 host_.reset(new ChromotingHost(
88 &signal_strategy_,
89 desktop_environment_factory_.get(),
90 scoped_ptr<protocol::SessionManager>(session_manager_),
91 task_runner_, // Audio
92 task_runner_, // Input
93 task_runner_, // Video capture
94 task_runner_, // Video encode
95 task_runner_, // Network
96 task_runner_)); // UI
97 host_->AddStatusObserver(&host_status_observer_);
98
99 xmpp_login_ = "host@domain";
100 session1_ = new MockSession();
101 session2_ = new MockSession();
102 session_unowned1_.reset(new MockSession());
103 session_unowned2_.reset(new MockSession());
104 session_config1_ = SessionConfig::ForTest();
105 session_jid1_ = "user@domain/rest-of-jid";
106 session_config2_ = SessionConfig::ForTest();
107 session_jid2_ = "user2@domain/rest-of-jid";
108 session_unowned_config1_ = SessionConfig::ForTest();
109 session_unowned_jid1_ = "user3@doman/rest-of-jid";
110 session_unowned_config2_ = SessionConfig::ForTest();
111 session_unowned_jid2_ = "user4@doman/rest-of-jid";
112
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(_))
122 .Times(AnyNumber());
123 EXPECT_CALL(*session2_, SetEventHandler(_))
124 .Times(AnyNumber());
125 EXPECT_CALL(*session_unowned1_, SetEventHandler(_))
126 .Times(AnyNumber())
127 .WillRepeatedly(Invoke(this, &ChromotingHostTest::SetEventHandler));
128 EXPECT_CALL(*session_unowned2_, SetEventHandler(_))
129 .Times(AnyNumber());
130 EXPECT_CALL(*session1_, config())
131 .WillRepeatedly(ReturnRef(session_config1_));
132 EXPECT_CALL(*session2_, config())
133 .WillRepeatedly(ReturnRef(session_config2_));
134
135 owned_connection1_.reset(new MockConnectionToClient(session1_,
136 &host_stub1_));
137 connection1_ = owned_connection1_.get();
138 owned_connection2_.reset(new MockConnectionToClient(session2_,
139 &host_stub2_));
140 connection2_ = owned_connection2_.get();
141
142 ON_CALL(video_stub1_, ProcessVideoPacketPtr(_, _))
143 .WillByDefault(DeleteArg<0>());
144 ON_CALL(video_stub2_, ProcessVideoPacketPtr(_, _))
145 .WillByDefault(DeleteArg<0>());
146 ON_CALL(*connection1_, video_stub())
147 .WillByDefault(Return(&video_stub1_));
148 ON_CALL(*connection1_, client_stub())
149 .WillByDefault(Return(&client_stub1_));
150 ON_CALL(*connection1_, session())
151 .WillByDefault(Return(session1_));
152 ON_CALL(*connection2_, video_stub())
153 .WillByDefault(Return(&video_stub2_));
154 ON_CALL(*connection2_, client_stub())
155 .WillByDefault(Return(&client_stub2_));
156 ON_CALL(*connection2_, session())
157 .WillByDefault(Return(session2_));
158 EXPECT_CALL(*connection1_, video_stub())
159 .Times(AnyNumber());
160 EXPECT_CALL(*connection1_, client_stub())
161 .Times(AnyNumber());
162 EXPECT_CALL(*connection1_, session())
163 .Times(AnyNumber());
164 EXPECT_CALL(*connection2_, video_stub())
165 .Times(AnyNumber());
166 EXPECT_CALL(*connection2_, client_stub())
167 .Times(AnyNumber());
168 EXPECT_CALL(*connection2_, session())
169 .Times(AnyNumber());
170
171 empty_candidate_config_ =
172 protocol::CandidateSessionConfig::CreateEmpty();
173 default_candidate_config_ =
174 protocol::CandidateSessionConfig::CreateDefault();
175 }
176
177 // Helper method to pretend a client is connected to ChromotingHost.
SimulateClientConnection(int connection_index,bool authenticate,bool reject)178 void SimulateClientConnection(int connection_index, bool authenticate,
179 bool reject) {
180 scoped_ptr<protocol::ConnectionToClient> connection =
181 ((connection_index == 0) ? owned_connection1_ : owned_connection2_).
182 PassAs<protocol::ConnectionToClient>();
183 protocol::ConnectionToClient* connection_ptr = connection.get();
184 scoped_ptr<ClientSession> client(new ClientSession(
185 host_.get(),
186 task_runner_, // Audio
187 task_runner_, // Input
188 task_runner_, // Video capture
189 task_runner_, // Video encode
190 task_runner_, // Network
191 task_runner_, // UI
192 connection.Pass(),
193 desktop_environment_factory_.get(),
194 base::TimeDelta(),
195 NULL));
196
197 connection_ptr->set_host_stub(client.get());
198
199 if (authenticate) {
200 task_runner_->PostTask(
201 FROM_HERE,
202 base::Bind(&ClientSession::OnConnectionAuthenticated,
203 base::Unretained(client.get()), connection_ptr));
204 if (!reject) {
205 task_runner_->PostTask(
206 FROM_HERE,
207 base::Bind(&ClientSession::OnConnectionChannelsConnected,
208 base::Unretained(client.get()), connection_ptr));
209 }
210 } else {
211 task_runner_->PostTask(
212 FROM_HERE, base::Bind(&ClientSession::OnConnectionClosed,
213 base::Unretained(client.get()), connection_ptr,
214 protocol::AUTHENTICATION_FAILED));
215 }
216
217 get_client(connection_index) = client.get();
218
219 // |host| is responsible for deleting |client| from now on.
220 host_->clients_.push_back(client.release());
221 }
222
TearDown()223 virtual void TearDown() OVERRIDE {
224 // Make sure that the host has been properly deleted.
225 DCHECK(host_.get() == NULL);
226 }
227
228 // Change the session route for |client1_|.
ChangeSessionRoute(const std::string & channel_name,const protocol::TransportRoute & route)229 void ChangeSessionRoute(const std::string& channel_name,
230 const protocol::TransportRoute& route) {
231 host_->OnSessionRouteChange(get_client(0), channel_name, route);
232 }
233
234 // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock
235 // DesktopEnvironmentFactory::Create().
CreateDesktopEnvironment()236 DesktopEnvironment* CreateDesktopEnvironment() {
237 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
238 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr())
239 .Times(0);
240 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr())
241 .Times(AtMost(1))
242 .WillOnce(Invoke(this, &ChromotingHostTest::CreateInputInjector));
243 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr())
244 .Times(AtMost(1));
245 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr())
246 .Times(AtMost(1))
247 .WillOnce(Invoke(this, &ChromotingHostTest::CreateVideoCapturer));
248 EXPECT_CALL(*desktop_environment, GetCapabilities())
249 .Times(AtMost(1));
250 EXPECT_CALL(*desktop_environment, SetCapabilities(_))
251 .Times(AtMost(1));
252
253 return desktop_environment;
254 }
255
256 // Creates a dummy InputInjector, to mock
257 // DesktopEnvironment::CreateInputInjector().
CreateInputInjector()258 InputInjector* CreateInputInjector() {
259 MockInputInjector* input_injector = new MockInputInjector();
260 EXPECT_CALL(*input_injector, StartPtr(_));
261 return input_injector;
262 }
263
264 // Creates a fake webrtc::ScreenCapturer, to mock
265 // DesktopEnvironment::CreateVideoCapturer().
CreateVideoCapturer()266 webrtc::ScreenCapturer* CreateVideoCapturer() {
267 return new ScreenCapturerFake();
268 }
269
DisconnectAllClients()270 void DisconnectAllClients() {
271 host_->DisconnectAllClients();
272 }
273
274 // Helper method to disconnect client 1 from the host.
DisconnectClient1()275 void DisconnectClient1() {
276 NotifyClientSessionClosed(0);
277 }
278
279 // Notify |host_| that the authenticating client has been rejected.
RejectAuthenticatingClient()280 void RejectAuthenticatingClient() {
281 host_->RejectAuthenticatingClient();
282 }
283
284 // Notify |host_| that a client session has closed.
NotifyClientSessionClosed(int connection_index)285 void NotifyClientSessionClosed(int connection_index) {
286 get_client(connection_index)->OnConnectionClosed(
287 get_connection(connection_index), protocol::OK);
288 }
289
SetEventHandler(protocol::Session::EventHandler * event_handler)290 void SetEventHandler(protocol::Session::EventHandler* event_handler) {
291 session_event_handler_ = event_handler;
292 }
293
NotifyConnectionClosed()294 void NotifyConnectionClosed() {
295 if (session_event_handler_) {
296 session_event_handler_->OnSessionStateChange(protocol::Session::CLOSED);
297 }
298 }
299
ShutdownHost()300 void ShutdownHost() {
301 task_runner_->PostTask(
302 FROM_HERE,
303 base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner,
304 base::Unretained(this)));
305 }
306
StopAndReleaseTaskRunner()307 void StopAndReleaseTaskRunner() {
308 host_.reset();
309 task_runner_ = NULL;
310 desktop_environment_factory_.reset();
311 }
312
QuitMainMessageLoop()313 void QuitMainMessageLoop() {
314 PostQuitTask(&message_loop_);
315 }
316
317 // Expect the host and session manager to start, and return the expectation
318 // that the session manager has started.
ExpectHostAndSessionManagerStart()319 Expectation ExpectHostAndSessionManagerStart() {
320 EXPECT_CALL(host_status_observer_, OnStart(xmpp_login_));
321 return EXPECT_CALL(*session_manager_, Init(_, host_.get()));
322 }
323
324 // Expect a client to connect.
325 // Return an expectation that a session has started, and that the first
326 // video packet has been sent to the client.
327 // Do |action| when that happens.
328 template <class A>
ExpectClientConnected(int connection_index,A action)329 Expectation ExpectClientConnected(int connection_index, A action) {
330 const std::string& session_jid = get_session_jid(connection_index);
331 MockVideoStub& video_stub = get_video_stub(connection_index);
332
333 Expectation client_authenticated =
334 EXPECT_CALL(host_status_observer_, OnClientAuthenticated(session_jid));
335 EXPECT_CALL(host_status_observer_, OnClientConnected(session_jid))
336 .After(client_authenticated);
337 Expectation video_packet_sent =
338 EXPECT_CALL(video_stub, ProcessVideoPacketPtr(_, _))
339 .After(client_authenticated)
340 .WillOnce(DoAll(
341 action,
342 RunDoneTask()))
343 .RetiresOnSaturation();
344 EXPECT_CALL(video_stub, ProcessVideoPacketPtr(_, _))
345 .Times(AnyNumber())
346 .After(video_packet_sent)
347 .WillRepeatedly(RunDoneTask());
348 return video_packet_sent;
349 }
350
351 // Return an expectation that a client will disconnect after a given
352 // expectation. The given action will be done after the event executor is
353 // notified that the session has finished.
354 template <class A>
ExpectClientDisconnected(int connection_index,bool expect_host_status_change,Expectation after,A action)355 Expectation ExpectClientDisconnected(int connection_index,
356 bool expect_host_status_change,
357 Expectation after,
358 A action) {
359 MockConnectionToClient* connection = get_connection(connection_index);
360
361 Expectation client_disconnected =
362 EXPECT_CALL(*connection, Disconnect())
363 .After(after)
364 .WillOnce(InvokeWithoutArgs(CreateFunctor(
365 this, &ChromotingHostTest::NotifyClientSessionClosed,
366 connection_index)))
367 .RetiresOnSaturation();
368 ExpectClientDisconnectEffects(connection_index,
369 expect_host_status_change,
370 after,
371 action);
372 return client_disconnected;
373 }
374
375 // Expect the side-effects of a client disconnection, after a given
376 // expectation. The given action will be done after the event executor is
377 // notifed that the session has finished.
378 template <class A>
ExpectClientDisconnectEffects(int connection_index,bool expect_host_status_change,Expectation after,A action)379 void ExpectClientDisconnectEffects(int connection_index,
380 bool expect_host_status_change,
381 Expectation after,
382 A action) {
383 const std::string& session_jid = get_session_jid(connection_index);
384
385 if (expect_host_status_change) {
386 EXPECT_CALL(host_status_observer_, OnClientDisconnected(session_jid))
387 .After(after)
388 .WillOnce(action)
389 .RetiresOnSaturation();
390 }
391 }
392
393 protected:
394 base::MessageLoop message_loop_;
395 scoped_refptr<AutoThreadTaskRunner> task_runner_;
396 MockConnectionToClientEventHandler handler_;
397 MockSignalStrategy signal_strategy_;
398 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_;
399 scoped_ptr<ChromotingHost> host_;
400 MockHostStatusObserver host_status_observer_;
401 protocol::MockSessionManager* session_manager_;
402 std::string xmpp_login_;
403 MockConnectionToClient* connection1_;
404 scoped_ptr<MockConnectionToClient> owned_connection1_;
405 ClientSession* client1_;
406 std::string session_jid1_;
407 MockSession* session1_; // Owned by |connection_|.
408 SessionConfig session_config1_;
409 MockVideoStub video_stub1_;
410 MockClientStub client_stub1_;
411 MockHostStub host_stub1_;
412 MockConnectionToClient* connection2_;
413 scoped_ptr<MockConnectionToClient> owned_connection2_;
414 ClientSession* client2_;
415 std::string session_jid2_;
416 MockSession* session2_; // Owned by |connection2_|.
417 SessionConfig session_config2_;
418 MockVideoStub video_stub2_;
419 MockClientStub client_stub2_;
420 MockHostStub host_stub2_;
421 scoped_ptr<MockSession> session_unowned1_; // Not owned by a connection.
422 SessionConfig session_unowned_config1_;
423 std::string session_unowned_jid1_;
424 scoped_ptr<MockSession> session_unowned2_; // Not owned by a connection.
425 SessionConfig session_unowned_config2_;
426 std::string session_unowned_jid2_;
427 protocol::Session::EventHandler* session_event_handler_;
428 scoped_ptr<protocol::CandidateSessionConfig> empty_candidate_config_;
429 scoped_ptr<protocol::CandidateSessionConfig> default_candidate_config_;
430
get_connection(int connection_index)431 MockConnectionToClient*& get_connection(int connection_index) {
432 return (connection_index == 0) ? connection1_ : connection2_;
433 }
434
get_client(int connection_index)435 ClientSession*& get_client(int connection_index) {
436 return (connection_index == 0) ? client1_ : client2_;
437 }
438
get_session_jid(int connection_index)439 const std::string& get_session_jid(int connection_index) {
440 return (connection_index == 0) ? session_jid1_ : session_jid2_;
441 }
442
get_video_stub(int connection_index)443 MockVideoStub& get_video_stub(int connection_index) {
444 return (connection_index == 0) ? video_stub1_ : video_stub2_;
445 }
446 };
447
TEST_F(ChromotingHostTest,StartAndShutdown)448 TEST_F(ChromotingHostTest, StartAndShutdown) {
449 Expectation start = ExpectHostAndSessionManagerStart();
450 EXPECT_CALL(host_status_observer_, OnShutdown()).After(start);
451
452 host_->Start(xmpp_login_);
453 ShutdownHost();
454 message_loop_.Run();
455 }
456
TEST_F(ChromotingHostTest,Connect)457 TEST_F(ChromotingHostTest, Connect) {
458 ExpectHostAndSessionManagerStart();
459
460 // Shut down the host when the first video packet is received.
461 Expectation video_packet_sent = ExpectClientConnected(
462 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
463 Expectation client_disconnected = ExpectClientDisconnected(
464 0, true, video_packet_sent, InvokeWithoutArgs(base::DoNothing));
465 EXPECT_CALL(host_status_observer_, OnShutdown()).After(client_disconnected);
466
467 host_->Start(xmpp_login_);
468 SimulateClientConnection(0, true, false);
469 message_loop_.Run();
470 }
471
TEST_F(ChromotingHostTest,RejectAuthenticatingClient)472 TEST_F(ChromotingHostTest, RejectAuthenticatingClient) {
473 Expectation start = ExpectHostAndSessionManagerStart();
474 EXPECT_CALL(host_status_observer_, OnClientAuthenticated(session_jid1_))
475 .WillOnce(InvokeWithoutArgs(
476 this, &ChromotingHostTest::RejectAuthenticatingClient));
477 ExpectClientDisconnected(
478 0, true, start,
479 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
480 EXPECT_CALL(host_status_observer_, OnShutdown());
481
482 host_->Start(xmpp_login_);
483 SimulateClientConnection(0, true, true);
484 message_loop_.Run();
485 }
486
TEST_F(ChromotingHostTest,AuthenticationFailed)487 TEST_F(ChromotingHostTest, AuthenticationFailed) {
488 ExpectHostAndSessionManagerStart();
489 EXPECT_CALL(host_status_observer_, OnAccessDenied(session_jid1_))
490 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
491 EXPECT_CALL(host_status_observer_, OnShutdown());
492
493 host_->Start(xmpp_login_);
494 SimulateClientConnection(0, false, false);
495 message_loop_.Run();
496 }
497
TEST_F(ChromotingHostTest,Reconnect)498 TEST_F(ChromotingHostTest, Reconnect) {
499 ExpectHostAndSessionManagerStart();
500
501 // When a video packet is received on the first connection, disconnect it,
502 // then quit the message loop.
503 Expectation video_packet_sent1 = ExpectClientConnected(0, DoAll(
504 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1),
505 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop)));
506 ExpectClientDisconnectEffects(
507 0, true, video_packet_sent1, InvokeWithoutArgs(base::DoNothing));
508
509 // When a video packet is received on the second connection, shut down the
510 // host.
511 Expectation video_packet_sent2 = ExpectClientConnected(
512 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
513 Expectation client_disconnected2 = ExpectClientDisconnected(
514 1, true, video_packet_sent2, InvokeWithoutArgs(base::DoNothing));
515 EXPECT_CALL(host_status_observer_, OnShutdown()).After(client_disconnected2);
516
517 host_->Start(xmpp_login_);
518 SimulateClientConnection(0, true, false);
519 message_loop_.Run();
520 SimulateClientConnection(1, true, false);
521 message_loop_.Run();
522 }
523
TEST_F(ChromotingHostTest,ConnectWhenAnotherClientIsConnected)524 TEST_F(ChromotingHostTest, ConnectWhenAnotherClientIsConnected) {
525 ExpectHostAndSessionManagerStart();
526
527 // When a video packet is received, connect the second connection.
528 // This should disconnect the first connection.
529 Expectation video_packet_sent1 = ExpectClientConnected(
530 0,
531 InvokeWithoutArgs(
532 CreateFunctor(
533 this,
534 &ChromotingHostTest::SimulateClientConnection, 1, true, false)));
535 ExpectClientDisconnected(
536 0, true, video_packet_sent1, InvokeWithoutArgs(base::DoNothing));
537 Expectation video_packet_sent2 = ExpectClientConnected(
538 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
539 Expectation client_disconnected2 = ExpectClientDisconnected(
540 1, true, video_packet_sent2, InvokeWithoutArgs(base::DoNothing));
541 EXPECT_CALL(host_status_observer_, OnShutdown()).After(client_disconnected2);
542
543 host_->Start(xmpp_login_);
544 SimulateClientConnection(0, true, false);
545 message_loop_.Run();
546 }
547
TEST_F(ChromotingHostTest,IncomingSessionDeclined)548 TEST_F(ChromotingHostTest, IncomingSessionDeclined) {
549 protocol::SessionManager::IncomingSessionResponse response =
550 protocol::SessionManager::ACCEPT;
551 host_->OnIncomingSession(session1_, &response);
552 EXPECT_EQ(protocol::SessionManager::DECLINE, response);
553
554 ShutdownHost();
555 message_loop_.Run();
556 }
557
TEST_F(ChromotingHostTest,IncomingSessionIncompatible)558 TEST_F(ChromotingHostTest, IncomingSessionIncompatible) {
559 ExpectHostAndSessionManagerStart();
560 EXPECT_CALL(*session_unowned1_, candidate_config()).WillOnce(Return(
561 empty_candidate_config_.get()));
562 EXPECT_CALL(host_status_observer_, OnShutdown());
563
564 host_->Start(xmpp_login_);
565
566 protocol::SessionManager::IncomingSessionResponse response =
567 protocol::SessionManager::ACCEPT;
568 host_->OnIncomingSession(session_unowned1_.get(), &response);
569 EXPECT_EQ(protocol::SessionManager::INCOMPATIBLE, response);
570
571 ShutdownHost();
572 message_loop_.Run();
573 }
574
TEST_F(ChromotingHostTest,IncomingSessionAccepted)575 TEST_F(ChromotingHostTest, IncomingSessionAccepted) {
576 ExpectHostAndSessionManagerStart();
577 EXPECT_CALL(*session_unowned1_, candidate_config()).WillOnce(Return(
578 default_candidate_config_.get()));
579 EXPECT_CALL(*session_unowned1_, set_config(_));
580 EXPECT_CALL(*session_unowned1_, Close()).WillOnce(InvokeWithoutArgs(
581 this, &ChromotingHostTest::NotifyConnectionClosed));
582 EXPECT_CALL(host_status_observer_, OnAccessDenied(_));
583 EXPECT_CALL(host_status_observer_, OnShutdown());
584
585 host_->Start(xmpp_login_);
586
587 protocol::SessionManager::IncomingSessionResponse response =
588 protocol::SessionManager::DECLINE;
589 host_->OnIncomingSession(session_unowned1_.release(), &response);
590 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
591
592 ShutdownHost();
593 message_loop_.Run();
594 }
595
TEST_F(ChromotingHostTest,IncomingSessionOverload)596 TEST_F(ChromotingHostTest, IncomingSessionOverload) {
597 ExpectHostAndSessionManagerStart();
598 EXPECT_CALL(*session_unowned1_, candidate_config()).WillOnce(Return(
599 default_candidate_config_.get()));
600 EXPECT_CALL(*session_unowned1_, set_config(_));
601 EXPECT_CALL(*session_unowned1_, Close()).WillOnce(InvokeWithoutArgs(
602 this, &ChromotingHostTest::NotifyConnectionClosed));
603 EXPECT_CALL(host_status_observer_, OnAccessDenied(_));
604 EXPECT_CALL(host_status_observer_, OnShutdown());
605
606 host_->Start(xmpp_login_);
607
608 protocol::SessionManager::IncomingSessionResponse response =
609 protocol::SessionManager::DECLINE;
610 host_->OnIncomingSession(session_unowned1_.release(), &response);
611 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
612
613 host_->OnIncomingSession(session_unowned2_.get(), &response);
614 EXPECT_EQ(protocol::SessionManager::OVERLOAD, response);
615
616 ShutdownHost();
617 message_loop_.Run();
618 }
619
TEST_F(ChromotingHostTest,OnSessionRouteChange)620 TEST_F(ChromotingHostTest, OnSessionRouteChange) {
621 std::string channel_name("ChannelName");
622 protocol::TransportRoute route;
623
624 ExpectHostAndSessionManagerStart();
625 Expectation video_packet_sent = ExpectClientConnected(
626 0, InvokeWithoutArgs(CreateFunctor(
627 this, &ChromotingHostTest::ChangeSessionRoute, channel_name, route)));
628 Expectation route_change =
629 EXPECT_CALL(host_status_observer_, OnClientRouteChange(
630 session_jid1_, channel_name, _))
631 .After(video_packet_sent)
632 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
633 ExpectClientDisconnected(0, true, route_change,
634 InvokeWithoutArgs(base::DoNothing));
635 EXPECT_CALL(host_status_observer_, OnShutdown());
636
637 host_->Start(xmpp_login_);
638 SimulateClientConnection(0, true, false);
639 message_loop_.Run();
640 }
641
TEST_F(ChromotingHostTest,DisconnectAllClients)642 TEST_F(ChromotingHostTest, DisconnectAllClients) {
643 ExpectHostAndSessionManagerStart();
644 Expectation video_packet_sent = ExpectClientConnected(
645 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients));
646 ExpectClientDisconnected(0, true, video_packet_sent,
647 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
648 EXPECT_CALL(host_status_observer_, OnShutdown());
649
650 host_->Start(xmpp_login_);
651 SimulateClientConnection(0, true, false);
652 message_loop_.Run();
653 }
654
655 } // namespace remoting
656