blob: 525cdde4a845ad21238e19e179362dc9357ec2d9 [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
sergeyu1417e0132015-12-23 19:01:225#include "remoting/host/chromoting_host.h"
6
dcheng0765c492016-04-06 22:41:537#include <memory>
sergeyu1417e0132015-12-23 19:01:228#include <utility>
9
[email protected]4ea2c7c2011-03-31 14:20:0610#include "base/bind.h"
[email protected]54857072012-11-15 06:34:2211#include "base/bind_helpers.h"
dcheng0765c492016-04-06 22:41:5312#include "base/memory/ptr_util.h"
Alexander Timin4f9c35c2018-11-01 20:15:2013#include "base/message_loop/message_loop.h"
fdoray6d056ff2016-07-04 21:56:4214#include "base/run_loop.h"
Yuwei Huang1132c582019-01-10 01:05:0615#include "base/test/scoped_task_environment.h"
16#include "base/threading/thread_task_runner_handle.h"
17#include "net/base/network_change_notifier.h"
[email protected]170cba42012-09-12 22:28:3918#include "remoting/base/auto_thread_task_runner.h"
[email protected]677bb0a2012-07-13 19:38:0719#include "remoting/host/audio_capturer.h"
[email protected]420a5e42012-12-18 21:42:1220#include "remoting/host/chromoting_host_context.h"
sergeyuc18df2ca2015-11-27 03:33:3521#include "remoting/host/fake_desktop_environment.h"
[email protected]20013202014-08-08 06:33:5022#include "remoting/host/fake_mouse_cursor_monitor.h"
[email protected]0a071a32011-02-08 00:18:2423#include "remoting/host/host_mock_objects.h"
[email protected]1e72daa2011-01-28 21:25:4224#include "remoting/proto/video.pb.h"
[email protected]d317a25a2012-06-26 22:58:3025#include "remoting/protocol/errors.h"
sergeyu60082fbf2015-11-24 21:12:4826#include "remoting/protocol/fake_connection_to_client.h"
sergeyu4d208002015-11-23 22:27:4327#include "remoting/protocol/fake_desktop_capturer.h"
[email protected]0a071a32011-02-08 00:18:2428#include "remoting/protocol/protocol_mock_objects.h"
[email protected]1e72daa2011-01-28 21:25:4229#include "remoting/protocol/session_config.h"
sergeyue5767602015-12-28 19:49:0330#include "remoting/protocol/transport_context.h"
[email protected]1e72daa2011-01-28 21:25:4231#include "testing/gmock/include/gmock/gmock.h"
[email protected]497d8a92013-01-28 23:54:0332#include "testing/gmock_mutant.h"
[email protected]1e72daa2011-01-28 21:25:4233#include "testing/gtest/include/gtest/gtest.h"
34
[email protected]f0a9d1b2011-03-04 21:31:4435using ::remoting::protocol::MockClientStub;
[email protected]f0a9d1b2011-03-04 21:31:4436using ::remoting::protocol::MockConnectionToClientEventHandler;
37using ::remoting::protocol::MockHostStub;
[email protected]f0a9d1b2011-03-04 21:31:4438using ::remoting::protocol::MockSession;
39using ::remoting::protocol::MockVideoStub;
[email protected]064128c2014-04-07 22:33:2840using ::remoting::protocol::Session;
[email protected]f0a9d1b2011-03-04 21:31:4441using ::remoting::protocol::SessionConfig;
42
[email protected]1e72daa2011-01-28 21:25:4243using testing::_;
44using testing::AnyNumber;
[email protected]37961b12011-03-30 12:39:0045using testing::AtLeast;
[email protected]064128c2014-04-07 22:33:2846using testing::AtMost;
[email protected]1e72daa2011-01-28 21:25:4247using testing::DeleteArg;
48using testing::DoAll;
[email protected]db638312012-06-20 00:41:3249using testing::Expectation;
[email protected]1e72daa2011-01-28 21:25:4250using testing::InSequence;
[email protected]d2a6c96f2012-06-29 19:19:1951using testing::Invoke;
[email protected]ec6411872011-11-11 03:28:5552using testing::InvokeArgument;
[email protected]1e72daa2011-01-28 21:25:4253using testing::InvokeWithoutArgs;
54using testing::Return;
[email protected]f41095f82011-06-07 16:57:4455using testing::ReturnRef;
[email protected]064128c2014-04-07 22:33:2856using testing::SaveArg;
[email protected]37961b12011-03-30 12:39:0057using testing::Sequence;
[email protected]1e72daa2011-01-28 21:25:4258
59namespace remoting {
60
Jamie Walch55d02bd2018-05-23 22:48:2961const size_t kNumFailuresIgnored = 5;
62
[email protected]1e72daa2011-01-28 21:25:4263class ChromotingHostTest : public testing::Test {
64 public:
Chris Watkins6fe52aa2017-11-28 03:24:0565 ChromotingHostTest() = default;
[email protected]1e72daa2011-01-28 21:25:4266
dcheng440d8e1c2014-10-28 01:23:1567 void SetUp() override {
Yuwei Huang1132c582019-01-10 01:05:0668 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
69
70 task_runner_ = new AutoThreadTaskRunner(base::ThreadTaskRunnerHandle::Get(),
Peter Kasting341e1fb2018-02-24 00:03:0171 base::DoNothing());
[email protected]3c8cfbe72012-07-03 00:24:1572
sergeyu3c62d532016-09-27 00:40:3373 desktop_environment_factory_.reset(
Yuwei Huang1132c582019-01-10 01:05:0674 new FakeDesktopEnvironmentFactory(base::ThreadTaskRunnerHandle::Get()));
[email protected]46c61392012-06-16 00:40:1175 session_manager_ = new protocol::MockSessionManager();
[email protected]1be2ddb2011-05-11 01:36:3676
sergeyue5767602015-12-28 19:49:0377 host_.reset(new ChromotingHost(
dcheng0765c492016-04-06 22:41:5378 desktop_environment_factory_.get(), base::WrapUnique(session_manager_),
sergeyue5767602015-12-28 19:49:0379 protocol::TransportContext::ForTests(protocol::TransportRole::SERVER),
Sergey Ulanovcc04df92017-07-07 18:33:4180 task_runner_, // Audio
zijieheccab8bd72016-11-23 00:57:3181 task_runner_,
82 DesktopEnvironmentOptions::CreateDefault())); // Video encode
Sergey Ulanovcc04df92017-07-07 18:33:4183 host_->status_monitor()->AddStatusObserver(&host_status_observer_);
[email protected]856dec52011-12-01 04:25:2684
[email protected]dc22637d62012-08-31 16:26:2485 xmpp_login_ = "host@domain";
[email protected]7aaaa8d2012-07-03 19:26:2386 session1_ = new MockSession();
[email protected]ee910fd2011-11-10 18:23:3187 session2_ = new MockSession();
[email protected]7aaaa8d2012-07-03 19:26:2388 session_unowned1_.reset(new MockSession());
89 session_unowned2_.reset(new MockSession());
[email protected]cdd1c9e2012-10-26 21:14:0490 session_config1_ = SessionConfig::ForTest();
[email protected]7aaaa8d2012-07-03 19:26:2391 session_jid1_ = "user@domain/rest-of-jid";
[email protected]cdd1c9e2012-10-26 21:14:0492 session_config2_ = SessionConfig::ForTest();
[email protected]7aaaa8d2012-07-03 19:26:2393 session_jid2_ = "user2@domain/rest-of-jid";
[email protected]7aaaa8d2012-07-03 19:26:2394 session_unowned_jid1_ = "user3@doman/rest-of-jid";
[email protected]7aaaa8d2012-07-03 19:26:2395 session_unowned_jid2_ = "user4@doman/rest-of-jid";
[email protected]d2a6c96f2012-06-29 19:19:1996
[email protected]7aaaa8d2012-07-03 19:26:2397 EXPECT_CALL(*session1_, jid())
98 .WillRepeatedly(ReturnRef(session_jid1_));
[email protected]ee910fd2011-11-10 18:23:3199 EXPECT_CALL(*session2_, jid())
[email protected]7aaaa8d2012-07-03 19:26:23100 .WillRepeatedly(ReturnRef(session_jid2_));
101 EXPECT_CALL(*session_unowned1_, jid())
102 .WillRepeatedly(ReturnRef(session_unowned_jid1_));
103 EXPECT_CALL(*session_unowned2_, jid())
104 .WillRepeatedly(ReturnRef(session_unowned_jid2_));
[email protected]b1f94ee2012-07-12 21:56:41105 EXPECT_CALL(*session_unowned1_, SetEventHandler(_))
[email protected]d2a6c96f2012-06-29 19:19:19106 .Times(AnyNumber())
[email protected]064128c2014-04-07 22:33:28107 .WillRepeatedly(SaveArg<0>(&session_unowned1_event_handler_));
[email protected]b1f94ee2012-07-12 21:56:41108 EXPECT_CALL(*session_unowned2_, SetEventHandler(_))
[email protected]064128c2014-04-07 22:33:28109 .Times(AnyNumber())
110 .WillRepeatedly(SaveArg<0>(&session_unowned2_event_handler_));
[email protected]7aaaa8d2012-07-03 19:26:23111 EXPECT_CALL(*session1_, config())
sergeyub4b09272015-04-23 18:59:12112 .WillRepeatedly(ReturnRef(*session_config1_));
[email protected]ee910fd2011-11-10 18:23:31113 EXPECT_CALL(*session2_, config())
sergeyub4b09272015-04-23 18:59:12114 .WillRepeatedly(ReturnRef(*session_config2_));
sergeyude15c0372015-12-10 23:08:08115 EXPECT_CALL(*session_unowned1_, config())
116 .WillRepeatedly(ReturnRef(*session_config1_));
117 EXPECT_CALL(*session_unowned2_, config())
118 .WillRepeatedly(ReturnRef(*session_config2_));
[email protected]ee910fd2011-11-10 18:23:31119
sergeyub031cd22015-11-19 22:17:13120 owned_connection1_.reset(
dcheng0765c492016-04-06 22:41:53121 new protocol::FakeConnectionToClient(base::WrapUnique(session1_)));
sergeyu60082fbf2015-11-24 21:12:48122 owned_connection1_->set_host_stub(&host_stub1_);
[email protected]7aaaa8d2012-07-03 19:26:23123 connection1_ = owned_connection1_.get();
sergeyu60082fbf2015-11-24 21:12:48124 connection1_->set_client_stub(&client_stub1_);
125
sergeyub031cd22015-11-19 22:17:13126 owned_connection2_.reset(
dcheng0765c492016-04-06 22:41:53127 new protocol::FakeConnectionToClient(base::WrapUnique(session2_)));
sergeyu60082fbf2015-11-24 21:12:48128 owned_connection2_->set_host_stub(&host_stub2_);
[email protected]ec6411872011-11-11 03:28:55129 connection2_ = owned_connection2_.get();
sergeyu60082fbf2015-11-24 21:12:48130 connection2_->set_client_stub(&client_stub2_);
[email protected]1e72daa2011-01-28 21:25:42131 }
132
[email protected]44f60762011-03-23 12:13:35133 // Helper method to pretend a client is connected to ChromotingHost.
[email protected]d317a25a2012-06-26 22:58:30134 void SimulateClientConnection(int connection_index, bool authenticate,
135 bool reject) {
dcheng0765c492016-04-06 22:41:53136 std::unique_ptr<protocol::ConnectionToClient> connection = std::move(
sergeyu1417e0132015-12-23 19:01:22137 (connection_index == 0) ? owned_connection1_ : owned_connection2_);
[email protected]3361e1f2012-03-20 20:31:44138 protocol::ConnectionToClient* connection_ptr = connection.get();
dcheng0765c492016-04-06 22:41:53139 std::unique_ptr<ClientSession> client(new ClientSession(
sergeyucd16e2062016-09-12 19:28:35140 host_.get(), std::move(connection), desktop_environment_factory_.get(),
zijiehe4aa6ea42016-11-12 01:28:16141 DesktopEnvironmentOptions::CreateDefault(), base::TimeDelta(), nullptr,
zijieheb7da62422017-07-11 01:17:15142 std::vector<HostExtension*>()));
sergeyuc18df2ca2015-11-27 03:33:35143 ClientSession* client_ptr = client.get();
[email protected]f19f09ca2013-03-13 11:10:29144
[email protected]22f3d242013-04-30 20:46:16145 connection_ptr->set_host_stub(client.get());
sergeyuc18df2ca2015-11-27 03:33:35146 get_client(connection_index) = client_ptr;
[email protected]22f3d242013-04-30 20:46:16147
148 // |host| is responsible for deleting |client| from now on.
sergeyub047307a2016-10-18 17:19:29149 host_->clients_.push_back(std::move(client));
sergeyuc18df2ca2015-11-27 03:33:35150
151 if (authenticate) {
sergeyu4e1f4cd2016-09-27 00:42:52152 client_ptr->OnConnectionAuthenticated();
sergeyuc18df2ca2015-11-27 03:33:35153 if (!reject)
sergeyu4e1f4cd2016-09-27 00:42:52154 client_ptr->OnConnectionChannelsConnected();
sergeyuc18df2ca2015-11-27 03:33:35155 } else {
sergeyu4e1f4cd2016-09-27 00:42:52156 client_ptr->OnConnectionClosed(protocol::AUTHENTICATION_FAILED);
sergeyuc18df2ca2015-11-27 03:33:35157 }
[email protected]1e72daa2011-01-28 21:25:42158 }
159
dcheng440d8e1c2014-10-28 01:23:15160 void TearDown() override {
sergeyuc18df2ca2015-11-27 03:33:35161 if (host_)
162 ShutdownHost();
163 task_runner_ = nullptr;
[email protected]b01b3062012-09-13 20:26:11164
fdoray6d056ff2016-07-04 21:56:42165 base::RunLoop().RunUntilIdle();
[email protected]20013202014-08-08 06:33:50166 }
167
[email protected]064128c2014-04-07 22:33:28168 void NotifyConnectionClosed1() {
169 if (session_unowned1_event_handler_) {
170 session_unowned1_event_handler_->OnSessionStateChange(Session::CLOSED);
171 }
[email protected]d2a6c96f2012-06-29 19:19:19172 }
173
[email protected]064128c2014-04-07 22:33:28174 void NotifyConnectionClosed2() {
175 if (session_unowned2_event_handler_) {
176 session_unowned2_event_handler_->OnSessionStateChange(Session::CLOSED);
[email protected]d2a6c96f2012-06-29 19:19:19177 }
178 }
179
[email protected]c5319f5032013-04-25 23:06:43180 void ShutdownHost() {
sergeyuc18df2ca2015-11-27 03:33:35181 EXPECT_CALL(host_status_observer_, OnShutdown());
[email protected]22f3d242013-04-30 20:46:16182 host_.reset();
[email protected]ce404ca2013-01-16 17:23:53183 desktop_environment_factory_.reset();
[email protected]970fb672011-06-20 20:54:47184 }
185
sergeyu1b032682015-12-17 03:17:36186 // Starts the host.
187 void StartHost() {
[email protected]dc22637d62012-08-31 16:26:24188 EXPECT_CALL(host_status_observer_, OnStart(xmpp_login_));
sergeyu1b032682015-12-17 03:17:36189 EXPECT_CALL(*session_manager_, AcceptIncoming(_));
190 host_->Start(xmpp_login_);
[email protected]7aaaa8d2012-07-03 19:26:23191 }
192
193 // Expect a client to connect.
sergeyuc18df2ca2015-11-27 03:33:35194 // Return an expectation that a session has started.
195 Expectation ExpectClientConnected(int connection_index) {
[email protected]7aaaa8d2012-07-03 19:26:23196 const std::string& session_jid = get_session_jid(connection_index);
[email protected]7aaaa8d2012-07-03 19:26:23197
198 Expectation client_authenticated =
199 EXPECT_CALL(host_status_observer_, OnClientAuthenticated(session_jid));
sergeyuc18df2ca2015-11-27 03:33:35200 return EXPECT_CALL(host_status_observer_, OnClientConnected(session_jid))
[email protected]7aaaa8d2012-07-03 19:26:23201 .After(client_authenticated);
[email protected]7aaaa8d2012-07-03 19:26:23202 }
203
sergeyuc18df2ca2015-11-27 03:33:35204 // Expect that a client is disconnected. The given action will be done after
205 // the status observer is notified that the session has finished.
206 Expectation ExpectClientDisconnected(int connection_index) {
sergeyu60082fbf2015-11-24 21:12:48207 return EXPECT_CALL(host_status_observer_,
208 OnClientDisconnected(get_session_jid(connection_index)))
sergeyu60082fbf2015-11-24 21:12:48209 .RetiresOnSaturation();
[email protected]7aaaa8d2012-07-03 19:26:23210 }
211
[email protected]1e72daa2011-01-28 21:25:42212 protected:
Yuwei Huang1132c582019-01-10 01:05:06213 base::test::ScopedTaskEnvironment scoped_task_environment_;
214 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
[email protected]22f3d242013-04-30 20:46:16215 scoped_refptr<AutoThreadTaskRunner> task_runner_;
[email protected]f0a9d1b2011-03-04 21:31:44216 MockConnectionToClientEventHandler handler_;
dcheng0765c492016-04-06 22:41:53217 std::unique_ptr<FakeDesktopEnvironmentFactory> desktop_environment_factory_;
[email protected]8bc6b8b52012-06-21 02:49:24218 MockHostStatusObserver host_status_observer_;
dcheng0765c492016-04-06 22:41:53219 std::unique_ptr<ChromotingHost> host_;
[email protected]46c61392012-06-16 00:40:11220 protocol::MockSessionManager* session_manager_;
[email protected]dc22637d62012-08-31 16:26:24221 std::string xmpp_login_;
sergeyu60082fbf2015-11-24 21:12:48222 protocol::FakeConnectionToClient* connection1_;
dcheng0765c492016-04-06 22:41:53223 std::unique_ptr<protocol::FakeConnectionToClient> owned_connection1_;
[email protected]7aaaa8d2012-07-03 19:26:23224 ClientSession* client1_;
225 std::string session_jid1_;
226 MockSession* session1_; // Owned by |connection_|.
dcheng0765c492016-04-06 22:41:53227 std::unique_ptr<SessionConfig> session_config1_;
[email protected]7aaaa8d2012-07-03 19:26:23228 MockClientStub client_stub1_;
229 MockHostStub host_stub1_;
sergeyu60082fbf2015-11-24 21:12:48230 protocol::FakeConnectionToClient* connection2_;
dcheng0765c492016-04-06 22:41:53231 std::unique_ptr<protocol::FakeConnectionToClient> owned_connection2_;
[email protected]ec6411872011-11-11 03:28:55232 ClientSession* client2_;
[email protected]7aaaa8d2012-07-03 19:26:23233 std::string session_jid2_;
[email protected]ee910fd2011-11-10 18:23:31234 MockSession* session2_; // Owned by |connection2_|.
dcheng0765c492016-04-06 22:41:53235 std::unique_ptr<SessionConfig> session_config2_;
[email protected]44f60762011-03-23 12:13:35236 MockClientStub client_stub2_;
[email protected]844a3722011-05-13 00:32:02237 MockHostStub host_stub2_;
dcheng0765c492016-04-06 22:41:53238 std::unique_ptr<MockSession> session_unowned1_; // Not owned by a connection.
[email protected]7aaaa8d2012-07-03 19:26:23239 std::string session_unowned_jid1_;
dcheng0765c492016-04-06 22:41:53240 std::unique_ptr<MockSession> session_unowned2_; // Not owned by a connection.
[email protected]7aaaa8d2012-07-03 19:26:23241 std::string session_unowned_jid2_;
[email protected]064128c2014-04-07 22:33:28242 protocol::Session::EventHandler* session_unowned1_event_handler_;
243 protocol::Session::EventHandler* session_unowned2_event_handler_;
[email protected]844a3722011-05-13 00:32:02244
[email protected]064128c2014-04-07 22:33:28245 // Returns the cached client pointers client1_ or client2_.
[email protected]7aaaa8d2012-07-03 19:26:23246 ClientSession*& get_client(int connection_index) {
247 return (connection_index == 0) ? client1_ : client2_;
248 }
249
250 const std::string& get_session_jid(int connection_index) {
251 return (connection_index == 0) ? session_jid1_ : session_jid2_;
252 }
[email protected]1e72daa2011-01-28 21:25:42253};
254
[email protected]46c61392012-06-16 00:40:11255TEST_F(ChromotingHostTest, StartAndShutdown) {
sergeyu1b032682015-12-17 03:17:36256 StartHost();
[email protected]1e72daa2011-01-28 21:25:42257}
258
[email protected]46c61392012-06-16 00:40:11259TEST_F(ChromotingHostTest, Connect) {
sergeyu1b032682015-12-17 03:17:36260 StartHost();
[email protected]7aaaa8d2012-07-03 19:26:23261
262 // Shut down the host when the first video packet is received.
sergeyuc18df2ca2015-11-27 03:33:35263 ExpectClientConnected(0);
[email protected]d317a25a2012-06-26 22:58:30264 SimulateClientConnection(0, true, false);
[email protected]66bb70d2012-06-26 20:16:54265}
266
[email protected]d317a25a2012-06-26 22:58:30267TEST_F(ChromotingHostTest, AuthenticationFailed) {
sergeyu1b032682015-12-17 03:17:36268 StartHost();
sergeyuc18df2ca2015-11-27 03:33:35269
270 EXPECT_CALL(host_status_observer_, OnAccessDenied(session_jid1_));
[email protected]d317a25a2012-06-26 22:58:30271 SimulateClientConnection(0, false, false);
[email protected]1e72daa2011-01-28 21:25:42272}
273
[email protected]46c61392012-06-16 00:40:11274TEST_F(ChromotingHostTest, Reconnect) {
sergeyu1b032682015-12-17 03:17:36275 StartHost();
sergeyuc18df2ca2015-11-27 03:33:35276
277 // Connect first client.
278 ExpectClientConnected(0);
[email protected]d317a25a2012-06-26 22:58:30279 SimulateClientConnection(0, true, false);
sergeyuc18df2ca2015-11-27 03:33:35280
281 // Disconnect first client.
282 ExpectClientDisconnected(0);
sergeyu4e1f4cd2016-09-27 00:42:52283 client1_->OnConnectionClosed(protocol::OK);
sergeyuc18df2ca2015-11-27 03:33:35284
285 // Connect second client.
286 ExpectClientConnected(1);
[email protected]d317a25a2012-06-26 22:58:30287 SimulateClientConnection(1, true, false);
sergeyuc18df2ca2015-11-27 03:33:35288
289 // Disconnect second client.
290 ExpectClientDisconnected(1);
sergeyu4e1f4cd2016-09-27 00:42:52291 client2_->OnConnectionClosed(protocol::OK);
[email protected]44f60762011-03-23 12:13:35292}
293
[email protected]46c61392012-06-16 00:40:11294TEST_F(ChromotingHostTest, ConnectWhenAnotherClientIsConnected) {
sergeyu1b032682015-12-17 03:17:36295 StartHost();
sergeyuc18df2ca2015-11-27 03:33:35296
297 // Connect first client.
298 ExpectClientConnected(0);
[email protected]d317a25a2012-06-26 22:58:30299 SimulateClientConnection(0, true, false);
[email protected]37961b12011-03-30 12:39:00300
sergeyuc18df2ca2015-11-27 03:33:35301 // Connect second client. First client should be disconnected automatically.
302 {
303 InSequence s;
304 ExpectClientDisconnected(0);
305 ExpectClientConnected(1);
306 }
307 SimulateClientConnection(1, true, false);
[email protected]da5665e2012-09-13 02:11:33308
sergeyuc18df2ca2015-11-27 03:33:35309 // Disconnect second client.
310 ExpectClientDisconnected(1);
sergeyu4e1f4cd2016-09-27 00:42:52311 client2_->OnConnectionClosed(protocol::OK);
[email protected]d2a6c96f2012-06-29 19:19:19312}
313
[email protected]d2a6c96f2012-06-29 19:19:19314TEST_F(ChromotingHostTest, IncomingSessionAccepted) {
sergeyu1b032682015-12-17 03:17:36315 StartHost();
[email protected]d2a6c96f2012-06-29 19:19:19316
sergeyuc18df2ca2015-11-27 03:33:35317 MockSession* session = session_unowned1_.get();
[email protected]d2a6c96f2012-06-29 19:19:19318 protocol::SessionManager::IncomingSessionResponse response =
319 protocol::SessionManager::DECLINE;
[email protected]7aaaa8d2012-07-03 19:26:23320 host_->OnIncomingSession(session_unowned1_.release(), &response);
[email protected]d2a6c96f2012-06-29 19:19:19321 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
322
sergeyuc18df2ca2015-11-27 03:33:35323 EXPECT_CALL(*session, Close(_)).WillOnce(InvokeWithoutArgs(
324 this, &ChromotingHostTest::NotifyConnectionClosed1));
[email protected]da5665e2012-09-13 02:11:33325 ShutdownHost();
[email protected]d2a6c96f2012-06-29 19:19:19326}
327
Jamie Walch55d02bd2018-05-23 22:48:29328TEST_F(ChromotingHostTest, LoginBackOffTriggersIfClientsDoNotAuthenticate) {
sergeyu1b032682015-12-17 03:17:36329 StartHost();
[email protected]d2a6c96f2012-06-29 19:19:19330
331 protocol::SessionManager::IncomingSessionResponse response =
332 protocol::SessionManager::DECLINE;
Jamie Walch55d02bd2018-05-23 22:48:29333 protocol::Session::EventHandler*
334 session_event_handlers[kNumFailuresIgnored + 1];
335 for (size_t i = 0; i < kNumFailuresIgnored + 1; ++i) {
336 // Set expectations and responses for the new session.
337 auto session = std::make_unique<MockSession>();
338 EXPECT_CALL(*session, jid())
339 .WillRepeatedly(ReturnRef(session_jid1_));
340 EXPECT_CALL(*session, config())
341 .WillRepeatedly(ReturnRef(*session_config1_));
342 EXPECT_CALL(*session, SetEventHandler(_))
343 .Times(AnyNumber())
344 .WillRepeatedly(SaveArg<0>(&session_event_handlers[i]));
345 EXPECT_CALL(*session, Close(_)).WillOnce(
346 InvokeWithoutArgs(
347 [&session_event_handlers, i]() {
348 session_event_handlers[i]->OnSessionStateChange(Session::CLOSED);
349 }));
350 // Simulate the incoming connection.
351 host_->OnIncomingSession(session.release(), &response);
352 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
353 // Begin authentication; this will increase the backoff count, and since
354 // OnSessionAuthenticated is never called, the host should only allow
355 // kNumFailuresIgnored + 1 connections before beginning the backoff.
356 host_->OnSessionAuthenticating(
357 host_->client_sessions_for_tests().front().get());
358 }
[email protected]064128c2014-04-07 22:33:28359
Jamie Walch55d02bd2018-05-23 22:48:29360 // As this is connection kNumFailuresIgnored + 2, it should be rejected.
[email protected]7aaaa8d2012-07-03 19:26:23361 host_->OnIncomingSession(session_unowned2_.get(), &response);
[email protected]d2a6c96f2012-06-29 19:19:19362 EXPECT_EQ(protocol::SessionManager::OVERLOAD, response);
Jamie Walch55d02bd2018-05-23 22:48:29363 EXPECT_EQ(host_->client_sessions_for_tests().size(), kNumFailuresIgnored + 1);
364
365 // Shut down host while objects owned by this test are still in scope.
366 ShutdownHost();
[email protected]d2a6c96f2012-06-29 19:19:19367}
368
Jamie Walch55d02bd2018-05-23 22:48:29369TEST_F(ChromotingHostTest, LoginBackOffResetsIfClientsAuthenticate) {
sergeyu1b032682015-12-17 03:17:36370 StartHost();
sergeyuc18df2ca2015-11-27 03:33:35371
[email protected]064128c2014-04-07 22:33:28372 protocol::SessionManager::IncomingSessionResponse response =
373 protocol::SessionManager::DECLINE;
Jamie Walch55d02bd2018-05-23 22:48:29374 protocol::Session::EventHandler*
375 session_event_handlers[kNumFailuresIgnored + 1];
376 for (size_t i = 0; i < kNumFailuresIgnored + 1; ++i) {
377 // Set expectations and responses for the new session.
378 auto session = std::make_unique<MockSession>();
379 EXPECT_CALL(*session, jid())
380 .WillRepeatedly(ReturnRef(session_jid1_));
381 EXPECT_CALL(*session, config())
382 .WillRepeatedly(ReturnRef(*session_config1_));
383 EXPECT_CALL(*session, SetEventHandler(_))
384 .Times(AnyNumber())
385 .WillRepeatedly(SaveArg<0>(&session_event_handlers[i]));
386 EXPECT_CALL(*session, Close(_)).WillOnce(
387 InvokeWithoutArgs(
388 [&session_event_handlers, i]() {
389 session_event_handlers[i]->OnSessionStateChange(Session::CLOSED);
390 }));
391 // Simulate the incoming connection.
392 host_->OnIncomingSession(session.release(), &response);
393 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
394 // Begin authentication; this will increase the backoff count
395 host_->OnSessionAuthenticating(
396 host_->client_sessions_for_tests().front().get());
397 }
[email protected]064128c2014-04-07 22:33:28398
Jamie Walch55d02bd2018-05-23 22:48:29399 // Simulate successful authentication for one of the previous connections.
400 // This should reset the backoff and disconnect all the other connections.
401 host_->OnSessionAuthenticated(
sergeyub047307a2016-10-18 17:19:29402 host_->client_sessions_for_tests().front().get());
sergeyub047307a2016-10-18 17:19:29403 EXPECT_EQ(host_->client_sessions_for_tests().size(), 1U);
Jamie Walch55d02bd2018-05-23 22:48:29404
405 // This is connection kNumFailuresIgnored + 2, but since we now have a
406 // successful authentication it should not be rejected.
407 auto session = std::make_unique<MockSession>();
408 protocol::Session::EventHandler* session_event_handler;
409 EXPECT_CALL(*session, jid())
410 .WillRepeatedly(ReturnRef(session_jid1_));
411 EXPECT_CALL(*session, config())
412 .WillRepeatedly(ReturnRef(*session_config1_));
413 EXPECT_CALL(*session, SetEventHandler(_))
414 .Times(AnyNumber())
415 .WillRepeatedly(SaveArg<0>(&session_event_handler));
416 EXPECT_CALL(*session, Close(_)).WillOnce(
417 InvokeWithoutArgs(
418 [&session_event_handler]() {
419 session_event_handler->OnSessionStateChange(Session::CLOSED);
420 }));
421 host_->OnIncomingSession(session.release(), &response);
422 EXPECT_EQ(protocol::SessionManager::ACCEPT, response);
423
424 // Shut down host while objects owned by this test are still in scope.
425 ShutdownHost();
[email protected]064128c2014-04-07 22:33:28426}
427
[email protected]e5ecce02012-07-03 20:34:23428TEST_F(ChromotingHostTest, OnSessionRouteChange) {
sergeyu1b032682015-12-17 03:17:36429 StartHost();
sergeyuc18df2ca2015-11-27 03:33:35430
431
432 ExpectClientConnected(0);
433 SimulateClientConnection(0, true, false);
434
[email protected]e5ecce02012-07-03 20:34:23435 std::string channel_name("ChannelName");
436 protocol::TransportRoute route;
sergeyuc18df2ca2015-11-27 03:33:35437 EXPECT_CALL(host_status_observer_,
438 OnClientRouteChange(session_jid1_, channel_name, _));
439 host_->OnSessionRouteChange(get_client(0), channel_name, route);
[email protected]e5ecce02012-07-03 20:34:23440}
441
[email protected]1e72daa2011-01-28 21:25:42442} // namespace remoting