Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/task.h" | 5 #include "base/task.h" |
| 6 #include "remoting/host/capturer_fake.h" | 6 #include "remoting/host/capturer_fake.h" |
| 7 #include "remoting/host/chromoting_host.h" | 7 #include "remoting/host/chromoting_host.h" |
| 8 #include "remoting/host/chromoting_host_context.h" | 8 #include "remoting/host/chromoting_host_context.h" |
| 9 #include "remoting/host/desktop_environment_fake.h" | |
| 10 #include "remoting/host/host_mock_objects.h" | 9 #include "remoting/host/host_mock_objects.h" |
| 11 #include "remoting/host/in_memory_host_config.h" | 10 #include "remoting/host/in_memory_host_config.h" |
| 12 #include "remoting/proto/video.pb.h" | 11 #include "remoting/proto/video.pb.h" |
| 13 #include "remoting/protocol/protocol_mock_objects.h" | 12 #include "remoting/protocol/protocol_mock_objects.h" |
| 14 #include "remoting/protocol/session_config.h" | 13 #include "remoting/protocol/session_config.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 16 |
| 18 using ::remoting::protocol::LocalLoginCredentials; | 17 using ::remoting::protocol::LocalLoginCredentials; |
| 19 using ::remoting::protocol::MockClientStub; | 18 using ::remoting::protocol::MockClientStub; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 34 using testing::Return; | 33 using testing::Return; |
| 35 | 34 |
| 36 namespace remoting { | 35 namespace remoting { |
| 37 | 36 |
| 38 namespace { | 37 namespace { |
| 39 | 38 |
| 40 void PostQuitTask(MessageLoop* message_loop) { | 39 void PostQuitTask(MessageLoop* message_loop) { |
| 41 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 40 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 42 } | 41 } |
| 43 | 42 |
| 44 void BeginSessionRequest(protocol::HostStub* host_stub) { | |
| 45 LocalLoginCredentials* credentials = | |
| 46 new LocalLoginCredentials(); | |
| 47 credentials->set_type(protocol::PASSWORD); | |
| 48 credentials->set_username("hello"); | |
| 49 | |
| 50 const std::string password = "world!"; | |
| 51 credentials->set_credential(password.data(), password.length()); | |
| 52 | |
| 53 host_stub->BeginSessionRequest( | |
| 54 credentials, | |
| 55 new DeleteTask<LocalLoginCredentials>(credentials)); | |
| 56 } | |
| 57 | |
| 58 // Run the task and delete it afterwards. This action is used to deal with | 43 // Run the task and delete it afterwards. This action is used to deal with |
| 59 // done callbacks. | 44 // done callbacks. |
| 60 ACTION(RunDoneTask) { | 45 ACTION(RunDoneTask) { |
| 61 arg1->Run(); | 46 arg1->Run(); |
| 62 delete arg1; | 47 delete arg1; |
| 63 } | 48 } |
| 64 | 49 |
| 65 ACTION_P(QuitMainMessageLoop, message_loop) { | 50 ACTION_P(QuitMainMessageLoop, message_loop) { |
| 66 PostQuitTask(message_loop); | 51 PostQuitTask(message_loop); |
| 67 } | 52 } |
| 68 | 53 |
| 69 } // namepace | 54 } // namespace |
| 70 | 55 |
| 71 class ChromotingHostTest : public testing::Test { | 56 class ChromotingHostTest : public testing::Test { |
| 72 public: | 57 public: |
| 73 ChromotingHostTest() { | 58 ChromotingHostTest() { |
| 74 } | 59 } |
| 75 | 60 |
| 76 virtual void SetUp() { | 61 virtual void SetUp() { |
| 77 config_ = new InMemoryHostConfig(); | 62 config_ = new InMemoryHostConfig(); |
| 78 ON_CALL(context_, main_message_loop()) | 63 ON_CALL(context_, main_message_loop()) |
| 79 .WillByDefault(Return(&message_loop_)); | 64 .WillByDefault(Return(&message_loop_)); |
| 80 ON_CALL(context_, encode_message_loop()) | 65 ON_CALL(context_, encode_message_loop()) |
| 81 .WillByDefault(Return(&message_loop_)); | 66 .WillByDefault(Return(&message_loop_)); |
| 82 ON_CALL(context_, network_message_loop()) | 67 ON_CALL(context_, network_message_loop()) |
| 83 .WillByDefault(Return(&message_loop_)); | 68 .WillByDefault(Return(&message_loop_)); |
| 84 EXPECT_CALL(context_, main_message_loop()) | 69 EXPECT_CALL(context_, main_message_loop()) |
| 85 .Times(AnyNumber()); | 70 .Times(AnyNumber()); |
| 86 EXPECT_CALL(context_, encode_message_loop()) | 71 EXPECT_CALL(context_, encode_message_loop()) |
| 87 .Times(AnyNumber()); | 72 .Times(AnyNumber()); |
| 88 EXPECT_CALL(context_, network_message_loop()) | 73 EXPECT_CALL(context_, network_message_loop()) |
| 89 .Times(AnyNumber()); | 74 .Times(AnyNumber()); |
| 90 | 75 |
| 91 Capturer* capturer = new CapturerFake(context_.main_message_loop()); | 76 Capturer* capturer = new CapturerFake(context_.main_message_loop()); |
| 92 host_stub_ = new MockHostStub(); | 77 host_stub_ = new MockHostStub(); |
| 78 host_stub2_ = new MockHostStub(); | |
| 93 input_stub_ = new MockInputStub(); | 79 input_stub_ = new MockInputStub(); |
| 80 input_stub2_ = new MockInputStub(); | |
| 94 DesktopEnvironment* desktop = | 81 DesktopEnvironment* desktop = |
| 95 new DesktopEnvironmentFake(capturer, input_stub_); | 82 new DesktopEnvironment(capturer, input_stub_); |
| 96 host_ = ChromotingHost::Create(&context_, config_, desktop); | 83 host_ = ChromotingHost::Create(&context_, config_, desktop); |
| 97 connection_ = new MockConnectionToClient( | 84 connection_ = new MockConnectionToClient( |
| 98 &message_loop_, &handler_, host_stub_, input_stub_); | 85 &message_loop_, &handler_, host_stub_, input_stub_); |
| 86 connection2_ = new MockConnectionToClient( | |
| 87 &message_loop_, &handler_, host_stub2_, input_stub2_); | |
| 99 session_ = new MockSession(); | 88 session_ = new MockSession(); |
| 89 session2_ = new MockSession(); | |
| 100 session_config_.reset(SessionConfig::CreateDefault()); | 90 session_config_.reset(SessionConfig::CreateDefault()); |
| 91 session_config2_.reset(SessionConfig::CreateDefault()); | |
| 101 | 92 |
| 102 ON_CALL(video_stub_, ProcessVideoPacket(_, _)) | 93 ON_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 103 .WillByDefault( | 94 .WillByDefault( |
| 104 DoAll(DeleteArg<0>(), DeleteArg<1>())); | 95 DoAll(DeleteArg<0>(), DeleteArg<1>())); |
| 96 ON_CALL(video_stub2_, ProcessVideoPacket(_, _)) | |
| 97 .WillByDefault( | |
| 98 DoAll(DeleteArg<0>(), DeleteArg<1>())); | |
| 105 ON_CALL(*connection_.get(), video_stub()) | 99 ON_CALL(*connection_.get(), video_stub()) |
| 106 .WillByDefault(Return(&video_stub_)); | 100 .WillByDefault(Return(&video_stub_)); |
| 107 ON_CALL(*connection_.get(), client_stub()) | 101 ON_CALL(*connection_.get(), client_stub()) |
| 108 .WillByDefault(Return(&client_stub_)); | 102 .WillByDefault(Return(&client_stub_)); |
| 109 ON_CALL(*connection_.get(), session()) | 103 ON_CALL(*connection_.get(), session()) |
| 110 .WillByDefault(Return(session_)); | 104 .WillByDefault(Return(session_)); |
| 105 ON_CALL(*connection2_.get(), video_stub()) | |
| 106 .WillByDefault(Return(&video_stub2_)); | |
| 107 ON_CALL(*connection2_.get(), client_stub()) | |
| 108 .WillByDefault(Return(&client_stub2_)); | |
| 109 ON_CALL(*connection2_.get(), session()) | |
| 110 .WillByDefault(Return(session2_)); | |
| 111 ON_CALL(*session_.get(), config()) | 111 ON_CALL(*session_.get(), config()) |
| 112 .WillByDefault(Return(session_config_.get())); | 112 .WillByDefault(Return(session_config_.get())); |
| 113 ON_CALL(*session2_.get(), config()) | |
| 114 .WillByDefault(Return(session_config2_.get())); | |
| 113 EXPECT_CALL(*connection_.get(), video_stub()) | 115 EXPECT_CALL(*connection_.get(), video_stub()) |
| 114 .Times(AnyNumber()); | 116 .Times(AnyNumber()); |
| 115 EXPECT_CALL(*connection_.get(), client_stub()) | 117 EXPECT_CALL(*connection_.get(), client_stub()) |
| 116 .Times(AnyNumber()); | 118 .Times(AnyNumber()); |
| 117 EXPECT_CALL(*connection_.get(), session()) | 119 EXPECT_CALL(*connection_.get(), session()) |
| 118 .Times(AnyNumber()); | 120 .Times(AnyNumber()); |
| 121 EXPECT_CALL(*connection2_.get(), video_stub()) | |
| 122 .Times(AnyNumber()); | |
| 123 EXPECT_CALL(*connection2_.get(), client_stub()) | |
| 124 .Times(AnyNumber()); | |
| 125 EXPECT_CALL(*connection2_.get(), session()) | |
| 126 .Times(AnyNumber()); | |
| 119 EXPECT_CALL(*session_.get(), config()) | 127 EXPECT_CALL(*session_.get(), config()) |
| 120 .Times(AnyNumber()); | 128 .Times(AnyNumber()); |
| 129 EXPECT_CALL(*session2_.get(), config()) | |
| 130 .Times(AnyNumber()); | |
| 131 | |
| 121 } | 132 } |
| 122 | 133 |
| 123 virtual void TearDown() { | 134 virtual void TearDown() { |
| 124 } | 135 } |
| 125 | 136 |
| 126 // Helper metjod to pretend a client is connected to ChromotingHost. | 137 // Helper method to pretend a client is connected to ChromotingHost. |
| 127 void SimulateClientConnection() { | 138 void SimulateClientConnection(int connection_index) { |
| 139 scoped_refptr<MockConnectionToClient> connection = | |
| 140 (connection_index == 0) ? connection_ : connection2_; | |
| 141 scoped_refptr<ClientSession> client = new ClientSession(host_.get(), | |
| 142 connection); | |
| 143 connection->set_host_stub(client.get()); | |
| 144 | |
| 128 context_.network_message_loop()->PostTask( | 145 context_.network_message_loop()->PostTask( |
| 129 FROM_HERE, | 146 FROM_HERE, |
| 130 NewRunnableMethod(host_.get(), | 147 NewRunnableMethod(host_.get(), |
| 131 &ChromotingHost::set_connection, | 148 &ChromotingHost::add_client, |
| 132 connection_)); | 149 client)); |
| 133 context_.network_message_loop()->PostTask( | 150 context_.network_message_loop()->PostTask( |
| 134 FROM_HERE, | 151 FROM_HERE, |
| 135 NewRunnableMethod(host_.get(), | 152 NewRunnableMethod(host_.get(), |
| 136 &ChromotingHost::OnClientConnected, | 153 &ChromotingHost::OnClientConnected, |
| 137 connection_)); | 154 connection)); |
| 138 context_.network_message_loop()->PostTask( | 155 context_.network_message_loop()->PostTask( |
| 139 FROM_HERE, | 156 FROM_HERE, |
| 140 NewRunnableFunction(&BeginSessionRequest, host_->host_stub())); | 157 NewRunnableMethod(host_.get(), |
| 158 &ChromotingHost::LocalLoginSucceeded, | |
| 159 connection)); | |
| 141 } | 160 } |
| 142 | 161 |
| 143 // Helper method to remove a client connection from ChromotongHost. | 162 void SimulateSecondClientConnection() { |
|
awong
2011/03/22 15:11:56
This is nit-picky, but I dislike the lack of symme
simonmorris
2011/03/23 10:35:20
Done (with CreateFunctor).
| |
| 163 SimulateClientConnection(1); | |
| 164 } | |
| 165 | |
| 166 // Helper method to remove a client connection from ChromotingHost. | |
| 144 void RemoveClientConnection() { | 167 void RemoveClientConnection() { |
| 145 context_.network_message_loop()->PostTask( | 168 context_.network_message_loop()->PostTask( |
| 146 FROM_HERE, | 169 FROM_HERE, |
| 147 NewRunnableMethod(host_.get(), | 170 NewRunnableMethod(host_.get(), |
| 148 &ChromotingHost::OnClientDisconnected, | 171 &ChromotingHost::OnClientDisconnected, |
| 149 connection_)); | 172 connection_)); |
| 150 } | 173 } |
| 151 | 174 |
| 152 protected: | 175 protected: |
| 153 MessageLoop message_loop_; | 176 MessageLoop message_loop_; |
| 154 MockConnectionToClientEventHandler handler_; | 177 MockConnectionToClientEventHandler handler_; |
| 155 scoped_refptr<ChromotingHost> host_; | 178 scoped_refptr<ChromotingHost> host_; |
| 156 scoped_refptr<InMemoryHostConfig> config_; | 179 scoped_refptr<InMemoryHostConfig> config_; |
| 157 MockChromotingHostContext context_; | 180 MockChromotingHostContext context_; |
| 158 scoped_refptr<MockConnectionToClient> connection_; | 181 scoped_refptr<MockConnectionToClient> connection_; |
| 159 scoped_refptr<MockSession> session_; | 182 scoped_refptr<MockSession> session_; |
| 160 scoped_ptr<SessionConfig> session_config_; | 183 scoped_ptr<SessionConfig> session_config_; |
| 161 MockVideoStub video_stub_; | 184 MockVideoStub video_stub_; |
| 162 MockClientStub client_stub_; | 185 MockClientStub client_stub_; |
| 163 MockHostStub* host_stub_; | 186 MockHostStub* host_stub_; |
| 164 MockInputStub* input_stub_; | 187 MockInputStub* input_stub_; |
| 188 scoped_refptr<MockConnectionToClient> connection2_; | |
| 189 scoped_refptr<MockSession> session2_; | |
| 190 scoped_ptr<SessionConfig> session_config2_; | |
| 191 MockVideoStub video_stub2_; | |
| 192 MockClientStub client_stub2_; | |
| 193 MockHostStub* host_stub2_; | |
| 194 MockInputStub* input_stub2_; | |
| 165 }; | 195 }; |
| 166 | 196 |
| 167 TEST_F(ChromotingHostTest, StartAndShutdown) { | 197 TEST_F(ChromotingHostTest, StartAndShutdown) { |
| 168 host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); | 198 host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); |
| 169 | 199 |
| 170 message_loop_.PostTask(FROM_HERE, | 200 message_loop_.PostTask(FROM_HERE, |
| 171 NewRunnableMethod(host_.get(), | 201 NewRunnableMethod(host_.get(), |
| 172 &ChromotingHost::Shutdown)); | 202 &ChromotingHost::Shutdown)); |
| 173 message_loop_.Run(); | 203 message_loop_.Run(); |
| 174 } | 204 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 185 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | 215 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 186 .WillOnce(DoAll( | 216 .WillOnce(DoAll( |
| 187 InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), | 217 InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), |
| 188 RunDoneTask())) | 218 RunDoneTask())) |
| 189 .RetiresOnSaturation(); | 219 .RetiresOnSaturation(); |
| 190 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | 220 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 191 .Times(AnyNumber()); | 221 .Times(AnyNumber()); |
| 192 EXPECT_CALL(*connection_.get(), Disconnect()) | 222 EXPECT_CALL(*connection_.get(), Disconnect()) |
| 193 .RetiresOnSaturation(); | 223 .RetiresOnSaturation(); |
| 194 | 224 |
| 195 SimulateClientConnection(); | 225 SimulateClientConnection(0); |
| 196 message_loop_.Run(); | 226 message_loop_.Run(); |
| 197 } | 227 } |
| 198 | 228 |
| 199 TEST_F(ChromotingHostTest, Reconnect) { | 229 TEST_F(ChromotingHostTest, Reconnect) { |
| 200 host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); | 230 host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); |
| 201 | 231 |
| 202 EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) | 232 EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) |
| 203 .Times(2) | 233 .Times(2) |
| 204 .WillRepeatedly(RunDoneTask()); | 234 .WillRepeatedly(RunDoneTask()); |
| 205 | 235 |
| 206 // When the video packet is received we first disconnect the mock | 236 // When the video packet is received we first disconnect the mock |
| 207 // connection. | 237 // connection. |
| 208 { | 238 { |
| 209 InSequence s; | 239 InSequence s; |
| 210 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | 240 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 211 .WillOnce(DoAll( | 241 .WillOnce(DoAll( |
| 212 InvokeWithoutArgs(this, | 242 InvokeWithoutArgs(this, |
| 213 &ChromotingHostTest::RemoveClientConnection), | 243 &ChromotingHostTest::RemoveClientConnection), |
| 214 RunDoneTask())) | 244 RunDoneTask())) |
| 215 .RetiresOnSaturation(); | 245 .RetiresOnSaturation(); |
| 216 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | 246 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 217 .Times(AnyNumber()); | 247 .Times(AnyNumber()); |
| 218 } | 248 } |
| 219 | 249 |
| 220 // If Disconnect() is called we can break the main message loop. | 250 // If Disconnect() is called we can break the main message loop. |
| 221 EXPECT_CALL(*connection_.get(), Disconnect()) | 251 EXPECT_CALL(*connection_.get(), Disconnect()) |
| 222 .WillOnce(QuitMainMessageLoop(&message_loop_)) | 252 .WillOnce(QuitMainMessageLoop(&message_loop_)) |
| 223 .RetiresOnSaturation(); | 253 .RetiresOnSaturation(); |
| 224 | 254 |
| 225 SimulateClientConnection(); | 255 SimulateClientConnection(0); |
| 226 message_loop_.Run(); | 256 message_loop_.Run(); |
| 227 | 257 |
| 228 // Connect the client again. | 258 // Connect the client again. |
| 229 { | 259 { |
| 230 InSequence s; | 260 InSequence s; |
| 231 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | 261 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 232 .WillOnce(DoAll( | 262 .WillOnce(DoAll( |
| 233 InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), | 263 InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), |
| 234 RunDoneTask())) | 264 RunDoneTask())) |
| 235 .RetiresOnSaturation(); | 265 .RetiresOnSaturation(); |
| 236 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | 266 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) |
| 237 .Times(AnyNumber()); | 267 .Times(AnyNumber()); |
| 238 } | 268 } |
| 239 EXPECT_CALL(*connection_.get(), Disconnect()) | 269 EXPECT_CALL(*connection_.get(), Disconnect()) |
| 240 .RetiresOnSaturation(); | 270 .RetiresOnSaturation(); |
| 241 | 271 |
| 242 SimulateClientConnection(); | 272 SimulateClientConnection(0); |
| 243 message_loop_.Run(); | 273 message_loop_.Run(); |
| 244 } | 274 } |
| 245 | 275 |
| 276 TEST_F(ChromotingHostTest, ConnectTwice) { | |
| 277 host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); | |
| 278 | |
| 279 EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) | |
| 280 .Times(1) | |
| 281 .WillRepeatedly(RunDoneTask()); | |
| 282 | |
| 283 EXPECT_CALL(client_stub2_, BeginSessionResponse(_, _)) | |
| 284 .Times(1) | |
| 285 .WillRepeatedly(RunDoneTask()); | |
| 286 | |
| 287 // When a video packet is received we connect the second mock | |
| 288 // connection. | |
| 289 { | |
| 290 InSequence s; | |
|
awong
2011/03/22 15:11:56
I'm always a little dubious when I see InSequences
simonmorris
2011/03/23 10:35:20
I think it's worth knowing that no video is sent t
| |
| 291 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | |
| 292 .WillOnce(DoAll( | |
| 293 InvokeWithoutArgs( | |
| 294 this, &ChromotingHostTest::SimulateSecondClientConnection), | |
| 295 RunDoneTask())) | |
| 296 .RetiresOnSaturation(); | |
| 297 EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) | |
| 298 .Times(AnyNumber()); | |
| 299 EXPECT_CALL(video_stub2_, ProcessVideoPacket(_, _)) | |
| 300 .WillOnce(DoAll( | |
| 301 InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), | |
| 302 RunDoneTask())) | |
| 303 .RetiresOnSaturation(); | |
| 304 EXPECT_CALL(video_stub2_, ProcessVideoPacket(_, _)) | |
| 305 .Times(AnyNumber()); | |
| 306 } | |
| 307 | |
| 308 EXPECT_CALL(*connection_.get(), Disconnect()) | |
| 309 .RetiresOnSaturation(); | |
| 310 EXPECT_CALL(*connection2_.get(), Disconnect()) | |
| 311 .RetiresOnSaturation(); | |
| 312 | |
| 313 SimulateClientConnection(0); | |
| 314 message_loop_.Run(); | |
| 315 } | |
| 316 | |
| 246 } // namespace remoting | 317 } // namespace remoting |
| OLD | NEW |