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 |