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