Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: remoting/host/setup/me2me_native_messaging_host_unittest.cc

Issue 103693006: Me2me Native Messaging host on Windows: restructure NativeMessagingHost and NativeMessagingChannel.… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 } 215 }
216 216
217 class NativeMessagingHostTest : public testing::Test { 217 class NativeMessagingHostTest : public testing::Test {
218 public: 218 public:
219 NativeMessagingHostTest(); 219 NativeMessagingHostTest();
220 virtual ~NativeMessagingHostTest(); 220 virtual ~NativeMessagingHostTest();
221 221
222 virtual void SetUp() OVERRIDE; 222 virtual void SetUp() OVERRIDE;
223 virtual void TearDown() OVERRIDE; 223 virtual void TearDown() OVERRIDE;
224 224
225 void Run();
226
227 // Deletes |host_|.
228 void DeleteHost();
229
230 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); 225 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe();
231 226
232 void WriteMessageToInputPipe(const base::Value& message); 227 void WriteMessageToInputPipe(const base::Value& message);
233 228
234 // The Host process should shut down when it receives a malformed request. 229 // The Host process should shut down when it receives a malformed request.
235 // This is tested by sending a known-good request, followed by |message|, 230 // This is tested by sending a known-good request, followed by |message|,
236 // followed by the known-good request again. The response file should only 231 // followed by the known-good request again. The response file should only
237 // contain a single response from the first good request. 232 // contain a single response from the first good request.
238 void TestBadRequest(const base::Value& message); 233 void TestBadRequest(const base::Value& message);
239 234
240 protected: 235 protected:
241 // Reference to the MockDaemonControllerDelegate, which is owned by 236 // Reference to the MockDaemonControllerDelegate, which is owned by
242 // |channel_|. 237 // |channel_|.
243 MockDaemonControllerDelegate* daemon_controller_delegate_; 238 MockDaemonControllerDelegate* daemon_controller_delegate_;
244 239
245 private: 240 private:
241 void StartHost();
242 void StopHost();
243 void ExitTest();
244
246 // Each test creates two unidirectional pipes: "input" and "output". 245 // Each test creates two unidirectional pipes: "input" and "output".
247 // NativeMessagingHost reads from input_read_handle and writes to 246 // NativeMessagingHost reads from input_read_handle and writes to
248 // output_write_handle. The unittest supplies data to input_write_handle, and 247 // output_write_handle. The unittest supplies data to input_write_handle, and
249 // verifies output from output_read_handle. 248 // verifies output from output_read_handle.
250 // 249 //
251 // unittest -> [input] -> NativeMessagingHost -> [output] -> unittest 250 // unittest -> [input] -> NativeMessagingHost -> [output] -> unittest
252 base::PlatformFile input_write_handle_; 251 base::PlatformFile input_write_handle_;
253 base::PlatformFile output_read_handle_; 252 base::PlatformFile output_read_handle_;
254 253
255 base::MessageLoop message_loop_; 254 // Message loop of the test thread.
256 base::RunLoop run_loop_; 255 scoped_ptr<base::MessageLoop> test_message_loop_;
257 scoped_refptr<AutoThreadTaskRunner> task_runner_; 256 scoped_ptr<base::RunLoop> test_run_loop_;
258 scoped_ptr<remoting::NativeMessagingChannel> channel_; 257
258 scoped_ptr<base::Thread> host_thread_;
259 scoped_ptr<base::RunLoop> host_run_loop_;
260
261 // Task runner of the host thread.
262 scoped_refptr<AutoThreadTaskRunner> host_task_runner_;
263 scoped_ptr<remoting::NativeMessagingHost> host_;
259 264
260 DISALLOW_COPY_AND_ASSIGN(NativeMessagingHostTest); 265 DISALLOW_COPY_AND_ASSIGN(NativeMessagingHostTest);
261 }; 266 };
262 267
263 NativeMessagingHostTest::NativeMessagingHostTest() 268 NativeMessagingHostTest::NativeMessagingHostTest() {}
264 : message_loop_(base::MessageLoop::TYPE_IO) {}
265 269
266 NativeMessagingHostTest::~NativeMessagingHostTest() {} 270 NativeMessagingHostTest::~NativeMessagingHostTest() {}
267 271
268 void NativeMessagingHostTest::SetUp() { 272 void NativeMessagingHostTest::SetUp() {
269 base::PlatformFile input_read_handle; 273 base::PlatformFile input_read_handle;
270 base::PlatformFile output_write_handle; 274 base::PlatformFile output_write_handle;
271 275
272 ASSERT_TRUE(MakePipe(&input_read_handle, &input_write_handle_)); 276 ASSERT_TRUE(MakePipe(&input_read_handle, &input_write_handle_));
273 ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle)); 277 ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle));
274 278
275 // Arrange to run |message_loop_| until no components depend on it. 279 test_message_loop_.reset(new base::MessageLoop());
276 task_runner_ = new AutoThreadTaskRunner( 280 test_run_loop_.reset(new base::RunLoop());
277 message_loop_.message_loop_proxy(), run_loop_.QuitClosure()); 281
282 // Run the host on a dedicated thread.
283 host_thread_.reset(new base::Thread("host_thread"));
284 host_thread_->Start();
285
286 // Arrange to run |test_message_loop_| until no components depend on it.
287 host_task_runner_ = new AutoThreadTaskRunner(
288 host_thread_->message_loop_proxy(),
289 base::Bind(&NativeMessagingHostTest::ExitTest,
290 base::Unretained(this)));
291
292 host_task_runner_->PostTask(
293 FROM_HERE,
294 base::Bind(&NativeMessagingHostTest::StartHost, base::Unretained(this)));
295
296 // Wait until the host finishes starting.
297 test_run_loop_->Run();
298 }
299
300 void NativeMessagingHostTest::StartHost() {
301 DCHECK(host_task_runner_->RunsTasksOnCurrentThread());
302
303 base::PlatformFile input_read_handle;
304 base::PlatformFile output_write_handle;
305
306 ASSERT_TRUE(MakePipe(&input_read_handle, &input_write_handle_));
307 ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle));
278 308
279 daemon_controller_delegate_ = new MockDaemonControllerDelegate(); 309 daemon_controller_delegate_ = new MockDaemonControllerDelegate();
280 scoped_refptr<DaemonController> daemon_controller( 310 scoped_refptr<DaemonController> daemon_controller(
281 new DaemonController( 311 new DaemonController(
282 scoped_ptr<DaemonController::Delegate>(daemon_controller_delegate_))); 312 scoped_ptr<DaemonController::Delegate>(daemon_controller_delegate_)));
283 313
284 scoped_refptr<PairingRegistry> pairing_registry = 314 scoped_refptr<PairingRegistry> pairing_registry =
285 new SynchronousPairingRegistry(scoped_ptr<PairingRegistry::Delegate>( 315 new SynchronousPairingRegistry(scoped_ptr<PairingRegistry::Delegate>(
286 new MockPairingRegistryDelegate())); 316 new MockPairingRegistryDelegate()));
287 scoped_ptr<NativeMessagingChannel::Delegate> host( 317
288 new NativeMessagingHost(daemon_controller, 318 scoped_ptr<NativeMessagingChannel> channel(
289 pairing_registry, 319 new NativeMessagingChannel(input_read_handle, output_write_handle));
290 scoped_ptr<remoting::OAuthClient>())); 320
291 channel_.reset( 321 host_.reset(new NativeMessagingHost(channel.Pass(),
292 new NativeMessagingChannel(host.Pass(), 322 daemon_controller,
293 input_read_handle, 323 pairing_registry,
294 output_write_handle)); 324 scoped_ptr<remoting::OAuthClient>()));
325 host_->Start(base::Bind(&NativeMessagingHostTest::StopHost,
326 base::Unretained(this)));
327
328 // Notify the test that the host has finished starting up.
329 test_message_loop_->message_loop_proxy()->PostTask(
330 FROM_HERE, test_run_loop_->QuitClosure());
331 }
332
333 void NativeMessagingHostTest::StopHost() {
334 DCHECK(host_task_runner_->RunsTasksOnCurrentThread());
335
336 host_.reset();
337
338 // Wait till all shutdown tasks have completed.
339 base::MessageLoop::current()->RunUntilIdle();
340
341 // Trigger a test shutdown via ExitTest().
342 host_task_runner_ = NULL;
343 }
344
345 void NativeMessagingHostTest::ExitTest() {
346 if (!test_message_loop_->message_loop_proxy()->RunsTasksOnCurrentThread()) {
347 test_message_loop_->message_loop_proxy()->PostTask(
348 FROM_HERE,
349 base::Bind(&NativeMessagingHostTest::ExitTest,
350 base::Unretained(this)));
351 return;
352 }
353 test_run_loop_->Quit();
295 } 354 }
296 355
297 void NativeMessagingHostTest::TearDown() { 356 void NativeMessagingHostTest::TearDown() {
298 // DaemonController destroys its internals asynchronously. Let these and any 357 // Closing the write-end of the input will send an EOF to the native
299 // other pending tasks run to make sure we don't leak the memory owned by 358 // messaging reader. This will trigger a host shutdown.
300 // them. 359 base::ClosePlatformFile(input_write_handle_);
301 message_loop_.RunUntilIdle();
302 360
303 // The NativeMessagingHost dtor closes the handles that are passed to it. 361 // Start a new RunLoop and Wait until the host finishes shutting down.
304 // |input_write_handle_| gets closed just before starting the host. So the 362 test_run_loop_.reset(new base::RunLoop());
305 // only handle left to close is |output_read_handle_|. 363 test_run_loop_->Run();
364
365 // Verify there are no more message in the output pipe.
366 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe();
367 EXPECT_FALSE(response);
368
369 // The It2MeNativeMessagingHost dtor closes the handles that are passed to it.
370 // So the only handle left to close is |output_read_handle_|.
306 base::ClosePlatformFile(output_read_handle_); 371 base::ClosePlatformFile(output_read_handle_);
307 } 372 }
308 373
309 void NativeMessagingHostTest::Run() {
310 // Close the write-end of input, so that the host sees EOF after reading
311 // messages and won't block waiting for more input.
312 base::ClosePlatformFile(input_write_handle_);
313 channel_->Start(base::Bind(&NativeMessagingHostTest::DeleteHost,
314 base::Unretained(this)));
315 run_loop_.Run();
316 }
317
318 void NativeMessagingHostTest::DeleteHost() {
319 // Destroy |channel_| so that it closes its end of the output pipe, so that
320 // TestBadRequest() will see EOF and won't block waiting for more data.
321 channel_.reset();
322 task_runner_ = NULL;
323 }
324
325 scoped_ptr<base::DictionaryValue> 374 scoped_ptr<base::DictionaryValue>
326 NativeMessagingHostTest::ReadMessageFromOutputPipe() { 375 NativeMessagingHostTest::ReadMessageFromOutputPipe() {
327 uint32 length; 376 uint32 length;
328 int read_result = base::ReadPlatformFileAtCurrentPos( 377 int read_result = base::ReadPlatformFileAtCurrentPos(
329 output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length)); 378 output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length));
330 if (read_result != sizeof(length)) { 379 if (read_result != sizeof(length)) {
331 return scoped_ptr<base::DictionaryValue>(); 380 return scoped_ptr<base::DictionaryValue>();
332 } 381 }
333 382
334 std::string message_json(length, '\0'); 383 std::string message_json(length, '\0');
(...skipping 28 matching lines...) Expand all
363 void NativeMessagingHostTest::TestBadRequest(const base::Value& message) { 412 void NativeMessagingHostTest::TestBadRequest(const base::Value& message) {
364 base::DictionaryValue good_message; 413 base::DictionaryValue good_message;
365 good_message.SetString("type", "hello"); 414 good_message.SetString("type", "hello");
366 415
367 // This test currently relies on synchronous processing of hello messages and 416 // This test currently relies on synchronous processing of hello messages and
368 // message parameters verification. 417 // message parameters verification.
369 WriteMessageToInputPipe(good_message); 418 WriteMessageToInputPipe(good_message);
370 WriteMessageToInputPipe(message); 419 WriteMessageToInputPipe(message);
371 WriteMessageToInputPipe(good_message); 420 WriteMessageToInputPipe(good_message);
372 421
373 Run();
374
375 // Read from output pipe, and verify responses. 422 // Read from output pipe, and verify responses.
376 scoped_ptr<base::DictionaryValue> response = 423 scoped_ptr<base::DictionaryValue> response =
377 ReadMessageFromOutputPipe(); 424 ReadMessageFromOutputPipe();
378 VerifyHelloResponse(response.Pass()); 425 VerifyHelloResponse(response.Pass());
379 426
380 response = ReadMessageFromOutputPipe(); 427 response = ReadMessageFromOutputPipe();
381 EXPECT_FALSE(response); 428 EXPECT_FALSE(response);
382 } 429 }
383 430
384 // TODO (weitaosu): crbug.com/323306. Re-enable these tests. 431 // TODO (weitaosu): crbug.com/323306. Re-enable these tests.
385 // Test all valid request-types. 432 // Test all valid request-types.
386 TEST_F(NativeMessagingHostTest, DISABLED_All) { 433 TEST_F(NativeMessagingHostTest, All) {
387 int next_id = 0; 434 int next_id = 0;
388 base::DictionaryValue message; 435 base::DictionaryValue message;
389 message.SetInteger("id", next_id++); 436 message.SetInteger("id", next_id++);
390 message.SetString("type", "hello"); 437 message.SetString("type", "hello");
391 WriteMessageToInputPipe(message); 438 WriteMessageToInputPipe(message);
392 439
393 message.SetInteger("id", next_id++); 440 message.SetInteger("id", next_id++);
394 message.SetString("type", "getHostName"); 441 message.SetString("type", "getHostName");
395 WriteMessageToInputPipe(message); 442 WriteMessageToInputPipe(message);
396 443
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 WriteMessageToInputPipe(message); 477 WriteMessageToInputPipe(message);
431 478
432 config.Clear(); 479 config.Clear();
433 config.SetBoolean("start", true); 480 config.SetBoolean("start", true);
434 message.Set("config", config.DeepCopy()); 481 message.Set("config", config.DeepCopy());
435 message.SetBoolean("consent", true); 482 message.SetBoolean("consent", true);
436 message.SetInteger("id", next_id++); 483 message.SetInteger("id", next_id++);
437 message.SetString("type", "startDaemon"); 484 message.SetString("type", "startDaemon");
438 WriteMessageToInputPipe(message); 485 WriteMessageToInputPipe(message);
439 486
440 Run();
441
442 void (*verify_routines[])(scoped_ptr<base::DictionaryValue>) = { 487 void (*verify_routines[])(scoped_ptr<base::DictionaryValue>) = {
443 &VerifyHelloResponse, 488 &VerifyHelloResponse,
444 &VerifyGetHostNameResponse, 489 &VerifyGetHostNameResponse,
445 &VerifyGetPinHashResponse, 490 &VerifyGetPinHashResponse,
446 &VerifyGenerateKeyPairResponse, 491 &VerifyGenerateKeyPairResponse,
447 &VerifyGetDaemonConfigResponse, 492 &VerifyGetDaemonConfigResponse,
448 &VerifyGetUsageStatsConsentResponse, 493 &VerifyGetUsageStatsConsentResponse,
449 &VerifyStopDaemonResponse, 494 &VerifyStopDaemonResponse,
450 &VerifyGetDaemonStateResponse, 495 &VerifyGetDaemonStateResponse,
451 &VerifyUpdateDaemonConfigResponse, 496 &VerifyUpdateDaemonConfigResponse,
(...skipping 13 matching lines...) Expand all
465 // Call the verification routine corresponding to the message id. 510 // Call the verification routine corresponding to the message id.
466 ASSERT_TRUE(verify_routines[id]); 511 ASSERT_TRUE(verify_routines[id]);
467 verify_routines[id](response.Pass()); 512 verify_routines[id](response.Pass());
468 513
469 // Clear the pointer so that the routine cannot be called the second time. 514 // Clear the pointer so that the routine cannot be called the second time.
470 verify_routines[id] = NULL; 515 verify_routines[id] = NULL;
471 } 516 }
472 } 517 }
473 518
474 // Verify that response ID matches request ID. 519 // Verify that response ID matches request ID.
475 TEST_F(NativeMessagingHostTest, DISABLED_Id) { 520 TEST_F(NativeMessagingHostTest, Id) {
476 base::DictionaryValue message; 521 base::DictionaryValue message;
477 message.SetString("type", "hello"); 522 message.SetString("type", "hello");
478 WriteMessageToInputPipe(message); 523 WriteMessageToInputPipe(message);
479 message.SetString("id", "42"); 524 message.SetString("id", "42");
480 WriteMessageToInputPipe(message); 525 WriteMessageToInputPipe(message);
481 526
482 Run();
483
484 scoped_ptr<base::DictionaryValue> response = 527 scoped_ptr<base::DictionaryValue> response =
485 ReadMessageFromOutputPipe(); 528 ReadMessageFromOutputPipe();
486 EXPECT_TRUE(response); 529 EXPECT_TRUE(response);
487 std::string value; 530 std::string value;
488 EXPECT_FALSE(response->GetString("id", &value)); 531 EXPECT_FALSE(response->GetString("id", &value));
489 532
490 response = ReadMessageFromOutputPipe(); 533 response = ReadMessageFromOutputPipe();
491 EXPECT_TRUE(response); 534 EXPECT_TRUE(response);
492 EXPECT_TRUE(response->GetString("id", &value)); 535 EXPECT_TRUE(response->GetString("id", &value));
493 EXPECT_EQ("42", value); 536 EXPECT_EQ("42", value);
494 } 537 }
495 538
496 // Verify non-Dictionary requests are rejected. 539 // Verify non-Dictionary requests are rejected.
497 TEST_F(NativeMessagingHostTest, DISABLED_WrongFormat) { 540 TEST_F(NativeMessagingHostTest, WrongFormat) {
498 base::ListValue message; 541 base::ListValue message;
499 TestBadRequest(message); 542 TestBadRequest(message);
500 } 543 }
501 544
502 // Verify requests with no type are rejected. 545 // Verify requests with no type are rejected.
503 TEST_F(NativeMessagingHostTest, DISABLED_MissingType) { 546 TEST_F(NativeMessagingHostTest, MissingType) {
504 base::DictionaryValue message; 547 base::DictionaryValue message;
505 TestBadRequest(message); 548 TestBadRequest(message);
506 } 549 }
507 550
508 // Verify rejection if type is unrecognized. 551 // Verify rejection if type is unrecognized.
509 TEST_F(NativeMessagingHostTest, DISABLED_InvalidType) { 552 TEST_F(NativeMessagingHostTest, InvalidType) {
510 base::DictionaryValue message; 553 base::DictionaryValue message;
511 message.SetString("type", "xxx"); 554 message.SetString("type", "xxx");
512 TestBadRequest(message); 555 TestBadRequest(message);
513 } 556 }
514 557
515 // Verify rejection if getPinHash request has no hostId. 558 // Verify rejection if getPinHash request has no hostId.
516 TEST_F(NativeMessagingHostTest, DISABLED_GetPinHashNoHostId) { 559 TEST_F(NativeMessagingHostTest, GetPinHashNoHostId) {
517 base::DictionaryValue message; 560 base::DictionaryValue message;
518 message.SetString("type", "getPinHash"); 561 message.SetString("type", "getPinHash");
519 message.SetString("pin", "1234"); 562 message.SetString("pin", "1234");
520 TestBadRequest(message); 563 TestBadRequest(message);
521 } 564 }
522 565
523 // Verify rejection if getPinHash request has no pin. 566 // Verify rejection if getPinHash request has no pin.
524 TEST_F(NativeMessagingHostTest, DISABLED_GetPinHashNoPin) { 567 TEST_F(NativeMessagingHostTest, GetPinHashNoPin) {
525 base::DictionaryValue message; 568 base::DictionaryValue message;
526 message.SetString("type", "getPinHash"); 569 message.SetString("type", "getPinHash");
527 message.SetString("hostId", "my_host"); 570 message.SetString("hostId", "my_host");
528 TestBadRequest(message); 571 TestBadRequest(message);
529 } 572 }
530 573
531 // Verify rejection if updateDaemonConfig request has invalid config. 574 // Verify rejection if updateDaemonConfig request has invalid config.
532 TEST_F(NativeMessagingHostTest, DISABLED_UpdateDaemonConfigInvalidConfig) { 575 TEST_F(NativeMessagingHostTest, UpdateDaemonConfigInvalidConfig) {
533 base::DictionaryValue message; 576 base::DictionaryValue message;
534 message.SetString("type", "updateDaemonConfig"); 577 message.SetString("type", "updateDaemonConfig");
535 message.SetString("config", "xxx"); 578 message.SetString("config", "xxx");
536 TestBadRequest(message); 579 TestBadRequest(message);
537 } 580 }
538 581
539 // Verify rejection if startDaemon request has invalid config. 582 // Verify rejection if startDaemon request has invalid config.
540 TEST_F(NativeMessagingHostTest, DISABLED_StartDaemonInvalidConfig) { 583 TEST_F(NativeMessagingHostTest, StartDaemonInvalidConfig) {
541 base::DictionaryValue message; 584 base::DictionaryValue message;
542 message.SetString("type", "startDaemon"); 585 message.SetString("type", "startDaemon");
543 message.SetString("config", "xxx"); 586 message.SetString("config", "xxx");
544 message.SetBoolean("consent", true); 587 message.SetBoolean("consent", true);
545 TestBadRequest(message); 588 TestBadRequest(message);
546 } 589 }
547 590
548 // Verify rejection if startDaemon request has no "consent" parameter. 591 // Verify rejection if startDaemon request has no "consent" parameter.
549 TEST_F(NativeMessagingHostTest, DISABLED_StartDaemonNoConsent) { 592 TEST_F(NativeMessagingHostTest, StartDaemonNoConsent) {
550 base::DictionaryValue message; 593 base::DictionaryValue message;
551 message.SetString("type", "startDaemon"); 594 message.SetString("type", "startDaemon");
552 message.Set("config", base::DictionaryValue().DeepCopy()); 595 message.Set("config", base::DictionaryValue().DeepCopy());
553 TestBadRequest(message); 596 TestBadRequest(message);
554 } 597 }
555 598
556 } // namespace remoting 599 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698