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

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

Issue 2515873003: Mojo C++ Bindings: Introduce mojo::SupportsStrongBinding
Patch Set: . Created 4 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 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 18 matching lines...) Expand all
29 ~BindingTestBase() override {} 29 ~BindingTestBase() override {}
30 30
31 base::MessageLoop& loop() { return loop_; } 31 base::MessageLoop& loop() { return loop_; }
32 32
33 private: 33 private:
34 base::MessageLoop loop_; 34 base::MessageLoop loop_;
35 35
36 DISALLOW_COPY_AND_ASSIGN(BindingTestBase); 36 DISALLOW_COPY_AND_ASSIGN(BindingTestBase);
37 }; 37 };
38 38
39 class ServiceImpl : public sample::Service { 39 class ServiceImpl : public SupportsStrongBinding<sample::Service> {
40 public: 40 public:
41 explicit ServiceImpl(bool* was_deleted = nullptr) 41 explicit ServiceImpl(
42 : was_deleted_(was_deleted) {} 42 bool* was_deleted = nullptr,
43 const base::Closure& destruction_callback = base::Closure())
44 : was_deleted_(was_deleted),
45 destruction_callback_(destruction_callback) {}
43 ~ServiceImpl() override { 46 ~ServiceImpl() override {
44 if (was_deleted_) 47 if (was_deleted_)
45 *was_deleted_ = true; 48 *was_deleted_ = true;
49 if (!destruction_callback_.is_null())
50 destruction_callback_.Run();
46 } 51 }
47 52
48 private: 53 private:
49 // sample::Service implementation 54 // sample::Service implementation
50 void Frobinate(sample::FooPtr foo, 55 void Frobinate(sample::FooPtr foo,
51 BazOptions options, 56 BazOptions options,
52 sample::PortPtr port, 57 sample::PortPtr port,
53 const FrobinateCallback& callback) override { 58 const FrobinateCallback& callback) override {
54 callback.Run(1); 59 callback.Run(1);
55 } 60 }
56 void GetPort(InterfaceRequest<sample::Port> port) override {} 61 void GetPort(InterfaceRequest<sample::Port> port) override {}
57 62
58 bool* const was_deleted_; 63 bool* const was_deleted_;
64 const base::Closure destruction_callback_;
59 65
60 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); 66 DISALLOW_COPY_AND_ASSIGN(ServiceImpl);
61 }; 67 };
62 68
63 template <typename... Args> 69 template <typename... Args>
64 void DoSetFlagAndRunClosure(bool* flag, 70 void DoSetFlagAndRunClosure(bool* flag,
65 const base::Closure& closure, 71 const base::Closure& closure,
66 Args... args) { 72 Args... args) {
67 *flag = true; 73 *flag = true;
68 if (!closure.is_null()) 74 if (!closure.is_null())
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // We can also close the other end, and the error handler still won't be 172 // We can also close the other end, and the error handler still won't be
167 // called. 173 // called.
168 ptr.reset(); 174 ptr.reset();
169 base::RunLoop().RunUntilIdle(); 175 base::RunLoop().RunUntilIdle();
170 EXPECT_FALSE(called); 176 EXPECT_FALSE(called);
171 } 177 }
172 178
173 class ServiceImplWithBinding : public ServiceImpl { 179 class ServiceImplWithBinding : public ServiceImpl {
174 public: 180 public:
175 ServiceImplWithBinding(bool* was_deleted, 181 ServiceImplWithBinding(bool* was_deleted,
176 const base::Closure& closure, 182 const base::Closure& destruction_callback,
177 InterfaceRequest<sample::Service> request) 183 InterfaceRequest<sample::Service> request)
178 : ServiceImpl(was_deleted), 184 : ServiceImpl(was_deleted, destruction_callback),
179 binding_(this, std::move(request)), 185 binding_(this, std::move(request)) {
180 closure_(closure) {
181 binding_.set_connection_error_handler( 186 binding_.set_connection_error_handler(
182 base::Bind(&ServiceImplWithBinding::OnConnectionError, 187 base::Bind(&ServiceImplWithBinding::OnConnectionError,
183 base::Unretained(this))); 188 base::Unretained(this)));
184 } 189 }
185 190
186 private: 191 private:
187 ~ServiceImplWithBinding() override{
188 closure_.Run();
189 }
190
191 void OnConnectionError() { delete this; } 192 void OnConnectionError() { delete this; }
192 193
193 Binding<sample::Service> binding_; 194 Binding<sample::Service> binding_;
194 base::Closure closure_;
195 195
196 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); 196 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding);
197 }; 197 };
198 198
199 // Tests that the binding may be deleted in the connection error handler. 199 // Tests that the binding may be deleted in the connection error handler.
200 TEST_F(BindingTest, SelfDeleteOnConnectionError) { 200 TEST_F(BindingTest, SelfDeleteOnConnectionError) {
201 bool was_deleted = false; 201 bool was_deleted = false;
202 sample::ServicePtr ptr; 202 sample::ServicePtr ptr;
203 // This should delete itself on connection error. 203 // This should delete itself on connection error.
204 base::RunLoop run_loop; 204 base::RunLoop run_loop;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 proxy.set_connection_error_handler(run_loop.QuitClosure()); 481 proxy.set_connection_error_handler(run_loop.QuitClosure());
482 weak_factory.InvalidateWeakPtrs(); 482 weak_factory.InvalidateWeakPtrs();
483 run_loop.Run(); 483 run_loop.Run();
484 } 484 }
485 } 485 }
486 486
487 // StrongBindingTest ----------------------------------------------------------- 487 // StrongBindingTest -----------------------------------------------------------
488 488
489 using StrongBindingTest = BindingTestBase; 489 using StrongBindingTest = BindingTestBase;
490 490
491 // Tests that destroying a mojo::StrongBinding closes the bound message pipe
492 // handle but does *not* destroy the implementation object.
493 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) {
494 base::RunLoop run_loop;
495 bool encountered_error = false;
496 bool was_deleted = false;
497 sample::ServicePtr ptr;
498 auto request = GetProxy(&ptr);
499 ptr.set_connection_error_handler(
500 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
501 bool called = false;
502 base::RunLoop run_loop2;
503
504 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
505 std::move(request));
506 ptr->Frobinate(
507 nullptr, sample::Service::BazOptions::REGULAR, nullptr,
508 SetFlagAndRunClosure<int32_t>(&called, run_loop2.QuitClosure()));
509 run_loop2.Run();
510 EXPECT_TRUE(called);
511 EXPECT_FALSE(encountered_error);
512 binding->Close();
513
514 // Now that the StrongBinding is closed we should detect an error on the other
515 // end of the pipe.
516 run_loop.Run();
517 EXPECT_TRUE(encountered_error);
518
519 // Destroying the StrongBinding also destroys the impl.
520 ASSERT_TRUE(was_deleted);
521 }
522
523 // Tests the typical case, where the implementation object owns the
524 // StrongBinding (and should be destroyed on connection error).
525 TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) { 491 TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
526 sample::ServicePtr ptr; 492 sample::ServicePtr ptr;
527 bool was_deleted = false; 493 bool was_deleted = false;
528 // Will delete itself. 494
529 base::RunLoop run_loop; 495 base::RunLoop run_loop;
530 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), 496 StrongBindingPtr<sample::Service> weak_binding = mojo::MakeStrongBinding(
531 GetProxy(&ptr)); 497 base::MakeUnique<ServiceImpl>(&was_deleted, run_loop.QuitClosure()),
532 498 GetProxy(&ptr));
533 base::RunLoop().RunUntilIdle();
534 EXPECT_FALSE(was_deleted);
535
536 ptr.reset(); 499 ptr.reset();
537 EXPECT_FALSE(was_deleted); 500 EXPECT_FALSE(was_deleted);
538 run_loop.Run(); 501 run_loop.Run();
539 EXPECT_TRUE(was_deleted); 502 EXPECT_TRUE(was_deleted);
503 EXPECT_FALSE(weak_binding);
504 }
505
506 TEST_F(StrongBindingTest, ExplicitImplDeletionIsSafe) {
507 sample::ServicePtr ptr;
508 bool was_deleted = false;
509
510 base::Closure close_callback;
511
512 std::unique_ptr<ServiceImpl> impl =
513 base::MakeUnique<ServiceImpl>(&was_deleted);
514 ServiceImpl* raw_impl = impl.get();
515 StrongBindingPtr<sample::Service> weak_binding =
516 mojo::MakeStrongBinding(std::move(impl), GetProxy(&ptr));
517
518 EXPECT_FALSE(was_deleted);
519
520 base::RunLoop run_loop;
521 ptr.set_connection_error_handler(run_loop.QuitClosure());
522
523 EXPECT_TRUE(weak_binding);
524
525 delete raw_impl;
526
527 EXPECT_TRUE(was_deleted);
528 EXPECT_FALSE(weak_binding);
529
530 run_loop.Run();
540 } 531 }
541 532
542 TEST_F(StrongBindingTest, FlushForTesting) { 533 TEST_F(StrongBindingTest, FlushForTesting) {
543 bool called = false; 534 bool called = false;
544 bool was_deleted = false; 535 bool was_deleted = false;
545 sample::ServicePtr ptr; 536 sample::ServicePtr ptr;
546 auto request = GetProxy(&ptr); 537 auto request = GetProxy(&ptr);
547 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), 538 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
548 std::move(request)); 539 std::move(request));
549 binding->set_connection_error_handler(base::Bind(&Fail)); 540 binding->set_connection_error_handler(base::Bind(&Fail));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 }, 592 },
602 run_loop.QuitClosure())); 593 run_loop.QuitClosure()));
603 594
604 ptr.ResetWithReason(5678u, "hello"); 595 ptr.ResetWithReason(5678u, "hello");
605 596
606 run_loop.Run(); 597 run_loop.Run();
607 } 598 }
608 599
609 } // namespace 600 } // namespace
610 } // mojo 601 } // mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698