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

Side by Side Diff: mojo/public/cpp/bindings/tests/binding_unittest.cc

Issue 2326913003: Privatize StrongBinding lifetime management (Closed)
Patch Set: . Created 4 years, 3 months 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h 5 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h
6 // (mojo::StrongBinding). 6 // (mojo::StrongBinding).
7 7
8 #include "mojo/public/cpp/bindings/binding.h" 8 #include "mojo/public/cpp/bindings/binding.h"
9 9
10 #include <stdint.h> 10 #include <stdint.h>
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 // StrongBindingTest ----------------------------------------------------------- 427 // StrongBindingTest -----------------------------------------------------------
428 428
429 using StrongBindingTest = BindingTestBase; 429 using StrongBindingTest = BindingTestBase;
430 430
431 // Tests that destroying a mojo::StrongBinding closes the bound message pipe 431 // Tests that destroying a mojo::StrongBinding closes the bound message pipe
432 // handle but does *not* destroy the implementation object. 432 // handle but does *not* destroy the implementation object.
433 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { 433 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) {
434 base::RunLoop run_loop; 434 base::RunLoop run_loop;
435 bool encountered_error = false; 435 bool encountered_error = false;
436 bool was_deleted = false; 436 bool was_deleted = false;
437 ServiceImpl impl(&was_deleted);
438 sample::ServicePtr ptr; 437 sample::ServicePtr ptr;
439 auto request = GetProxy(&ptr); 438 auto request = GetProxy(&ptr);
440 ptr.set_connection_error_handler( 439 ptr.set_connection_error_handler(
441 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); 440 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
442 bool called = false; 441 bool called = false;
443 base::RunLoop run_loop2; 442 base::RunLoop run_loop2;
444 { 443
445 StrongBinding<sample::Service> binding(&impl, std::move(request)); 444 auto binding = MakeStrongBinding(
446 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, 445 base::MakeUnique<ServiceImpl>(&was_deleted), std::move(request));
447 SetFlagAndRunClosure<int32_t>(&called, 446 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
448 run_loop2.QuitClosure())); 447 SetFlagAndRunClosure<int32_t>(&called,
449 run_loop2.Run(); 448 run_loop2.QuitClosure()));
450 EXPECT_TRUE(called); 449 run_loop2.Run();
451 EXPECT_FALSE(encountered_error); 450 EXPECT_TRUE(called);
452 } 451 EXPECT_FALSE(encountered_error);
453 // Now that the StrongBinding is out of scope we should detect an error on the 452 binding->Close();
454 // other end of the pipe. 453
454 // Now that the StrongBinding is closed we should detect an error on the other
455 // end of the pipe.
455 run_loop.Run(); 456 run_loop.Run();
456 EXPECT_TRUE(encountered_error); 457 EXPECT_TRUE(encountered_error);
457 // But destroying the StrongBinding doesn't destroy the object. 458
458 ASSERT_FALSE(was_deleted); 459 // Destroying the StrongBinding also destroys the impl.
460 ASSERT_TRUE(was_deleted);
459 } 461 }
460 462
461 class ServiceImplWithStrongBinding : public ServiceImpl {
462 public:
463 ServiceImplWithStrongBinding(bool* was_deleted,
464 InterfaceRequest<sample::Service> request)
465 : ServiceImpl(was_deleted), binding_(this, std::move(request)) {}
466
467 StrongBinding<sample::Service>& binding() { return binding_; }
468
469 private:
470 StrongBinding<sample::Service> binding_;
471
472 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithStrongBinding);
473 };
474
475 // Tests the typical case, where the implementation object owns the 463 // Tests the typical case, where the implementation object owns the
476 // StrongBinding (and should be destroyed on connection error). 464 // StrongBinding (and should be destroyed on connection error).
477 TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) { 465 TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
478 sample::ServicePtr ptr; 466 sample::ServicePtr ptr;
479 bool was_deleted = false; 467 bool was_deleted = false;
480 // Will delete itself. 468 // Will delete itself.
481 base::RunLoop run_loop; 469 base::RunLoop run_loop;
482 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), 470 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(),
483 GetProxy(&ptr)); 471 GetProxy(&ptr));
484 472
485 base::RunLoop().RunUntilIdle(); 473 base::RunLoop().RunUntilIdle();
486 EXPECT_FALSE(was_deleted); 474 EXPECT_FALSE(was_deleted);
487 475
488 ptr.reset(); 476 ptr.reset();
489 EXPECT_FALSE(was_deleted); 477 EXPECT_FALSE(was_deleted);
490 run_loop.Run(); 478 run_loop.Run();
491 EXPECT_TRUE(was_deleted); 479 EXPECT_TRUE(was_deleted);
492 } 480 }
493 481
494 // Tests that even when the implementation object owns the StrongBinding, that
yzshen1 2016/09/09 16:21:30 This pattern seems pretty weird. +1 that StrongBin
495 // the implementation can still be deleted (which should result in the message
496 // pipe being closed). Also checks that the connection error handler doesn't get
497 // called.
498 TEST_F(StrongBindingTest, ExplicitDeleteImpl) {
499 bool ptr_error_handler_called = false;
500 sample::ServicePtr ptr;
501 auto request = GetProxy(&ptr);
502 base::RunLoop run_loop;
503 ptr.set_connection_error_handler(
504 SetFlagAndRunClosure(&ptr_error_handler_called, run_loop.QuitClosure()));
505 bool was_deleted = false;
506 ServiceImplWithStrongBinding* impl =
507 new ServiceImplWithStrongBinding(&was_deleted, std::move(request));
508 bool binding_error_handler_called = false;
509 impl->binding().set_connection_error_handler(
510 SetFlagAndRunClosure(&binding_error_handler_called));
511
512 base::RunLoop().RunUntilIdle();
513 EXPECT_FALSE(ptr_error_handler_called);
514 EXPECT_FALSE(was_deleted);
515
516 delete impl;
517 EXPECT_FALSE(ptr_error_handler_called);
518 EXPECT_TRUE(was_deleted);
519 was_deleted = false; // It shouldn't be double-deleted!
520 run_loop.Run();
521 EXPECT_TRUE(ptr_error_handler_called);
522 EXPECT_FALSE(was_deleted);
523
524 EXPECT_FALSE(binding_error_handler_called);
525 }
526
527 TEST_F(StrongBindingTest, FlushForTesting) { 482 TEST_F(StrongBindingTest, FlushForTesting) {
528 bool called = false; 483 bool called = false;
529 bool was_deleted = false; 484 bool was_deleted = false;
530 sample::ServicePtr ptr; 485 sample::ServicePtr ptr;
531 auto request = GetProxy(&ptr); 486 auto request = GetProxy(&ptr);
532 StrongBinding<sample::Service> binding(new ServiceImpl(&was_deleted), 487 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
533 std::move(request)); 488 std::move(request));
534 binding.set_connection_error_handler(base::Bind(&Fail)); 489 binding->set_connection_error_handler(base::Bind(&Fail));
535 490
536 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, 491 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
537 SetFlagAndRunClosure<int32_t>(&called)); 492 SetFlagAndRunClosure<int32_t>(&called));
538 EXPECT_FALSE(called); 493 EXPECT_FALSE(called);
539 // Because the flush is sent from the binding, it only guarantees that the 494 // Because the flush is sent from the binding, it only guarantees that the
540 // request has been received, not the response. The second flush waits for the 495 // request has been received, not the response. The second flush waits for the
541 // response to be received. 496 // response to be received.
542 binding.FlushForTesting(); 497 ASSERT_TRUE(binding);
543 binding.FlushForTesting(); 498 binding->FlushForTesting();
499 ASSERT_TRUE(binding);
500 binding->FlushForTesting();
544 EXPECT_TRUE(called); 501 EXPECT_TRUE(called);
545 EXPECT_FALSE(was_deleted); 502 EXPECT_FALSE(was_deleted);
546 ptr.reset(); 503 ptr.reset();
547 binding.set_connection_error_handler(base::Closure()); 504 ASSERT_TRUE(binding);
548 binding.FlushForTesting(); 505 binding->set_connection_error_handler(base::Closure());
506 binding->FlushForTesting();
549 EXPECT_TRUE(was_deleted); 507 EXPECT_TRUE(was_deleted);
550 } 508 }
551 509
552 TEST_F(StrongBindingTest, FlushForTestingWithClosedPeer) { 510 TEST_F(StrongBindingTest, FlushForTestingWithClosedPeer) {
553 bool called = false; 511 bool called = false;
554 bool was_deleted = false; 512 bool was_deleted = false;
555 sample::ServicePtr ptr; 513 sample::ServicePtr ptr;
556 auto request = GetProxy(&ptr); 514 auto request = GetProxy(&ptr);
557 StrongBinding<sample::Service> binding(new ServiceImpl(&was_deleted), 515 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
558 std::move(request)); 516 std::move(request));
559 binding.set_connection_error_handler(SetFlagAndRunClosure(&called)); 517 binding->set_connection_error_handler(SetFlagAndRunClosure(&called));
560 ptr.reset(); 518 ptr.reset();
561 519
562 EXPECT_FALSE(called); 520 EXPECT_FALSE(called);
563 EXPECT_FALSE(was_deleted); 521 EXPECT_FALSE(was_deleted);
564 binding.FlushForTesting(); 522 ASSERT_TRUE(binding);
523 binding->FlushForTesting();
565 EXPECT_TRUE(called); 524 EXPECT_TRUE(called);
566 EXPECT_TRUE(was_deleted); 525 EXPECT_TRUE(was_deleted);
567 binding.FlushForTesting(); 526 ASSERT_FALSE(binding);
568 EXPECT_TRUE(was_deleted);
569 } 527 }
570 528
571 } // namespace 529 } // namespace
572 } // mojo 530 } // mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698