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/me2me_native_messaging_host.h" | 5 #include "remoting/host/setup/me2me_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" |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 public: | 155 public: |
156 MockDaemonControllerDelegate(); | 156 MockDaemonControllerDelegate(); |
157 ~MockDaemonControllerDelegate() override; | 157 ~MockDaemonControllerDelegate() override; |
158 | 158 |
159 // DaemonController::Delegate interface. | 159 // DaemonController::Delegate interface. |
160 DaemonController::State GetState() override; | 160 DaemonController::State GetState() override; |
161 scoped_ptr<base::DictionaryValue> GetConfig() override; | 161 scoped_ptr<base::DictionaryValue> GetConfig() override; |
162 void SetConfigAndStart( | 162 void SetConfigAndStart( |
163 scoped_ptr<base::DictionaryValue> config, | 163 scoped_ptr<base::DictionaryValue> config, |
164 bool consent, | 164 bool consent, |
165 const DaemonController::CompletionCallback& done) override; | 165 const base::Closure& on_done, |
| 166 const DaemonController::ErrorCallback& on_error) override; |
166 void UpdateConfig(scoped_ptr<base::DictionaryValue> config, | 167 void UpdateConfig(scoped_ptr<base::DictionaryValue> config, |
167 const DaemonController::CompletionCallback& done) override; | 168 const base::Closure& on_done, |
168 void Stop(const DaemonController::CompletionCallback& done) override; | 169 const DaemonController::ErrorCallback& on_error) override; |
| 170 void Stop(const base::Closure& on_done, |
| 171 const DaemonController::ErrorCallback& on_error) override; |
169 DaemonController::UsageStatsConsent GetUsageStatsConsent() override; | 172 DaemonController::UsageStatsConsent GetUsageStatsConsent() override; |
170 | 173 |
171 private: | 174 private: |
172 DISALLOW_COPY_AND_ASSIGN(MockDaemonControllerDelegate); | 175 DISALLOW_COPY_AND_ASSIGN(MockDaemonControllerDelegate); |
173 }; | 176 }; |
174 | 177 |
175 MockDaemonControllerDelegate::MockDaemonControllerDelegate() {} | 178 MockDaemonControllerDelegate::MockDaemonControllerDelegate() {} |
176 | 179 |
177 MockDaemonControllerDelegate::~MockDaemonControllerDelegate() {} | 180 MockDaemonControllerDelegate::~MockDaemonControllerDelegate() {} |
178 | 181 |
179 DaemonController::State MockDaemonControllerDelegate::GetState() { | 182 DaemonController::State MockDaemonControllerDelegate::GetState() { |
180 return DaemonController::STATE_STARTED; | 183 return DaemonController::STATE_STARTED; |
181 } | 184 } |
182 | 185 |
183 scoped_ptr<base::DictionaryValue> MockDaemonControllerDelegate::GetConfig() { | 186 scoped_ptr<base::DictionaryValue> MockDaemonControllerDelegate::GetConfig() { |
184 return make_scoped_ptr(new base::DictionaryValue()); | 187 return make_scoped_ptr(new base::DictionaryValue()); |
185 } | 188 } |
186 | 189 |
187 void MockDaemonControllerDelegate::SetConfigAndStart( | 190 void MockDaemonControllerDelegate::SetConfigAndStart( |
188 scoped_ptr<base::DictionaryValue> config, | 191 scoped_ptr<base::DictionaryValue> config, |
189 bool consent, | 192 bool consent, |
190 const DaemonController::CompletionCallback& done) { | 193 const base::Closure& on_done, |
| 194 const DaemonController::ErrorCallback& on_error) { |
191 | 195 |
192 // Verify parameters passed in. | 196 // Verify parameters passed in. |
193 if (consent && config && config->HasKey("start")) { | 197 if (consent && config && config->HasKey("start")) { |
194 done.Run(DaemonController::RESULT_OK); | 198 on_done.Run(); |
195 } else { | 199 } else { |
196 done.Run(DaemonController::RESULT_FAILED); | 200 on_error.Run("Missing 'start'", FROM_HERE); |
197 } | 201 } |
198 } | 202 } |
199 | 203 |
200 void MockDaemonControllerDelegate::UpdateConfig( | 204 void MockDaemonControllerDelegate::UpdateConfig( |
201 scoped_ptr<base::DictionaryValue> config, | 205 scoped_ptr<base::DictionaryValue> config, |
202 const DaemonController::CompletionCallback& done) { | 206 const base::Closure& on_done, |
| 207 const DaemonController::ErrorCallback& on_error) { |
203 if (config && config->HasKey("update")) { | 208 if (config && config->HasKey("update")) { |
204 done.Run(DaemonController::RESULT_OK); | 209 on_done.Run(); |
205 } else { | 210 } else { |
206 done.Run(DaemonController::RESULT_FAILED); | 211 on_error.Run("Missing 'update'", FROM_HERE); |
207 } | 212 } |
208 } | 213 } |
209 | 214 |
210 void MockDaemonControllerDelegate::Stop( | 215 void MockDaemonControllerDelegate::Stop( |
211 const DaemonController::CompletionCallback& done) { | 216 const base::Closure& on_done, |
212 done.Run(DaemonController::RESULT_OK); | 217 const DaemonController::ErrorCallback& on_error) { |
| 218 on_done.Run(); |
213 } | 219 } |
214 | 220 |
215 DaemonController::UsageStatsConsent | 221 DaemonController::UsageStatsConsent |
216 MockDaemonControllerDelegate::GetUsageStatsConsent() { | 222 MockDaemonControllerDelegate::GetUsageStatsConsent() { |
217 DaemonController::UsageStatsConsent consent; | 223 DaemonController::UsageStatsConsent consent; |
218 consent.supported = true; | 224 consent.supported = true; |
219 consent.allowed = true; | 225 consent.allowed = true; |
220 consent.set_by_policy = true; | 226 consent.set_by_policy = true; |
221 return consent; | 227 return consent; |
222 } | 228 } |
223 | 229 |
224 class Me2MeNativeMessagingHostTest : public testing::Test { | 230 class Me2MeNativeMessagingHostTest : public testing::Test { |
225 public: | 231 public: |
226 Me2MeNativeMessagingHostTest(); | 232 Me2MeNativeMessagingHostTest(); |
227 ~Me2MeNativeMessagingHostTest() override; | 233 ~Me2MeNativeMessagingHostTest() override; |
228 | 234 |
229 void SetUp() override; | 235 void SetUp() override; |
230 void TearDown() override; | 236 void TearDown() override; |
231 | 237 |
232 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); | 238 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); |
233 | 239 |
234 void WriteMessageToInputPipe(const base::Value& message); | 240 void WriteMessageToInputPipe(const base::Value& message); |
235 | 241 |
236 // The Host process should shut down when it receives a malformed request. | 242 void TestBadDictionary(const base::DictionaryValue& message); |
237 // This is tested by sending a known-good request, followed by |message|, | 243 void TestBadRequest(const base::Value& message, |
238 // followed by the known-good request again. The response file should only | 244 const std::string& expected_type); |
239 // contain a single response from the first good request. | |
240 void TestBadRequest(const base::Value& message); | |
241 | 245 |
242 protected: | 246 protected: |
243 // Reference to the MockDaemonControllerDelegate, which is owned by | 247 // Reference to the MockDaemonControllerDelegate, which is owned by |
244 // |channel_|. | 248 // |channel_|. |
245 MockDaemonControllerDelegate* daemon_controller_delegate_; | 249 MockDaemonControllerDelegate* daemon_controller_delegate_; |
246 | 250 |
247 private: | 251 private: |
248 void StartHost(); | 252 void StartHost(); |
249 void StopHost(); | 253 void StopHost(); |
250 void ExitTest(); | 254 void ExitTest(); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 const base::Value& message) { | 414 const base::Value& message) { |
411 std::string message_json; | 415 std::string message_json; |
412 base::JSONWriter::Write(message, &message_json); | 416 base::JSONWriter::Write(message, &message_json); |
413 | 417 |
414 uint32 length = message_json.length(); | 418 uint32 length = message_json.length(); |
415 input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length), | 419 input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length), |
416 sizeof(length)); | 420 sizeof(length)); |
417 input_write_file_.WriteAtCurrentPos(message_json.data(), length); | 421 input_write_file_.WriteAtCurrentPos(message_json.data(), length); |
418 } | 422 } |
419 | 423 |
420 void Me2MeNativeMessagingHostTest::TestBadRequest(const base::Value& message) { | 424 void Me2MeNativeMessagingHostTest::TestBadDictionary( |
| 425 const base::DictionaryValue& message) { |
| 426 std::string type; |
| 427 EXPECT_TRUE(message.GetString("type", &type)); |
| 428 TestBadRequest(message, type + "Response"); |
| 429 } |
| 430 |
| 431 void Me2MeNativeMessagingHostTest::TestBadRequest( |
| 432 const base::Value& message, |
| 433 const std::string& expected_type) { |
421 base::DictionaryValue good_message; | 434 base::DictionaryValue good_message; |
422 good_message.SetString("type", "hello"); | 435 good_message.SetString("type", "hello"); |
423 | 436 |
424 // This test currently relies on synchronous processing of hello messages and | 437 // This test currently relies on synchronous processing of hello messages and |
425 // message parameters verification. | 438 // message parameters verification. |
426 WriteMessageToInputPipe(good_message); | 439 WriteMessageToInputPipe(good_message); |
427 WriteMessageToInputPipe(message); | 440 WriteMessageToInputPipe(message); |
428 WriteMessageToInputPipe(good_message); | |
429 | 441 |
430 // Read from output pipe, and verify responses. | 442 // Read from output pipe, and verify responses. |
431 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 443 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
432 VerifyHelloResponse(response.Pass()); | 444 VerifyHelloResponse(response.Pass()); |
433 | 445 |
434 response = ReadMessageFromOutputPipe(); | 446 response = ReadMessageFromOutputPipe(); |
435 EXPECT_FALSE(response); | 447 EXPECT_TRUE(response); |
| 448 |
| 449 // If a type is expected, assert that it matches (note that a type is expected |
| 450 // for all message that included one). |
| 451 std::string value; |
| 452 if (!expected_type.empty()) { |
| 453 EXPECT_TRUE(response->GetString("type", &value)); |
| 454 EXPECT_EQ(expected_type, value); |
| 455 } else { |
| 456 EXPECT_FALSE(response->GetString("type", &value)); |
| 457 } |
| 458 |
| 459 EXPECT_TRUE(response->GetString("error_message", &value)); |
| 460 EXPECT_TRUE(response->GetString("error_location", &value)); |
436 } | 461 } |
437 | 462 |
438 // TODO (weitaosu): crbug.com/323306. Re-enable these tests. | |
439 // Test all valid request-types. | 463 // Test all valid request-types. |
440 TEST_F(Me2MeNativeMessagingHostTest, All) { | 464 TEST_F(Me2MeNativeMessagingHostTest, All) { |
441 int next_id = 0; | 465 int next_id = 0; |
442 base::DictionaryValue message; | 466 base::DictionaryValue message; |
443 message.SetInteger("id", next_id++); | 467 message.SetInteger("id", next_id++); |
444 message.SetString("type", "hello"); | 468 message.SetString("type", "hello"); |
445 WriteMessageToInputPipe(message); | 469 WriteMessageToInputPipe(message); |
446 | 470 |
447 message.SetInteger("id", next_id++); | 471 message.SetInteger("id", next_id++); |
448 message.SetString("type", "getHostName"); | 472 message.SetString("type", "getHostName"); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 | 568 |
545 response = ReadMessageFromOutputPipe(); | 569 response = ReadMessageFromOutputPipe(); |
546 EXPECT_TRUE(response); | 570 EXPECT_TRUE(response); |
547 EXPECT_TRUE(response->GetString("id", &value)); | 571 EXPECT_TRUE(response->GetString("id", &value)); |
548 EXPECT_EQ("42", value); | 572 EXPECT_EQ("42", value); |
549 } | 573 } |
550 | 574 |
551 // Verify non-Dictionary requests are rejected. | 575 // Verify non-Dictionary requests are rejected. |
552 TEST_F(Me2MeNativeMessagingHostTest, WrongFormat) { | 576 TEST_F(Me2MeNativeMessagingHostTest, WrongFormat) { |
553 base::ListValue message; | 577 base::ListValue message; |
554 TestBadRequest(message); | 578 TestBadRequest(message, ""); |
555 } | 579 } |
556 | 580 |
557 // Verify requests with no type are rejected. | 581 // Verify requests with no type are rejected. |
558 TEST_F(Me2MeNativeMessagingHostTest, MissingType) { | 582 TEST_F(Me2MeNativeMessagingHostTest, MissingType) { |
559 base::DictionaryValue message; | 583 base::DictionaryValue message; |
560 TestBadRequest(message); | 584 TestBadRequest(message, ""); |
561 } | 585 } |
562 | 586 |
563 // Verify rejection if type is unrecognized. | 587 // Verify rejection if type is unrecognized. |
564 TEST_F(Me2MeNativeMessagingHostTest, InvalidType) { | 588 TEST_F(Me2MeNativeMessagingHostTest, InvalidType) { |
565 base::DictionaryValue message; | 589 base::DictionaryValue message; |
566 message.SetString("type", "xxx"); | 590 message.SetString("type", "xxx"); |
567 TestBadRequest(message); | 591 TestBadDictionary(message); |
568 } | 592 } |
569 | 593 |
570 // Verify rejection if getPinHash request has no hostId. | 594 // Verify rejection if getPinHash request has no hostId. |
571 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoHostId) { | 595 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoHostId) { |
572 base::DictionaryValue message; | 596 base::DictionaryValue message; |
573 message.SetString("type", "getPinHash"); | 597 message.SetString("type", "getPinHash"); |
574 message.SetString("pin", "1234"); | 598 message.SetString("pin", "1234"); |
575 TestBadRequest(message); | 599 TestBadDictionary(message); |
576 } | 600 } |
577 | 601 |
578 // Verify rejection if getPinHash request has no pin. | 602 // Verify rejection if getPinHash request has no pin. |
579 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoPin) { | 603 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoPin) { |
580 base::DictionaryValue message; | 604 base::DictionaryValue message; |
581 message.SetString("type", "getPinHash"); | 605 message.SetString("type", "getPinHash"); |
582 message.SetString("hostId", "my_host"); | 606 message.SetString("hostId", "my_host"); |
583 TestBadRequest(message); | 607 TestBadDictionary(message); |
584 } | 608 } |
585 | 609 |
586 // Verify rejection if updateDaemonConfig request has invalid config. | 610 // Verify rejection if updateDaemonConfig request has invalid config. |
587 TEST_F(Me2MeNativeMessagingHostTest, UpdateDaemonConfigInvalidConfig) { | 611 TEST_F(Me2MeNativeMessagingHostTest, UpdateDaemonConfigInvalidConfig) { |
588 base::DictionaryValue message; | 612 base::DictionaryValue message; |
589 message.SetString("type", "updateDaemonConfig"); | 613 message.SetString("type", "updateDaemonConfig"); |
590 message.SetString("config", "xxx"); | 614 message.SetString("config", "xxx"); |
591 TestBadRequest(message); | 615 TestBadDictionary(message); |
592 } | 616 } |
593 | 617 |
594 // Verify rejection if startDaemon request has invalid config. | 618 // Verify rejection if startDaemon request has invalid config. |
595 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonInvalidConfig) { | 619 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonInvalidConfig) { |
596 base::DictionaryValue message; | 620 base::DictionaryValue message; |
597 message.SetString("type", "startDaemon"); | 621 message.SetString("type", "startDaemon"); |
598 message.SetString("config", "xxx"); | 622 message.SetString("config", "xxx"); |
599 message.SetBoolean("consent", true); | 623 message.SetBoolean("consent", true); |
600 TestBadRequest(message); | 624 TestBadDictionary(message); |
601 } | 625 } |
602 | 626 |
603 // Verify rejection if startDaemon request has no "consent" parameter. | 627 // Verify rejection if startDaemon request has no "consent" parameter. |
604 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonNoConsent) { | 628 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonNoConsent) { |
605 base::DictionaryValue message; | 629 base::DictionaryValue message; |
606 message.SetString("type", "startDaemon"); | 630 message.SetString("type", "startDaemon"); |
607 message.Set("config", base::DictionaryValue().DeepCopy()); | 631 message.Set("config", base::DictionaryValue().DeepCopy()); |
608 TestBadRequest(message); | 632 TestBadDictionary(message); |
609 } | 633 } |
610 | 634 |
611 // Verify rejection if getCredentialsFromAuthCode has no auth code. | 635 // Verify rejection if getCredentialsFromAuthCode has no auth code. |
612 TEST_F(Me2MeNativeMessagingHostTest, GetCredentialsFromAuthCodeNoAuthCode) { | 636 TEST_F(Me2MeNativeMessagingHostTest, GetCredentialsFromAuthCodeNoAuthCode) { |
613 base::DictionaryValue message; | 637 base::DictionaryValue message; |
614 message.SetString("type", "getCredentialsFromAuthCode"); | 638 message.SetString("type", "getCredentialsFromAuthCode"); |
615 TestBadRequest(message); | 639 TestBadDictionary(message); |
616 } | 640 } |
617 | 641 |
618 } // namespace remoting | 642 } // namespace remoting |
OLD | NEW |