OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "remoting/host/setup/native_messaging_host.h" | 5 #include "remoting/host/setup/native_messaging_host.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/strings/stringize_macros.h" | 14 #include "base/strings/stringize_macros.h" |
15 #include "base/values.h" | 15 #include "base/values.h" |
16 #include "google_apis/gaia/gaia_oauth_client.h" | 16 #include "google_apis/gaia/gaia_oauth_client.h" |
17 #include "net/base/file_stream.h" | 17 #include "net/base/file_stream.h" |
18 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
| 19 #include "remoting/base/auto_thread_task_runner.h" |
19 #include "remoting/host/pin_hash.h" | 20 #include "remoting/host/pin_hash.h" |
20 #include "remoting/host/setup/test_util.h" | 21 #include "remoting/host/setup/test_util.h" |
21 #include "remoting/protocol/pairing_registry.h" | 22 #include "remoting/protocol/pairing_registry.h" |
22 #include "remoting/protocol/protocol_mock_objects.h" | 23 #include "remoting/protocol/protocol_mock_objects.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
24 | 25 |
25 using remoting::protocol::MockPairingRegistryDelegate; | 26 using remoting::protocol::MockPairingRegistryDelegate; |
26 using remoting::protocol::PairingRegistry; | 27 using remoting::protocol::PairingRegistry; |
27 using remoting::protocol::SynchronousPairingRegistry; | 28 using remoting::protocol::SynchronousPairingRegistry; |
28 | 29 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 EXPECT_TRUE(response->GetString("type", &value)); | 124 EXPECT_TRUE(response->GetString("type", &value)); |
124 EXPECT_EQ("startDaemonResponse", value); | 125 EXPECT_EQ("startDaemonResponse", value); |
125 EXPECT_TRUE(response->GetString("result", &value)); | 126 EXPECT_TRUE(response->GetString("result", &value)); |
126 EXPECT_EQ("OK", value); | 127 EXPECT_EQ("OK", value); |
127 } | 128 } |
128 | 129 |
129 } // namespace | 130 } // namespace |
130 | 131 |
131 namespace remoting { | 132 namespace remoting { |
132 | 133 |
133 class MockDaemonController : public DaemonController { | 134 class MockDaemonControllerDelegate : public DaemonController::Delegate { |
134 public: | 135 public: |
135 MockDaemonController(); | 136 MockDaemonControllerDelegate(); |
136 virtual ~MockDaemonController(); | 137 virtual ~MockDaemonControllerDelegate(); |
137 | 138 |
138 virtual State GetState() OVERRIDE; | 139 // DaemonController::Delegate interface. |
139 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; | 140 virtual DaemonController::State GetState() OVERRIDE; |
140 virtual void SetConfigAndStart(scoped_ptr<base::DictionaryValue> config, | 141 virtual scoped_ptr<base::DictionaryValue> GetConfig() OVERRIDE; |
141 bool consent, | 142 virtual void SetConfigAndStart( |
142 const CompletionCallback& callback) OVERRIDE; | 143 scoped_ptr<base::DictionaryValue> config, |
143 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, | 144 bool consent, |
144 const CompletionCallback& callback) OVERRIDE; | 145 const DaemonController::CompletionCallback& done) OVERRIDE; |
145 virtual void Stop(const CompletionCallback& callback) OVERRIDE; | 146 virtual void UpdateConfig( |
| 147 scoped_ptr<base::DictionaryValue> config, |
| 148 const DaemonController::CompletionCallback& done) OVERRIDE; |
| 149 virtual void Stop(const DaemonController::CompletionCallback& done) OVERRIDE; |
146 virtual void SetWindow(void* window_handle) OVERRIDE; | 150 virtual void SetWindow(void* window_handle) OVERRIDE; |
147 virtual void GetVersion(const GetVersionCallback& callback) OVERRIDE; | 151 virtual std::string GetVersion() OVERRIDE; |
148 virtual void GetUsageStatsConsent( | 152 virtual DaemonController::UsageStatsConsent GetUsageStatsConsent() OVERRIDE; |
149 const GetUsageStatsConsentCallback& callback) OVERRIDE; | |
150 | 153 |
151 private: | 154 private: |
152 DISALLOW_COPY_AND_ASSIGN(MockDaemonController); | 155 DISALLOW_COPY_AND_ASSIGN(MockDaemonControllerDelegate); |
153 }; | 156 }; |
154 | 157 |
155 MockDaemonController::MockDaemonController() {} | 158 MockDaemonControllerDelegate::MockDaemonControllerDelegate() {} |
156 | 159 |
157 MockDaemonController::~MockDaemonController() {} | 160 MockDaemonControllerDelegate::~MockDaemonControllerDelegate() {} |
158 | 161 |
159 DaemonController::State MockDaemonController::GetState() { | 162 DaemonController::State MockDaemonControllerDelegate::GetState() { |
160 return DaemonController::STATE_STARTED; | 163 return DaemonController::STATE_STARTED; |
161 } | 164 } |
162 | 165 |
163 void MockDaemonController::GetConfig(const GetConfigCallback& callback) { | 166 scoped_ptr<base::DictionaryValue> MockDaemonControllerDelegate::GetConfig() { |
164 scoped_ptr<base::DictionaryValue> config(new base::DictionaryValue()); | 167 return scoped_ptr<base::DictionaryValue>(new base::DictionaryValue()); |
165 callback.Run(config.Pass()); | |
166 } | 168 } |
167 | 169 |
168 void MockDaemonController::SetConfigAndStart( | 170 void MockDaemonControllerDelegate::SetConfigAndStart( |
169 scoped_ptr<base::DictionaryValue> config, bool consent, | 171 scoped_ptr<base::DictionaryValue> config, |
170 const CompletionCallback& callback) { | 172 bool consent, |
| 173 const DaemonController::CompletionCallback& done) { |
171 | 174 |
172 // Verify parameters passed in. | 175 // Verify parameters passed in. |
173 if (consent && config && config->HasKey("start")) { | 176 if (consent && config && config->HasKey("start")) { |
174 callback.Run(DaemonController::RESULT_OK); | 177 done.Run(DaemonController::RESULT_OK); |
175 } else { | 178 } else { |
176 callback.Run(DaemonController::RESULT_FAILED); | 179 done.Run(DaemonController::RESULT_FAILED); |
177 } | 180 } |
178 } | 181 } |
179 | 182 |
180 void MockDaemonController::UpdateConfig( | 183 void MockDaemonControllerDelegate::UpdateConfig( |
181 scoped_ptr<base::DictionaryValue> config, | 184 scoped_ptr<base::DictionaryValue> config, |
182 const CompletionCallback& callback) { | 185 const DaemonController::CompletionCallback& done) { |
183 if (config && config->HasKey("update")) { | 186 if (config && config->HasKey("update")) { |
184 callback.Run(DaemonController::RESULT_OK); | 187 done.Run(DaemonController::RESULT_OK); |
185 } else { | 188 } else { |
186 callback.Run(DaemonController::RESULT_FAILED); | 189 done.Run(DaemonController::RESULT_FAILED); |
187 } | 190 } |
188 } | 191 } |
189 | 192 |
190 void MockDaemonController::Stop(const CompletionCallback& callback) { | 193 void MockDaemonControllerDelegate::Stop( |
191 callback.Run(DaemonController::RESULT_OK); | 194 const DaemonController::CompletionCallback& done) { |
| 195 done.Run(DaemonController::RESULT_OK); |
192 } | 196 } |
193 | 197 |
194 void MockDaemonController::SetWindow(void* window_handle) {} | 198 void MockDaemonControllerDelegate::SetWindow(void* window_handle) {} |
195 | 199 |
196 void MockDaemonController::GetVersion(const GetVersionCallback& callback) { | 200 std::string MockDaemonControllerDelegate::GetVersion() { |
197 // Unused - NativeMessagingHost returns the compiled-in version string | 201 // Unused - NativeMessagingHost returns the compiled-in version string |
198 // instead of calling this method. | 202 // instead of calling this method. |
| 203 NOTREACHED(); |
| 204 return std::string(); |
199 } | 205 } |
200 | 206 |
201 void MockDaemonController::GetUsageStatsConsent( | 207 DaemonController::UsageStatsConsent |
202 const GetUsageStatsConsentCallback& callback) { | 208 MockDaemonControllerDelegate::GetUsageStatsConsent() { |
203 callback.Run(true, true, true); | 209 DaemonController::UsageStatsConsent consent; |
| 210 consent.supported = true; |
| 211 consent.allowed = true; |
| 212 consent.set_by_policy = true; |
| 213 return consent; |
204 } | 214 } |
205 | 215 |
206 class NativeMessagingHostTest : public testing::Test { | 216 class NativeMessagingHostTest : public testing::Test { |
207 public: | 217 public: |
208 NativeMessagingHostTest(); | 218 NativeMessagingHostTest(); |
209 virtual ~NativeMessagingHostTest(); | 219 virtual ~NativeMessagingHostTest(); |
210 | 220 |
211 virtual void SetUp() OVERRIDE; | 221 virtual void SetUp() OVERRIDE; |
212 virtual void TearDown() OVERRIDE; | 222 virtual void TearDown() OVERRIDE; |
213 | 223 |
214 void Run(); | 224 void Run(); |
215 | 225 |
| 226 // Deletes |host_|. |
| 227 void DeleteHost(); |
| 228 |
216 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); | 229 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); |
217 | 230 |
218 void WriteMessageToInputPipe(const base::Value& message); | 231 void WriteMessageToInputPipe(const base::Value& message); |
219 | 232 |
220 // The Host process should shut down when it receives a malformed request. | 233 // The Host process should shut down when it receives a malformed request. |
221 // This is tested by sending a known-good request, followed by |message|, | 234 // This is tested by sending a known-good request, followed by |message|, |
222 // followed by the known-good request again. The response file should only | 235 // followed by the known-good request again. The response file should only |
223 // contain a single response from the first good request. | 236 // contain a single response from the first good request. |
224 void TestBadRequest(const base::Value& message); | 237 void TestBadRequest(const base::Value& message); |
225 | 238 |
226 protected: | 239 protected: |
227 // Reference to the MockDaemonController, which is owned by |host_|. | 240 // Reference to the MockDaemonControllerDelegate, which is owned by |host_|. |
228 MockDaemonController* daemon_controller_; | 241 MockDaemonControllerDelegate* daemon_controller_delegate_; |
229 | 242 |
230 private: | 243 private: |
231 // Each test creates two unidirectional pipes: "input" and "output". | 244 // Each test creates two unidirectional pipes: "input" and "output". |
232 // NativeMessagingHost reads from input_read_handle and writes to | 245 // NativeMessagingHost reads from input_read_handle and writes to |
233 // output_write_handle. The unittest supplies data to input_write_handle, and | 246 // output_write_handle. The unittest supplies data to input_write_handle, and |
234 // verifies output from output_read_handle. | 247 // verifies output from output_read_handle. |
235 // | 248 // |
236 // unittest -> [input] -> NativeMessagingHost -> [output] -> unittest | 249 // unittest -> [input] -> NativeMessagingHost -> [output] -> unittest |
237 base::PlatformFile input_read_handle_; | 250 base::PlatformFile input_read_handle_; |
238 base::PlatformFile input_write_handle_; | 251 base::PlatformFile input_write_handle_; |
239 base::PlatformFile output_read_handle_; | 252 base::PlatformFile output_read_handle_; |
240 base::PlatformFile output_write_handle_; | 253 base::PlatformFile output_write_handle_; |
241 | 254 |
242 base::MessageLoop message_loop_; | 255 base::MessageLoop message_loop_; |
243 base::RunLoop run_loop_; | 256 base::RunLoop run_loop_; |
244 scoped_ptr<remoting::NativeMessagingHost> host_; | 257 scoped_ptr<remoting::NativeMessagingHost> host_; |
245 | 258 |
246 DISALLOW_COPY_AND_ASSIGN(NativeMessagingHostTest); | 259 DISALLOW_COPY_AND_ASSIGN(NativeMessagingHostTest); |
247 }; | 260 }; |
248 | 261 |
249 NativeMessagingHostTest::NativeMessagingHostTest() | 262 NativeMessagingHostTest::NativeMessagingHostTest() |
250 : message_loop_(base::MessageLoop::TYPE_IO) {} | 263 : message_loop_(base::MessageLoop::TYPE_IO) {} |
251 | 264 |
252 NativeMessagingHostTest::~NativeMessagingHostTest() {} | 265 NativeMessagingHostTest::~NativeMessagingHostTest() {} |
253 | 266 |
254 void NativeMessagingHostTest::SetUp() { | 267 void NativeMessagingHostTest::SetUp() { |
255 ASSERT_TRUE(MakePipe(&input_read_handle_, &input_write_handle_)); | 268 ASSERT_TRUE(MakePipe(&input_read_handle_, &input_write_handle_)); |
256 ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle_)); | 269 ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle_)); |
257 | 270 |
258 daemon_controller_ = new MockDaemonController(); | 271 // Arrange to run |message_loop_| until no components depend on it. |
259 scoped_ptr<DaemonController> daemon_controller(daemon_controller_); | 272 scoped_refptr<AutoThreadTaskRunner> task_runner = new AutoThreadTaskRunner( |
| 273 message_loop_.message_loop_proxy(), run_loop_.QuitClosure()); |
| 274 |
| 275 daemon_controller_delegate_ = new MockDaemonControllerDelegate(); |
| 276 scoped_refptr<DaemonController> daemon_controller( |
| 277 new DaemonController( |
| 278 scoped_ptr<DaemonController::Delegate>(daemon_controller_delegate_))); |
260 | 279 |
261 scoped_refptr<PairingRegistry> pairing_registry = | 280 scoped_refptr<PairingRegistry> pairing_registry = |
262 new SynchronousPairingRegistry(scoped_ptr<PairingRegistry::Delegate>( | 281 new SynchronousPairingRegistry(scoped_ptr<PairingRegistry::Delegate>( |
263 new MockPairingRegistryDelegate())); | 282 new MockPairingRegistryDelegate())); |
264 | 283 |
265 host_.reset(new NativeMessagingHost(daemon_controller.Pass(), | 284 host_.reset(new NativeMessagingHost( |
266 pairing_registry, | 285 daemon_controller, |
267 scoped_ptr<remoting::OAuthClient>(), | 286 pairing_registry, |
268 input_read_handle_, output_write_handle_, | 287 scoped_ptr<remoting::OAuthClient>(), |
269 message_loop_.message_loop_proxy(), | 288 input_read_handle_, output_write_handle_, |
270 run_loop_.QuitClosure())); | 289 task_runner, |
| 290 base::Bind(&NativeMessagingHostTest::DeleteHost, |
| 291 base::Unretained(this)))); |
271 } | 292 } |
272 | 293 |
273 void NativeMessagingHostTest::TearDown() { | 294 void NativeMessagingHostTest::TearDown() { |
274 // The NativeMessagingHost dtor closes the handles that are passed to it. | 295 // The NativeMessagingHost dtor closes the handles that are passed to it. |
275 // |input_write_handle_| gets closed just before starting the host. So the | 296 // |input_write_handle_| gets closed just before starting the host. So the |
276 // only handle left to close is |output_read_handle_|. | 297 // only handle left to close is |output_read_handle_|. |
277 base::ClosePlatformFile(output_read_handle_); | 298 base::ClosePlatformFile(output_read_handle_); |
278 } | 299 } |
279 | 300 |
280 void NativeMessagingHostTest::Run() { | 301 void NativeMessagingHostTest::Run() { |
281 // Close the write-end of input, so that the host sees EOF after reading | 302 // Close the write-end of input, so that the host sees EOF after reading |
282 // messages and won't block waiting for more input. | 303 // messages and won't block waiting for more input. |
283 base::ClosePlatformFile(input_write_handle_); | 304 base::ClosePlatformFile(input_write_handle_); |
284 host_->Start(); | 305 host_->Start(); |
285 run_loop_.Run(); | 306 run_loop_.Run(); |
| 307 } |
286 | 308 |
| 309 void NativeMessagingHostTest::DeleteHost() { |
287 // Destroy |host_| so that it closes its end of the output pipe, so that | 310 // Destroy |host_| so that it closes its end of the output pipe, so that |
288 // TestBadRequest() will see EOF and won't block waiting for more data. | 311 // TestBadRequest() will see EOF and won't block waiting for more data. |
289 host_.reset(); | 312 host_.reset(); |
290 } | 313 } |
291 | 314 |
292 scoped_ptr<base::DictionaryValue> | 315 scoped_ptr<base::DictionaryValue> |
293 NativeMessagingHostTest::ReadMessageFromOutputPipe() { | 316 NativeMessagingHostTest::ReadMessageFromOutputPipe() { |
294 uint32 length; | 317 uint32 length; |
295 int read_result = base::ReadPlatformFileAtCurrentPos( | 318 int read_result = base::ReadPlatformFileAtCurrentPos( |
296 output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length)); | 319 output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length)); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 | 536 |
514 // Verify rejection if startDaemon request has no "consent" parameter. | 537 // Verify rejection if startDaemon request has no "consent" parameter. |
515 TEST_F(NativeMessagingHostTest, StartDaemonNoConsent) { | 538 TEST_F(NativeMessagingHostTest, StartDaemonNoConsent) { |
516 base::DictionaryValue message; | 539 base::DictionaryValue message; |
517 message.SetString("type", "startDaemon"); | 540 message.SetString("type", "startDaemon"); |
518 message.Set("config", base::DictionaryValue().DeepCopy()); | 541 message.Set("config", base::DictionaryValue().DeepCopy()); |
519 TestBadRequest(message); | 542 TestBadRequest(message); |
520 } | 543 } |
521 | 544 |
522 } // namespace remoting | 545 } // namespace remoting |
OLD | NEW |