Home | History | Annotate | Download | only in host
      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 
     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.
     59 ACTION(RunDoneTask) {
     60   arg1.Run();
     61 }
     62 
     63 }  // namespace
     64 
     65 class ChromotingHostTest : public testing::Test {
     66  public:
     67   ChromotingHostTest() {
     68   }
     69 
     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.
    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 
    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_|.
    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().
    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().
    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().
    266   webrtc::ScreenCapturer* CreateVideoCapturer() {
    267     return new ScreenCapturerFake();
    268   }
    269 
    270   void DisconnectAllClients() {
    271     host_->DisconnectAllClients();
    272   }
    273 
    274   // Helper method to disconnect client 1 from the host.
    275   void DisconnectClient1() {
    276     NotifyClientSessionClosed(0);
    277   }
    278 
    279   // Notify |host_| that the authenticating client has been rejected.
    280   void RejectAuthenticatingClient() {
    281     host_->RejectAuthenticatingClient();
    282   }
    283 
    284   // Notify |host_| that a client session has closed.
    285   void NotifyClientSessionClosed(int connection_index) {
    286     get_client(connection_index)->OnConnectionClosed(
    287         get_connection(connection_index), protocol::OK);
    288   }
    289 
    290   void SetEventHandler(protocol::Session::EventHandler* event_handler) {
    291     session_event_handler_ = event_handler;
    292   }
    293 
    294   void NotifyConnectionClosed() {
    295     if (session_event_handler_) {
    296       session_event_handler_->OnSessionStateChange(protocol::Session::CLOSED);
    297     }
    298   }
    299 
    300   void ShutdownHost() {
    301     task_runner_->PostTask(
    302         FROM_HERE,
    303         base::Bind(&ChromotingHostTest::StopAndReleaseTaskRunner,
    304                    base::Unretained(this)));
    305   }
    306 
    307   void StopAndReleaseTaskRunner() {
    308     host_.reset();
    309     task_runner_ = NULL;
    310     desktop_environment_factory_.reset();
    311   }
    312 
    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.
    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>
    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>
    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>
    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 
    431   MockConnectionToClient*& get_connection(int connection_index) {
    432     return (connection_index == 0) ? connection1_ : connection2_;
    433   }
    434 
    435   ClientSession*& get_client(int connection_index) {
    436     return (connection_index == 0) ? client1_ : client2_;
    437   }
    438 
    439   const std::string& get_session_jid(int connection_index) {
    440     return (connection_index == 0) ? session_jid1_ : session_jid2_;
    441   }
    442 
    443   MockVideoStub& get_video_stub(int connection_index) {
    444     return (connection_index == 0) ? video_stub1_ : video_stub2_;
    445   }
    446 };
    447 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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