blob: 56a0b0adbb5e119fb0b29707c978d7a4fd842c0e [file] [log] [blame]
[email protected]988dfc3c2012-01-04 01:10:111// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]1e72daa2011-01-28 21:25:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4ea2c7c2011-03-31 14:20:065#include "base/bind.h"
[email protected]54857072012-11-15 06:34:226#include "base/bind_helpers.h"
[email protected]e57a7162011-06-15 04:14:237#include "base/memory/scoped_ptr.h"
[email protected]60fc96002011-08-12 23:07:058#include "base/message_loop_proxy.h"
[email protected]170cba42012-09-12 22:28:399#include "remoting/base/auto_thread_task_runner.h"
[email protected]420a5e42012-12-18 21:42:1210#include "remoting/capturer/video_frame_capturer_fake.h"
[email protected]677bb0a2012-07-13 19:38:0711#include "remoting/host/audio_capturer.h"
[email protected]8450ac32012-07-19 20:16:0312#include "remoting/host/chromoting_host.h"
[email protected]420a5e42012-12-18 21:42:1213#include "remoting/host/chromoting_host_context.h"
[email protected]170cba42012-09-12 22:28:3914#include "remoting/host/desktop_environment.h"
[email protected]0a071a32011-02-08 00:18:2415#include "remoting/host/host_mock_objects.h"
[email protected]856dec52011-12-01 04:25:2616#include "remoting/host/it2me_host_user_interface.h"
[email protected]420a5e42012-12-18 21:42:1217#include "remoting/jingle_glue/mock_objects.h"
[email protected]1e72daa2011-01-28 21:25:4218#include "remoting/proto/video.pb.h"
[email protected]d317a25a2012-06-26 22:58:3019#include "remoting/protocol/errors.h"
[email protected]0a071a32011-02-08 00:18:2420#include "remoting/protocol/protocol_mock_objects.h"
[email protected]1e72daa2011-01-28 21:25:4221#include "remoting/protocol/session_config.h"
[email protected]44f60762011-03-23 12:13:3522#include "testing/gmock_mutant.h"
[email protected]1e72daa2011-01-28 21:25:4223#include "testing/gmock/include/gmock/gmock.h"
24#include "testing/gtest/include/gtest/gtest.h"
25
[email protected]f0a9d1b2011-03-04 21:31:4426using ::remoting::protocol::MockClientStub;
27using ::remoting::protocol::MockConnectionToClient;
28using ::remoting::protocol::MockConnectionToClientEventHandler;
29using ::remoting::protocol::MockHostStub;
[email protected]f0a9d1b2011-03-04 21:31:4430using ::remoting::protocol::MockSession;
31using ::remoting::protocol::MockVideoStub;
32using ::remoting::protocol::SessionConfig;
33
[email protected]1e72daa2011-01-28 21:25:4234using testing::_;
35using testing::AnyNumber;
[email protected]37961b12011-03-30 12:39:0036using testing::AtLeast;
[email protected]44f60762011-03-23 12:13:3537using testing::CreateFunctor;
[email protected]1e72daa2011-01-28 21:25:4238using testing::DeleteArg;
39using testing::DoAll;
[email protected]db638312012-06-20 00:41:3240using testing::Expectation;
[email protected]1e72daa2011-01-28 21:25:4241using testing::InSequence;
[email protected]d2a6c96f2012-06-29 19:19:1942using testing::Invoke;
[email protected]ec6411872011-11-11 03:28:5543using testing::InvokeArgument;
[email protected]1e72daa2011-01-28 21:25:4244using testing::InvokeWithoutArgs;
45using testing::Return;
[email protected]f41095f82011-06-07 16:57:4446using testing::ReturnRef;
[email protected]37961b12011-03-30 12:39:0047using testing::Sequence;
[email protected]1e72daa2011-01-28 21:25:4248
49namespace remoting {
50
51namespace {
52
53void PostQuitTask(MessageLoop* message_loop) {
[email protected]b9a514dd2011-12-09 04:02:5654 message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
[email protected]1e72daa2011-01-28 21:25:4255}
56
57// Run the task and delete it afterwards. This action is used to deal with
58// done callbacks.
59ACTION(RunDoneTask) {
[email protected]9e2a3132011-10-07 05:07:4060 arg1.Run();
[email protected]1e72daa2011-01-28 21:25:4261}
62
[email protected]44f60762011-03-23 12:13:3563} // namespace
[email protected]1e72daa2011-01-28 21:25:4264
[email protected]b9deda22012-10-18 23:30:3665class MockIt2MeHostUserInterface : public It2MeHostUserInterface {
66 public:
67 MockIt2MeHostUserInterface(
68 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
69 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
70
71 void InitFrom(
72 scoped_ptr<DisconnectWindow> disconnect_window,
73 scoped_ptr<ContinueWindow> continue_window,
74 scoped_ptr<LocalInputMonitor> local_input_monitor);
75
76 // A test-only version of Start that does not register a HostStatusObserver.
77 // TODO(rmsousa): Make the unit tests work with the regular Start().
78 virtual void Start(ChromotingHost* host,
79 const base::Closure& disconnect_callback) OVERRIDE;
80};
81
82MockIt2MeHostUserInterface::MockIt2MeHostUserInterface(
83 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
84 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
85 : It2MeHostUserInterface(network_task_runner, ui_task_runner) {
86}
87
88void MockIt2MeHostUserInterface::InitFrom(
89 scoped_ptr<DisconnectWindow> disconnect_window,
90 scoped_ptr<ContinueWindow> continue_window,
91 scoped_ptr<LocalInputMonitor> local_input_monitor) {
92 DCHECK(ui_task_runner()->BelongsToCurrentThread());
93
94 disconnect_window_ = disconnect_window.Pass();
95 continue_window_ = continue_window.Pass();
96 local_input_monitor_ = local_input_monitor.Pass();
97}
98
99void MockIt2MeHostUserInterface::Start(
100 ChromotingHost* host, const base::Closure& disconnect_callback) {
101 DCHECK(network_task_runner()->BelongsToCurrentThread());
102 DCHECK(host_ == NULL);
103
104 host_ = host;
105 disconnect_callback_ = disconnect_callback;
106}
107
[email protected]1e72daa2011-01-28 21:25:42108class ChromotingHostTest : public testing::Test {
109 public:
110 ChromotingHostTest() {
111 }
112
[email protected]2def95c2011-07-30 01:46:38113 virtual void SetUp() OVERRIDE {
[email protected]170cba42012-09-12 22:28:39114 ui_task_runner_ = new AutoThreadTaskRunner(
115 message_loop_.message_loop_proxy(),
116 base::Bind(&ChromotingHostTest::QuitMainMessageLoop,
117 base::Unretained(this)));
[email protected]3c8cfbe72012-07-03 00:24:15118
[email protected]170cba42012-09-12 22:28:39119 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory());
[email protected]a031c972012-12-27 20:10:40120 EXPECT_CALL(*desktop_environment_factory_, CreatePtr())
[email protected]81904792012-10-18 04:16:28121 .Times(AnyNumber())
122 .WillRepeatedly(Invoke(this,
123 &ChromotingHostTest::CreateDesktopEnvironment));
[email protected]ce404ca2013-01-16 17:23:53124 EXPECT_CALL(*desktop_environment_factory_, SupportsAudioCapture())
125 .Times(AnyNumber())
126 .WillRepeatedly(Return(false));
[email protected]81904792012-10-18 04:16:28127
[email protected]46c61392012-06-16 00:40:11128 session_manager_ = new protocol::MockSessionManager();
[email protected]1be2ddb2011-05-11 01:36:36129
[email protected]988dfc3c2012-01-04 01:10:11130 host_ = new ChromotingHost(
[email protected]b5921652012-10-02 21:26:39131 &signal_strategy_,
132 desktop_environment_factory_.get(),
133 scoped_ptr<protocol::SessionManager>(session_manager_),
[email protected]32debfb2012-12-05 23:40:51134 ui_task_runner_, // Audio
[email protected]ce404ca2013-01-16 17:23:53135 ui_task_runner_, // Input
[email protected]32debfb2012-12-05 23:40:51136 ui_task_runner_, // Video capture
137 ui_task_runner_, // Video encode
[email protected]ce404ca2013-01-16 17:23:53138 ui_task_runner_, // Network
139 ui_task_runner_); // UI
[email protected]8bc6b8b52012-06-21 02:49:24140 host_->AddStatusObserver(&host_status_observer_);
[email protected]856dec52011-12-01 04:25:26141
142 disconnect_window_ = new MockDisconnectWindow();
143 continue_window_ = new MockContinueWindow();
144 local_input_monitor_ = new MockLocalInputMonitor();
[email protected]c696e712012-10-10 03:56:43145 it2me_host_user_interface_.reset(
[email protected]32debfb2012-12-05 23:40:51146 new MockIt2MeHostUserInterface(ui_task_runner_, ui_task_runner_));
[email protected]b9deda22012-10-18 23:30:36147 it2me_host_user_interface_->InitFrom(
[email protected]3361e1f2012-03-20 20:31:44148 scoped_ptr<DisconnectWindow>(disconnect_window_),
149 scoped_ptr<ContinueWindow>(continue_window_),
150 scoped_ptr<LocalInputMonitor>(local_input_monitor_));
[email protected]856dec52011-12-01 04:25:26151
[email protected]b9deda22012-10-18 23:30:36152 it2me_host_user_interface_->Start(
153 host_, base::Bind(&ChromotingHost::Shutdown, host_, base::Closure()));
154
[email protected]dc22637d62012-08-31 16:26:24155 xmpp_login_ = "host@domain";
[email protected]7aaaa8d2012-07-03 19:26:23156 session1_ = new MockSession();
[email protected]ee910fd2011-11-10 18:23:31157 session2_ = new MockSession();
[email protected]7aaaa8d2012-07-03 19:26:23158 session_unowned1_.reset(new MockSession());
159 session_unowned2_.reset(new MockSession());
[email protected]cdd1c9e2012-10-26 21:14:04160 session_config1_ = SessionConfig::ForTest();
[email protected]7aaaa8d2012-07-03 19:26:23161 session_jid1_ = "user@domain/rest-of-jid";
[email protected]cdd1c9e2012-10-26 21:14:04162 session_config2_ = SessionConfig::ForTest();
[email protected]7aaaa8d2012-07-03 19:26:23163 session_jid2_ = "user2@domain/rest-of-jid";
[email protected]cdd1c9e2012-10-26 21:14:04164 session_unowned_config1_ = SessionConfig::ForTest();
[email protected]7aaaa8d2012-07-03 19:26:23165 session_unowned_jid1_ = "user3@doman/rest-of-jid";
[email protected]cdd1c9e2012-10-26 21:14:04166 session_unowned_config2_ = SessionConfig::ForTest();
[email protected]7aaaa8d2012-07-03 19:26:23167 session_unowned_jid2_ = "user4@doman/rest-of-jid";
[email protected]d2a6c96f2012-06-29 19:19:19168
[email protected]7aaaa8d2012-07-03 19:26:23169 EXPECT_CALL(*session1_, jid())
170 .WillRepeatedly(ReturnRef(session_jid1_));
[email protected]ee910fd2011-11-10 18:23:31171 EXPECT_CALL(*session2_, jid())
[email protected]7aaaa8d2012-07-03 19:26:23172 .WillRepeatedly(ReturnRef(session_jid2_));
173 EXPECT_CALL(*session_unowned1_, jid())
174 .WillRepeatedly(ReturnRef(session_unowned_jid1_));
175 EXPECT_CALL(*session_unowned2_, jid())
176 .WillRepeatedly(ReturnRef(session_unowned_jid2_));
[email protected]b1f94ee2012-07-12 21:56:41177 EXPECT_CALL(*session1_, SetEventHandler(_))
[email protected]ee910fd2011-11-10 18:23:31178 .Times(AnyNumber());
[email protected]b1f94ee2012-07-12 21:56:41179 EXPECT_CALL(*session2_, SetEventHandler(_))
[email protected]ee910fd2011-11-10 18:23:31180 .Times(AnyNumber());
[email protected]b1f94ee2012-07-12 21:56:41181 EXPECT_CALL(*session_unowned1_, SetEventHandler(_))
[email protected]d2a6c96f2012-06-29 19:19:19182 .Times(AnyNumber())
[email protected]b1f94ee2012-07-12 21:56:41183 .WillRepeatedly(Invoke(this, &ChromotingHostTest::SetEventHandler));
184 EXPECT_CALL(*session_unowned2_, SetEventHandler(_))
[email protected]d2a6c96f2012-06-29 19:19:19185 .Times(AnyNumber());
[email protected]7aaaa8d2012-07-03 19:26:23186 EXPECT_CALL(*session1_, config())
187 .WillRepeatedly(ReturnRef(session_config1_));
[email protected]ee910fd2011-11-10 18:23:31188 EXPECT_CALL(*session2_, config())
189 .WillRepeatedly(ReturnRef(session_config2_));
190
[email protected]170cba42012-09-12 22:28:39191 owned_connection1_.reset(new MockConnectionToClient(session1_,
192 &host_stub1_));
[email protected]7aaaa8d2012-07-03 19:26:23193 connection1_ = owned_connection1_.get();
[email protected]170cba42012-09-12 22:28:39194 owned_connection2_.reset(new MockConnectionToClient(session2_,
195 &host_stub2_));
[email protected]ec6411872011-11-11 03:28:55196 connection2_ = owned_connection2_.get();
[email protected]1e72daa2011-01-28 21:25:42197
[email protected]7aaaa8d2012-07-03 19:26:23198 ON_CALL(video_stub1_, ProcessVideoPacketPtr(_, _))
[email protected]9e2a3132011-10-07 05:07:40199 .WillByDefault(DeleteArg<0>());
[email protected]9302fce2012-03-28 03:57:57200 ON_CALL(video_stub2_, ProcessVideoPacketPtr(_, _))
[email protected]9e2a3132011-10-07 05:07:40201 .WillByDefault(DeleteArg<0>());
[email protected]7aaaa8d2012-07-03 19:26:23202 ON_CALL(*connection1_, video_stub())
203 .WillByDefault(Return(&video_stub1_));
204 ON_CALL(*connection1_, client_stub())
205 .WillByDefault(Return(&client_stub1_));
206 ON_CALL(*connection1_, session())
207 .WillByDefault(Return(session1_));
[email protected]ec6411872011-11-11 03:28:55208 ON_CALL(*connection2_, video_stub())
[email protected]44f60762011-03-23 12:13:35209 .WillByDefault(Return(&video_stub2_));
[email protected]ec6411872011-11-11 03:28:55210 ON_CALL(*connection2_, client_stub())
[email protected]44f60762011-03-23 12:13:35211 .WillByDefault(Return(&client_stub2_));
[email protected]ec6411872011-11-11 03:28:55212 ON_CALL(*connection2_, session())
[email protected]ee910fd2011-11-10 18:23:31213 .WillByDefault(Return(session2_));
[email protected]7aaaa8d2012-07-03 19:26:23214 EXPECT_CALL(*connection1_, video_stub())
[email protected]9cabbaf02011-01-29 00:59:59215 .Times(AnyNumber());
[email protected]7aaaa8d2012-07-03 19:26:23216 EXPECT_CALL(*connection1_, client_stub())
[email protected]9cabbaf02011-01-29 00:59:59217 .Times(AnyNumber());
[email protected]7aaaa8d2012-07-03 19:26:23218 EXPECT_CALL(*connection1_, session())
[email protected]9cabbaf02011-01-29 00:59:59219 .Times(AnyNumber());
[email protected]ec6411872011-11-11 03:28:55220 EXPECT_CALL(*connection2_, video_stub())
[email protected]44f60762011-03-23 12:13:35221 .Times(AnyNumber());
[email protected]ec6411872011-11-11 03:28:55222 EXPECT_CALL(*connection2_, client_stub())
[email protected]44f60762011-03-23 12:13:35223 .Times(AnyNumber());
[email protected]ec6411872011-11-11 03:28:55224 EXPECT_CALL(*connection2_, session())
[email protected]44f60762011-03-23 12:13:35225 .Times(AnyNumber());
[email protected]07e76bb2012-07-02 18:55:29226
227 empty_candidate_config_ =
228 protocol::CandidateSessionConfig::CreateEmpty();
229 default_candidate_config_ =
230 protocol::CandidateSessionConfig::CreateDefault();
[email protected]1e72daa2011-01-28 21:25:42231 }
232
[email protected]44f60762011-03-23 12:13:35233 // Helper method to pretend a client is connected to ChromotingHost.
[email protected]d317a25a2012-06-26 22:58:30234 void SimulateClientConnection(int connection_index, bool authenticate,
235 bool reject) {
[email protected]3361e1f2012-03-20 20:31:44236 scoped_ptr<protocol::ConnectionToClient> connection =
[email protected]7aaaa8d2012-07-03 19:26:23237 ((connection_index == 0) ? owned_connection1_ : owned_connection2_).
[email protected]3361e1f2012-03-20 20:31:44238 PassAs<protocol::ConnectionToClient>();
239 protocol::ConnectionToClient* connection_ptr = connection.get();
[email protected]170cba42012-09-12 22:28:39240 scoped_refptr<ClientSession> client = new ClientSession(
[email protected]c7bb03d2012-08-10 18:49:49241 host_.get(),
[email protected]32debfb2012-12-05 23:40:51242 ui_task_runner_, // Audio
[email protected]ce404ca2013-01-16 17:23:53243 ui_task_runner_, // Input
[email protected]32debfb2012-12-05 23:40:51244 ui_task_runner_, // Video capture
245 ui_task_runner_, // Video encode
246 ui_task_runner_, // Network
[email protected]ce404ca2013-01-16 17:23:53247 ui_task_runner_, // UI
[email protected]c7bb03d2012-08-10 18:49:49248 connection.Pass(),
[email protected]81904792012-10-18 04:16:28249 desktop_environment_factory_.get(),
[email protected]c7bb03d2012-08-10 18:49:49250 base::TimeDelta());
[email protected]46c61392012-06-16 00:40:11251 connection_ptr->set_host_stub(client);
[email protected]44f60762011-03-23 12:13:35252
[email protected]32debfb2012-12-05 23:40:51253 ui_task_runner_->PostTask(
[email protected]1e1cb3b2011-11-10 02:07:41254 FROM_HERE, base::Bind(&ChromotingHostTest::AddClientToHost,
255 host_, client));
[email protected]66bb70d2012-06-26 20:16:54256
[email protected]d317a25a2012-06-26 22:58:30257 if (authenticate) {
[email protected]32debfb2012-12-05 23:40:51258 ui_task_runner_->PostTask(
[email protected]d317a25a2012-06-26 22:58:30259 FROM_HERE, base::Bind(&ClientSession::OnConnectionAuthenticated,
[email protected]170cba42012-09-12 22:28:39260 client, connection_ptr));
[email protected]d317a25a2012-06-26 22:58:30261 if (!reject) {
[email protected]32debfb2012-12-05 23:40:51262 ui_task_runner_->PostTask(
[email protected]d317a25a2012-06-26 22:58:30263 FROM_HERE,
264 base::Bind(&ClientSession::OnConnectionChannelsConnected,
[email protected]170cba42012-09-12 22:28:39265 client, connection_ptr));
[email protected]d317a25a2012-06-26 22:58:30266 }
267 } else {
[email protected]32debfb2012-12-05 23:40:51268 ui_task_runner_->PostTask(
[email protected]d317a25a2012-06-26 22:58:30269 FROM_HERE, base::Bind(&ClientSession::OnConnectionClosed,
[email protected]170cba42012-09-12 22:28:39270 client, connection_ptr,
[email protected]d317a25a2012-06-26 22:58:30271 protocol::AUTHENTICATION_FAILED));
[email protected]ee910fd2011-11-10 18:23:31272 }
273
[email protected]7aaaa8d2012-07-03 19:26:23274 get_client(connection_index) = client;
[email protected]1e72daa2011-01-28 21:25:42275 }
276
[email protected]b01b3062012-09-13 20:26:11277 virtual void TearDown() OVERRIDE {
278 // Make sure that the host has been properly deleted.
279 DCHECK(host_.get() == NULL);
280 }
281
[email protected]e5ecce02012-07-03 20:34:23282 // Change the session route for |client1_|.
283 void ChangeSessionRoute(const std::string& channel_name,
284 const protocol::TransportRoute& route) {
285 host_->OnSessionRouteChange(get_client(0), channel_name, route);
286 }
287
[email protected]ce404ca2013-01-16 17:23:53288 // Creates a DesktopEnvironment with a fake VideoFrameCapturer, to mock
289 // DesktopEnvironmentFactory::Create().
[email protected]a031c972012-12-27 20:10:40290 DesktopEnvironment* CreateDesktopEnvironment() {
[email protected]ce404ca2013-01-16 17:23:53291 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
292 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr(_))
293 .Times(0);
294 EXPECT_CALL(*desktop_environment, CreateEventExecutorPtr(_, _))
295 .Times(AnyNumber())
296 .WillRepeatedly(Invoke(this, &ChromotingHostTest::CreateEventExecutor));
297 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr(_, _))
298 .Times(AnyNumber())
299 .WillRepeatedly(Invoke(this, &ChromotingHostTest::CreateVideoCapturer));
300
301 return desktop_environment;
302 }
303
304 // Creates a dummy EventExecutor, to mock
305 // DesktopEnvironment::CreateEventExecutor().
306 EventExecutor* CreateEventExecutor(
307 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
308 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
309 MockEventExecutor* event_executor = new MockEventExecutor();
310 EXPECT_CALL(*event_executor, StartPtr(_));
311 return event_executor;
312 }
313
314 // Creates a fake VideoFrameCapturer, to mock
315 // DesktopEnvironment::CreateVideoCapturer().
316 VideoFrameCapturer* CreateVideoCapturer(
317 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
318 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) {
319 return new VideoFrameCapturerFake();
[email protected]81904792012-10-18 04:16:28320 }
321
[email protected]e5ecce02012-07-03 20:34:23322 void DisconnectAllClients() {
323 host_->DisconnectAllClients();
324 }
325
[email protected]7aaaa8d2012-07-03 19:26:23326 // Helper method to disconnect client 1 from the host.
327 void DisconnectClient1() {
[email protected]24a2a9d22012-12-07 09:06:47328 NotifyClientSessionClosed(0);
[email protected]1e72daa2011-01-28 21:25:42329 }
330
[email protected]66bb70d2012-06-26 20:16:54331 // Notify |host_| that the authenticating client has been rejected.
332 void RejectAuthenticatingClient() {
333 host_->RejectAuthenticatingClient();
334 }
335
[email protected]7aaaa8d2012-07-03 19:26:23336 // Notify |host_| that a client session has closed.
337 void NotifyClientSessionClosed(int connection_index) {
[email protected]24a2a9d22012-12-07 09:06:47338 get_client(connection_index)->OnConnectionClosed(
339 get_connection(connection_index), protocol::OK);
[email protected]46c61392012-06-16 00:40:11340 }
341
[email protected]b1f94ee2012-07-12 21:56:41342 void SetEventHandler(protocol::Session::EventHandler* event_handler) {
343 session_event_handler_ = event_handler;
[email protected]d2a6c96f2012-06-29 19:19:19344 }
345
346 void NotifyConnectionClosed() {
[email protected]b1f94ee2012-07-12 21:56:41347 if (session_event_handler_) {
348 session_event_handler_->OnSessionStateChange(protocol::Session::CLOSED);
[email protected]d2a6c96f2012-06-29 19:19:19349 }
350 }
351
[email protected]e2918e872011-05-03 17:06:58352 static void AddClientToHost(scoped_refptr<ChromotingHost> host,
[email protected]ec6411872011-11-11 03:28:55353 ClientSession* session) {
[email protected]e2918e872011-05-03 17:06:58354 host->clients_.push_back(session);
[email protected]e2918e872011-05-03 17:06:58355 }
356
[email protected]970fb672011-06-20 20:54:47357 void ShutdownHost() {
[email protected]170cba42012-09-12 22:28:39358 ui_task_runner_->PostTask(
359 FROM_HERE,
360 base::Bind(&ChromotingHost::Shutdown, host_,
361 base::Bind(&ChromotingHostTest::ReleaseUiTaskRunner,
362 base::Unretained(this))));
363 }
364
365 void ReleaseUiTaskRunner() {
366 it2me_host_user_interface_.reset();
367 ui_task_runner_ = NULL;
[email protected]da5665e2012-09-13 02:11:33368 host_ = NULL;
[email protected]ce404ca2013-01-16 17:23:53369 desktop_environment_factory_.reset();
[email protected]970fb672011-06-20 20:54:47370 }
371
[email protected]46c61392012-06-16 00:40:11372 void QuitMainMessageLoop() {
373 PostQuitTask(&message_loop_);
374 }
375
[email protected]7aaaa8d2012-07-03 19:26:23376 // Expect the host to start.
377 void ExpectHostStart() {
378 EXPECT_CALL(*disconnect_window_, Hide());
379 EXPECT_CALL(*continue_window_, Hide());
380 }
381
382 // Expect the host and session manager to start, and return the expectation
383 // that the session manager has started.
384 Expectation ExpectHostAndSessionManagerStart() {
385 ExpectHostStart();
[email protected]dc22637d62012-08-31 16:26:24386 EXPECT_CALL(host_status_observer_, OnStart(xmpp_login_));
[email protected]7aaaa8d2012-07-03 19:26:23387 return EXPECT_CALL(*session_manager_, Init(_, host_.get()));
388 }
389
390 // Expect a client to connect.
391 // Return an expectation that a session has started, and that the first
392 // video packet has been sent to the client.
393 // Do |action| when that happens.
394 template <class A>
395 Expectation ExpectClientConnected(int connection_index, A action) {
396 const std::string& session_jid = get_session_jid(connection_index);
397 MockVideoStub& video_stub = get_video_stub(connection_index);
398
399 Expectation client_authenticated =
400 EXPECT_CALL(host_status_observer_, OnClientAuthenticated(session_jid));
401 EXPECT_CALL(host_status_observer_, OnClientConnected(session_jid))
402 .After(client_authenticated);
[email protected]7aaaa8d2012-07-03 19:26:23403 Expectation video_packet_sent =
404 EXPECT_CALL(video_stub, ProcessVideoPacketPtr(_, _))
[email protected]170cba42012-09-12 22:28:39405 .After(client_authenticated)
[email protected]7aaaa8d2012-07-03 19:26:23406 .WillOnce(DoAll(
407 action,
408 RunDoneTask()))
409 .RetiresOnSaturation();
410 EXPECT_CALL(video_stub, ProcessVideoPacketPtr(_, _))
411 .Times(AnyNumber())
412 .After(video_packet_sent)
413 .WillRepeatedly(RunDoneTask());
414 return video_packet_sent;
415 }
416
417 // Return an expectation that a client will disconnect after a given
418 // expectation. The given action will be done after the event executor is
419 // notified that the session has finished.
420 template <class A>
421 Expectation ExpectClientDisconnected(int connection_index,
422 bool expect_host_status_change,
423 Expectation after,
424 A action) {
425 MockConnectionToClient* connection = get_connection(connection_index);
426
427 Expectation client_disconnected =
428 EXPECT_CALL(*connection, Disconnect())
429 .After(after)
430 .WillOnce(InvokeWithoutArgs(CreateFunctor(
431 this, &ChromotingHostTest::NotifyClientSessionClosed,
432 connection_index)))
433 .RetiresOnSaturation();
434 ExpectClientDisconnectEffects(connection_index,
435 expect_host_status_change,
436 after,
437 action);
438 return client_disconnected;
439 }
440
441 // Expect the side-effects of a client disconnection, after a given
442 // expectation. The given action will be done after the event executor is
443 // notifed that the session has finished.
444 template <class A>
445 void ExpectClientDisconnectEffects(int connection_index,
446 bool expect_host_status_change,
447 Expectation after,
448 A action) {
449 const std::string& session_jid = get_session_jid(connection_index);
450
[email protected]7aaaa8d2012-07-03 19:26:23451 if (expect_host_status_change) {
452 EXPECT_CALL(host_status_observer_, OnClientDisconnected(session_jid))
453 .After(after)
[email protected]170cba42012-09-12 22:28:39454 .WillOnce(action)
[email protected]7aaaa8d2012-07-03 19:26:23455 .RetiresOnSaturation();
456 }
457 }
458
[email protected]1e72daa2011-01-28 21:25:42459 protected:
460 MessageLoop message_loop_;
[email protected]170cba42012-09-12 22:28:39461 scoped_refptr<AutoThreadTaskRunner> ui_task_runner_;
[email protected]f0a9d1b2011-03-04 21:31:44462 MockConnectionToClientEventHandler handler_;
[email protected]988dfc3c2012-01-04 01:10:11463 MockSignalStrategy signal_strategy_;
[email protected]81904792012-10-18 04:16:28464 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_;
[email protected]b9deda22012-10-18 23:30:36465 scoped_ptr<MockIt2MeHostUserInterface> it2me_host_user_interface_;
[email protected]1e72daa2011-01-28 21:25:42466 scoped_refptr<ChromotingHost> host_;
[email protected]8bc6b8b52012-06-21 02:49:24467 MockHostStatusObserver host_status_observer_;
[email protected]46c61392012-06-16 00:40:11468 protocol::MockSessionManager* session_manager_;
[email protected]dc22637d62012-08-31 16:26:24469 std::string xmpp_login_;
[email protected]7aaaa8d2012-07-03 19:26:23470 MockConnectionToClient* connection1_;
471 scoped_ptr<MockConnectionToClient> owned_connection1_;
472 ClientSession* client1_;
473 std::string session_jid1_;
474 MockSession* session1_; // Owned by |connection_|.
475 SessionConfig session_config1_;
476 MockVideoStub video_stub1_;
477 MockClientStub client_stub1_;
478 MockHostStub host_stub1_;
[email protected]ec6411872011-11-11 03:28:55479 MockConnectionToClient* connection2_;
480 scoped_ptr<MockConnectionToClient> owned_connection2_;
481 ClientSession* client2_;
[email protected]7aaaa8d2012-07-03 19:26:23482 std::string session_jid2_;
[email protected]ee910fd2011-11-10 18:23:31483 MockSession* session2_; // Owned by |connection2_|.
[email protected]c5219dda2011-09-10 17:21:00484 SessionConfig session_config2_;
[email protected]44f60762011-03-23 12:13:35485 MockVideoStub video_stub2_;
486 MockClientStub client_stub2_;
[email protected]844a3722011-05-13 00:32:02487 MockHostStub host_stub2_;
[email protected]7aaaa8d2012-07-03 19:26:23488 scoped_ptr<MockSession> session_unowned1_; // Not owned by a connection.
489 SessionConfig session_unowned_config1_;
490 std::string session_unowned_jid1_;
491 scoped_ptr<MockSession> session_unowned2_; // Not owned by a connection.
492 SessionConfig session_unowned_config2_;
493 std::string session_unowned_jid2_;
[email protected]b1f94ee2012-07-12 21:56:41494 protocol::Session::EventHandler* session_event_handler_;
[email protected]07e76bb2012-07-02 18:55:29495 scoped_ptr<protocol::CandidateSessionConfig> empty_candidate_config_;
496 scoped_ptr<protocol::CandidateSessionConfig> default_candidate_config_;
[email protected]844a3722011-05-13 00:32:02497
498 // Owned by |host_|.
[email protected]f41095f82011-06-07 16:57:44499 MockDisconnectWindow* disconnect_window_;
[email protected]9a37fdf2011-07-07 23:05:01500 MockContinueWindow* continue_window_;
[email protected]c78669c92011-06-13 22:42:38501 MockLocalInputMonitor* local_input_monitor_;
[email protected]7aaaa8d2012-07-03 19:26:23502
503 MockConnectionToClient*& get_connection(int connection_index) {
504 return (connection_index == 0) ? connection1_ : connection2_;
505 }
506
507 ClientSession*& get_client(int connection_index) {
508 return (connection_index == 0) ? client1_ : client2_;
509 }
510
511 const std::string& get_session_jid(int connection_index) {
512 return (connection_index == 0) ? session_jid1_ : session_jid2_;
513 }
514
515 MockVideoStub& get_video_stub(int connection_index) {
516 return (connection_index == 0) ? video_stub1_ : video_stub2_;
517 }
[email protected]1e72daa2011-01-28 21:25:42518};
519
[email protected]46c61392012-06-16 00:40:11520TEST_F(ChromotingHostTest, StartAndShutdown) {
[email protected]7aaaa8d2012-07-03 19:26:23521 Expectation start = ExpectHostAndSessionManagerStart();
[email protected]8bc6b8b52012-06-21 02:49:24522 EXPECT_CALL(host_status_observer_, OnShutdown()).After(start);
[email protected]46c61392012-06-16 00:40:11523
[email protected]dc22637d62012-08-31 16:26:24524 host_->Start(xmpp_login_);
[email protected]170cba42012-09-12 22:28:39525 ShutdownHost();
[email protected]1e72daa2011-01-28 21:25:42526 message_loop_.Run();
527}
528
[email protected]46c61392012-06-16 00:40:11529TEST_F(ChromotingHostTest, Connect) {
[email protected]7aaaa8d2012-07-03 19:26:23530 ExpectHostAndSessionManagerStart();
531
532 // Shut down the host when the first video packet is received.
533 Expectation video_packet_sent = ExpectClientConnected(
534 0, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
535 Expectation client_disconnected = ExpectClientDisconnected(
[email protected]54857072012-11-15 06:34:22536 0, true, video_packet_sent, InvokeWithoutArgs(base::DoNothing));
[email protected]7aaaa8d2012-07-03 19:26:23537 EXPECT_CALL(host_status_observer_, OnShutdown()).After(client_disconnected);
[email protected]46c61392012-06-16 00:40:11538
[email protected]dc22637d62012-08-31 16:26:24539 host_->Start(xmpp_login_);
[email protected]d317a25a2012-06-26 22:58:30540 SimulateClientConnection(0, true, false);
[email protected]66bb70d2012-06-26 20:16:54541 message_loop_.Run();
542}
543
544TEST_F(ChromotingHostTest, RejectAuthenticatingClient) {
[email protected]7aaaa8d2012-07-03 19:26:23545 Expectation start = ExpectHostAndSessionManagerStart();
546 EXPECT_CALL(host_status_observer_, OnClientAuthenticated(session_jid1_))
547 .WillOnce(InvokeWithoutArgs(
548 this, &ChromotingHostTest::RejectAuthenticatingClient));
549 ExpectClientDisconnected(
550 0, true, start,
551 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
552 EXPECT_CALL(host_status_observer_, OnShutdown());
[email protected]66bb70d2012-06-26 20:16:54553
[email protected]dc22637d62012-08-31 16:26:24554 host_->Start(xmpp_login_);
[email protected]d317a25a2012-06-26 22:58:30555 SimulateClientConnection(0, true, true);
556 message_loop_.Run();
557}
558
559TEST_F(ChromotingHostTest, AuthenticationFailed) {
[email protected]7aaaa8d2012-07-03 19:26:23560 ExpectHostAndSessionManagerStart();
561 EXPECT_CALL(host_status_observer_, OnAccessDenied(session_jid1_))
562 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
563 EXPECT_CALL(host_status_observer_, OnShutdown());
[email protected]d317a25a2012-06-26 22:58:30564
[email protected]dc22637d62012-08-31 16:26:24565 host_->Start(xmpp_login_);
[email protected]d317a25a2012-06-26 22:58:30566 SimulateClientConnection(0, false, false);
[email protected]1e72daa2011-01-28 21:25:42567 message_loop_.Run();
568}
569
[email protected]46c61392012-06-16 00:40:11570TEST_F(ChromotingHostTest, Reconnect) {
[email protected]7aaaa8d2012-07-03 19:26:23571 ExpectHostAndSessionManagerStart();
572
573 // When a video packet is received on the first connection, disconnect it,
574 // then quit the message loop.
575 Expectation video_packet_sent1 = ExpectClientConnected(0, DoAll(
576 InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectClient1),
577 InvokeWithoutArgs(this, &ChromotingHostTest::QuitMainMessageLoop)));
578 ExpectClientDisconnectEffects(
[email protected]54857072012-11-15 06:34:22579 0, true, video_packet_sent1, InvokeWithoutArgs(base::DoNothing));
[email protected]7aaaa8d2012-07-03 19:26:23580
581 // When a video packet is received on the second connection, shut down the
582 // host.
583 Expectation video_packet_sent2 = ExpectClientConnected(
584 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
585 Expectation client_disconnected2 = ExpectClientDisconnected(
[email protected]54857072012-11-15 06:34:22586 1, true, video_packet_sent2, InvokeWithoutArgs(base::DoNothing));
[email protected]7aaaa8d2012-07-03 19:26:23587 EXPECT_CALL(host_status_observer_, OnShutdown()).After(client_disconnected2);
[email protected]46c61392012-06-16 00:40:11588
[email protected]dc22637d62012-08-31 16:26:24589 host_->Start(xmpp_login_);
[email protected]d317a25a2012-06-26 22:58:30590 SimulateClientConnection(0, true, false);
[email protected]1e72daa2011-01-28 21:25:42591 message_loop_.Run();
[email protected]d317a25a2012-06-26 22:58:30592 SimulateClientConnection(1, true, false);
[email protected]44f60762011-03-23 12:13:35593 message_loop_.Run();
594}
595
[email protected]46c61392012-06-16 00:40:11596TEST_F(ChromotingHostTest, ConnectWhenAnotherClientIsConnected) {
[email protected]7aaaa8d2012-07-03 19:26:23597 ExpectHostAndSessionManagerStart();
598
599 // When a video packet is received, connect the second connection.
600 // This should disconnect the first connection.
601 Expectation video_packet_sent1 = ExpectClientConnected(
602 0,
603 InvokeWithoutArgs(
604 CreateFunctor(
605 this,
606 &ChromotingHostTest::SimulateClientConnection, 1, true, false)));
607 ExpectClientDisconnected(
[email protected]54857072012-11-15 06:34:22608 0, true, video_packet_sent1, InvokeWithoutArgs(base::DoNothing));
[email protected]7aaaa8d2012-07-03 19:26:23609 Expectation video_packet_sent2 = ExpectClientConnected(
610 1, InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
611 Expectation client_disconnected2 = ExpectClientDisconnected(
[email protected]54857072012-11-15 06:34:22612 1, true, video_packet_sent2, InvokeWithoutArgs(base::DoNothing));
[email protected]7aaaa8d2012-07-03 19:26:23613 EXPECT_CALL(host_status_observer_, OnShutdown()).After(client_disconnected2);
[email protected]46c61392012-06-16 00:40:11614
[email protected]dc22637d62012-08-31 16:26:24615 host_->Start(xmpp_login_);
[email protected]d317a25a2012-06-26 22:58:30616 SimulateClientConnection(0, true, false);
[email protected]37961b12011-03-30 12:39:00617 message_loop_.Run();
618}
619
[email protected]d2a6c96f2012-06-29 19:19:19620TEST_F(ChromotingHostTest, IncomingSessionDeclined) {
[email protected]7aaaa8d2012-07-03 19:26:23621 ExpectHostStart();
[email protected]d2a6c96f2012-06-29 19:19:19622 protocol::SessionManager::IncomingSessionResponse response =
623 protocol::SessionManager::ACCEPT;
[email protected]7aaaa8d2012-07-03 19:26:23624 host_->OnIncomingSession(session1_, &response);
[email protected]d2a6c96f2012-06-29 19:19:19625 EXPECT_EQ(protocol::SessionManager::DECLINE, response);
[email protected]da5665e2012-09-13 02:11:33626
627 ShutdownHost();
628 message_loop_.Run();
[email protected]d2a6c96f2012-06-29 19:19:19629}
630
631TEST_F(ChromotingHostTest, IncomingSessionIncompatible) {
[email protected]7aaaa8d2012-07-03 19:26:23632 ExpectHostAndSessionManagerStart();
633 EXPECT_CALL(*session_unowned1_, candidate_config()).WillOnce(Return(
[email protected]07e76bb2012-07-02 18:55:29634 empty_candidate_config_.get()));
[email protected]d2a6c96f2012-06-29 19:19:19635 EXPECT_CALL(host_status_observer_, OnShutdown());
636
[email protected]dc22637d62012-08-31 16:26:24637 host_->Start(xmpp_login_);
[email protected]d2a6c96f2012-06-29 19:19:19638
639 protocol::SessionManager::IncomingSessionResponse response =
640 protocol::SessionManager::ACCEPT;
[email protected]7aaaa8d2012-07-03 19:26:23641 host_->OnIncomingSession(session_unowned1_.get(), &response);
[email protected]d2a6c96f2012-06-29 19:19:19642 EXPECT_EQ(protocol::SessionManager::INCOMPATIBLE, response);
643
[email protected]da5665e2012-09-13 02:11:33644 ShutdownHost();
645 message_loop_.Run();
[email protected]d2a6c96f2012-06-29 19:19:19646}
647
648TEST_F(ChromotingHostTest, IncomingSessionAccepted) {
[email protected]7aaaa8d2012-07-03 19:26:23649 ExpectHostAndSessionManagerStart();
650 EXPECT_CALL(*session_unowned1_, candidate_config()).WillOnce(Return(
[email protected]07e76bb2012-07-02 18:55:29651 default_candidate_config_.get()));
[email protected]7aaaa8d2012-07-03 19:26:23652 EXPECT_CALL(*session_unowned1_, set_config(_));
653 EXPECT_CALL(*session_unowned1_, Close()).WillOnce(InvokeWithoutArgs(
[email protected]d2a6c96f2012-06-29 19:19:19654 this, &ChromotingHostTest::NotifyConnectionClosed));
655 EXPECT_CALL(host_status_observer_, OnAccessDenied(_));
656 EXPECT_CALL(host_status_observer_, OnShutdown());
657
[email protected]dc22637d62012-08-31 16:26:24658 host_->Start(xmpp_login_);
[email protected]d2a6c96f2012-06-29 19:19:19659
660 protocol::SessionManager::IncomingSessionResponse response =
661 protocol::SessionManager::DECLINE;
[email protected]7aaaa8d2012-07-03 19:26:23662 host_->OnIncomingSession(session_unowned1_.release(), &response);
[email protected]d2a6c96f2012-06-29 19:19:19663 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
664
[email protected]da5665e2012-09-13 02:11:33665 ShutdownHost();
666 message_loop_.Run();
[email protected]d2a6c96f2012-06-29 19:19:19667}
668
669TEST_F(ChromotingHostTest, IncomingSessionOverload) {
[email protected]7aaaa8d2012-07-03 19:26:23670 ExpectHostAndSessionManagerStart();
671 EXPECT_CALL(*session_unowned1_, candidate_config()).WillOnce(Return(
[email protected]07e76bb2012-07-02 18:55:29672 default_candidate_config_.get()));
[email protected]7aaaa8d2012-07-03 19:26:23673 EXPECT_CALL(*session_unowned1_, set_config(_));
674 EXPECT_CALL(*session_unowned1_, Close()).WillOnce(InvokeWithoutArgs(
[email protected]d2a6c96f2012-06-29 19:19:19675 this, &ChromotingHostTest::NotifyConnectionClosed));
676 EXPECT_CALL(host_status_observer_, OnAccessDenied(_));
677 EXPECT_CALL(host_status_observer_, OnShutdown());
678
[email protected]dc22637d62012-08-31 16:26:24679 host_->Start(xmpp_login_);
[email protected]d2a6c96f2012-06-29 19:19:19680
681 protocol::SessionManager::IncomingSessionResponse response =
682 protocol::SessionManager::DECLINE;
[email protected]7aaaa8d2012-07-03 19:26:23683 host_->OnIncomingSession(session_unowned1_.release(), &response);
[email protected]d2a6c96f2012-06-29 19:19:19684 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
685
[email protected]7aaaa8d2012-07-03 19:26:23686 host_->OnIncomingSession(session_unowned2_.get(), &response);
[email protected]d2a6c96f2012-06-29 19:19:19687 EXPECT_EQ(protocol::SessionManager::OVERLOAD, response);
688
[email protected]da5665e2012-09-13 02:11:33689 ShutdownHost();
690 message_loop_.Run();
[email protected]d2a6c96f2012-06-29 19:19:19691}
692
[email protected]e5ecce02012-07-03 20:34:23693TEST_F(ChromotingHostTest, OnSessionRouteChange) {
694 std::string channel_name("ChannelName");
695 protocol::TransportRoute route;
696
697 ExpectHostAndSessionManagerStart();
698 Expectation video_packet_sent = ExpectClientConnected(
699 0, InvokeWithoutArgs(CreateFunctor(
700 this, &ChromotingHostTest::ChangeSessionRoute, channel_name, route)));
701 Expectation route_change =
702 EXPECT_CALL(host_status_observer_, OnClientRouteChange(
703 session_jid1_, channel_name, _))
704 .After(video_packet_sent)
705 .WillOnce(InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
[email protected]54857072012-11-15 06:34:22706 ExpectClientDisconnected(0, true, route_change,
707 InvokeWithoutArgs(base::DoNothing));
[email protected]e5ecce02012-07-03 20:34:23708 EXPECT_CALL(host_status_observer_, OnShutdown());
709
[email protected]dc22637d62012-08-31 16:26:24710 host_->Start(xmpp_login_);
[email protected]e5ecce02012-07-03 20:34:23711 SimulateClientConnection(0, true, false);
712 message_loop_.Run();
713}
714
715TEST_F(ChromotingHostTest, DisconnectAllClients) {
716 ExpectHostAndSessionManagerStart();
717 Expectation video_packet_sent = ExpectClientConnected(
718 0, InvokeWithoutArgs(this, &ChromotingHostTest::DisconnectAllClients));
719 ExpectClientDisconnected(0, true, video_packet_sent,
720 InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost));
721 EXPECT_CALL(host_status_observer_, OnShutdown());
722
[email protected]dc22637d62012-08-31 16:26:24723 host_->Start(xmpp_login_);
[email protected]e5ecce02012-07-03 20:34:23724 SimulateClientConnection(0, true, false);
725 message_loop_.Run();
726}
727
[email protected]1e72daa2011-01-28 21:25:42728} // namespace remoting