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

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

Issue 1823683006: Mojo C++ bindings: sync call support for associated interfaces and master interfaces (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/threading/thread.h" 10 #include "base/threading/thread.h"
11 #include "mojo/message_pump/message_pump_mojo.h" 11 #include "mojo/message_pump/message_pump_mojo.h"
12 #include "mojo/public/cpp/bindings/associated_binding.h"
12 #include "mojo/public/cpp/bindings/binding.h" 13 #include "mojo/public/cpp/bindings/binding.h"
13 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" 14 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 16
16 namespace mojo { 17 namespace mojo {
17 namespace test { 18 namespace test {
18 namespace { 19 namespace {
19 20
20 class TestSyncCommonImpl { 21 class TestSyncCommonImpl {
21 public: 22 public:
22 TestSyncCommonImpl() {} 23 TestSyncCommonImpl() {}
23 24
24 using PingHandler = Callback<void(const Callback<void()>&)>; 25 using PingHandler = Callback<void(const Callback<void()>&)>;
25 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; } 26 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; }
26 27
27 using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>; 28 using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>;
28 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } 29 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; }
29 30
30 using AsyncEchoHandler = 31 using AsyncEchoHandler =
31 Callback<void(int32_t, const Callback<void(int32_t)>&)>; 32 Callback<void(int32_t, const Callback<void(int32_t)>&)>;
32 void set_async_echo_handler(const AsyncEchoHandler& handler) { 33 void set_async_echo_handler(const AsyncEchoHandler& handler) {
33 async_echo_handler_ = handler; 34 async_echo_handler_ = handler;
34 } 35 }
35 36
37 using SendInterfaceHandler = Callback<void(TestSyncAssociatedPtrInfo)>;
38 void set_send_interface_handler(const SendInterfaceHandler& handler) {
39 send_interface_handler_ = handler;
40 }
41
42 using SendRequestHandler = Callback<void(TestSyncAssociatedRequest)>;
43 void set_send_request_handler(const SendRequestHandler& handler) {
44 send_request_handler_ = handler;
45 }
46
36 void PingImpl(const Callback<void()>& callback) { 47 void PingImpl(const Callback<void()>& callback) {
37 if (ping_handler_.is_null()) { 48 if (ping_handler_.is_null()) {
38 callback.Run(); 49 callback.Run();
39 return; 50 return;
40 } 51 }
41 ping_handler_.Run(callback); 52 ping_handler_.Run(callback);
42 } 53 }
43 void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { 54 void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) {
44 if (echo_handler_.is_null()) { 55 if (echo_handler_.is_null()) {
45 callback.Run(value); 56 callback.Run(value);
46 return; 57 return;
47 } 58 }
48 echo_handler_.Run(value, callback); 59 echo_handler_.Run(value, callback);
49 } 60 }
50 void AsyncEchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { 61 void AsyncEchoImpl(int32_t value, const Callback<void(int32_t)>& callback) {
51 if (async_echo_handler_.is_null()) { 62 if (async_echo_handler_.is_null()) {
52 callback.Run(value); 63 callback.Run(value);
53 return; 64 return;
54 } 65 }
55 async_echo_handler_.Run(value, callback); 66 async_echo_handler_.Run(value, callback);
56 } 67 }
68 void SendInterfaceImpl(TestSyncAssociatedPtrInfo ptr) {
69 send_interface_handler_.Run(std::move(ptr));
70 }
71 void SendRequestImpl(TestSyncAssociatedRequest request) {
72 send_request_handler_.Run(std::move(request));
73 }
57 74
58 private: 75 private:
59 PingHandler ping_handler_; 76 PingHandler ping_handler_;
60 EchoHandler echo_handler_; 77 EchoHandler echo_handler_;
61 AsyncEchoHandler async_echo_handler_; 78 AsyncEchoHandler async_echo_handler_;
79 SendInterfaceHandler send_interface_handler_;
80 SendRequestHandler send_request_handler_;
62 81
63 DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl); 82 DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl);
64 }; 83 };
65 84
66 class TestSyncImpl : public TestSync, public TestSyncCommonImpl { 85 class TestSyncImpl : public TestSync, public TestSyncCommonImpl {
67 public: 86 public:
68 explicit TestSyncImpl(TestSyncRequest request) 87 explicit TestSyncImpl(TestSyncRequest request)
69 : binding_(this, std::move(request)) {} 88 : binding_(this, std::move(request)) {}
70 89
71 // TestSync implementation: 90 // TestSync implementation:
72 void Ping(const PingCallback& callback) override { PingImpl(callback); } 91 void Ping(const PingCallback& callback) override { PingImpl(callback); }
73 void Echo(int32_t value, const EchoCallback& callback) override { 92 void Echo(int32_t value, const EchoCallback& callback) override {
74 EchoImpl(value, callback); 93 EchoImpl(value, callback);
75 } 94 }
76 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { 95 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override {
77 AsyncEchoImpl(value, callback); 96 AsyncEchoImpl(value, callback);
78 } 97 }
79 98
80 Binding<TestSync>* binding() { return &binding_; } 99 Binding<TestSync>* binding() { return &binding_; }
81 100
82 private: 101 private:
83 Binding<TestSync> binding_; 102 Binding<TestSync> binding_;
84 103
85 DISALLOW_COPY_AND_ASSIGN(TestSyncImpl); 104 DISALLOW_COPY_AND_ASSIGN(TestSyncImpl);
86 }; 105 };
87 106
107 class TestSyncMasterImpl : public TestSyncMaster, public TestSyncCommonImpl {
108 public:
109 explicit TestSyncMasterImpl(TestSyncMasterRequest request)
110 : binding_(this, std::move(request)) {}
111
112 // TestSyncMaster implementation:
113 void Ping(const PingCallback& callback) override { PingImpl(callback); }
114 void Echo(int32_t value, const EchoCallback& callback) override {
115 EchoImpl(value, callback);
116 }
117 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override {
118 AsyncEchoImpl(value, callback);
119 }
120 void SendInterface(TestSyncAssociatedPtrInfo ptr) override {
121 SendInterfaceImpl(std::move(ptr));
122 }
123 void SendRequest(TestSyncAssociatedRequest request) override {
124 SendRequestImpl(std::move(request));
125 }
126
127 Binding<TestSyncMaster>* binding() { return &binding_; }
128
129 private:
130 Binding<TestSyncMaster> binding_;
131
132 DISALLOW_COPY_AND_ASSIGN(TestSyncMasterImpl);
133 };
134
135 class TestSyncAssociatedImpl : public TestSync, public TestSyncCommonImpl {
136 public:
137 explicit TestSyncAssociatedImpl(TestSyncAssociatedRequest request)
138 : binding_(this, std::move(request)) {}
139
140 // TestSync implementation:
141 void Ping(const PingCallback& callback) override { PingImpl(callback); }
142 void Echo(int32_t value, const EchoCallback& callback) override {
143 EchoImpl(value, callback);
144 }
145 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override {
146 AsyncEchoImpl(value, callback);
147 }
148
149 AssociatedBinding<TestSync>* binding() { return &binding_; }
150
151 private:
152 AssociatedBinding<TestSync> binding_;
153
154 DISALLOW_COPY_AND_ASSIGN(TestSyncAssociatedImpl);
155 };
156
88 template <typename Interface> 157 template <typename Interface>
89 struct ImplTraits; 158 struct ImplTraits;
90 159
91 template <> 160 template <>
92 struct ImplTraits<TestSync> { 161 struct ImplTraits<TestSync> {
93 using Type = TestSyncImpl; 162 using Type = TestSyncImpl;
94 }; 163 };
95 164
165 template <>
166 struct ImplTraits<TestSyncMaster> {
167 using Type = TestSyncMasterImpl;
168 };
169
96 template <typename Interface> 170 template <typename Interface>
97 class TestSyncServiceThread { 171 class TestSyncServiceThread {
98 public: 172 public:
99 TestSyncServiceThread() 173 TestSyncServiceThread()
100 : thread_("TestSyncServiceThread"), ping_called_(false) { 174 : thread_("TestSyncServiceThread"), ping_called_(false) {
101 base::Thread::Options thread_options; 175 base::Thread::Options thread_options;
102 thread_options.message_pump_factory = 176 thread_options.message_pump_factory =
103 base::Bind(&common::MessagePumpMojo::Create); 177 base::Bind(&common::MessagePumpMojo::Create);
104 thread_.StartWithOptions(thread_options); 178 thread_.StartWithOptions(thread_options);
105 } 179 }
(...skipping 26 matching lines...) Expand all
132 base::Thread thread_; 206 base::Thread thread_;
133 207
134 scoped_ptr<typename ImplTraits<Interface>::Type> impl_; 208 scoped_ptr<typename ImplTraits<Interface>::Type> impl_;
135 209
136 mutable base::Lock lock_; 210 mutable base::Lock lock_;
137 bool ping_called_; 211 bool ping_called_;
138 212
139 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); 213 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread);
140 }; 214 };
141 215
142 template <typename T> 216 class SyncMethodTest : public testing::Test {
143 class SyncMethodCommonTest : public testing::Test {
144 public: 217 public:
145 SyncMethodCommonTest() : loop_(common::MessagePumpMojo::Create()) {} 218 SyncMethodTest() : loop_(common::MessagePumpMojo::Create()) {}
146 ~SyncMethodCommonTest() override { loop_.RunUntilIdle(); } 219 ~SyncMethodTest() override { loop_.RunUntilIdle(); }
147 220
148 private: 221 protected:
149 base::MessageLoop loop_; 222 base::MessageLoop loop_;
150 }; 223 };
151 224
152 using InterfaceTypes = testing::Types<TestSync>; 225 template <typename T>
226 class SyncMethodCommonTest : public SyncMethodTest {
227 public:
228 SyncMethodCommonTest() {}
229 ~SyncMethodCommonTest() override {}
230 };
231
232 class SyncMethodAssociatedTest : public SyncMethodTest {
233 public:
234 SyncMethodAssociatedTest() {}
235 ~SyncMethodAssociatedTest() override {}
236
237 protected:
238 void SetUp() override {
239 master_impl_.reset(new TestSyncMasterImpl(GetProxy(&master_ptr_)));
240
241 master_ptr_.associated_group()->CreateAssociatedInterface(
242 AssociatedGroup::WILL_PASS_REQUEST, &asso_ptr_info_, &asso_request_);
243 master_ptr_.associated_group()->CreateAssociatedInterface(
244 AssociatedGroup::WILL_PASS_PTR, &opposite_asso_ptr_info_,
245 &opposite_asso_request_);
246
247 master_impl_->set_send_interface_handler(
248 [this](TestSyncAssociatedPtrInfo ptr) {
249 opposite_asso_ptr_info_ = std::move(ptr);
250 });
251 base::RunLoop run_loop;
252 master_impl_->set_send_request_handler(
253 [this, &run_loop](TestSyncAssociatedRequest request) {
254 asso_request_ = std::move(request);
255 run_loop.Quit();
256 });
257
258 master_ptr_->SendInterface(std::move(opposite_asso_ptr_info_));
259 master_ptr_->SendRequest(std::move(asso_request_));
260 run_loop.Run();
261 }
262
263 void TearDown() override {
264 asso_ptr_info_ = TestSyncAssociatedPtrInfo();
265 asso_request_ = TestSyncAssociatedRequest();
266 opposite_asso_ptr_info_ = TestSyncAssociatedPtrInfo();
267 opposite_asso_request_ = TestSyncAssociatedRequest();
268
269 master_ptr_ = nullptr;
270 master_impl_.reset();
271 }
272
273 InterfacePtr<TestSyncMaster> master_ptr_;
274 scoped_ptr<TestSyncMasterImpl> master_impl_;
275
276 // An associated interface whose binding lives at the |master_impl_| side.
277 TestSyncAssociatedPtrInfo asso_ptr_info_;
278 TestSyncAssociatedRequest asso_request_;
279
280 // An associated interface whose binding lives at the |master_ptr_| side.
281 TestSyncAssociatedPtrInfo opposite_asso_ptr_info_;
282 TestSyncAssociatedRequest opposite_asso_request_;
283 };
284
285 // TestSync and TestSyncMaster exercise Router and MultiplexRouter,
286 // respectively.
287 using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>;
153 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); 288 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes);
154 289
155 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { 290 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) {
156 InterfacePtr<TypeParam> ptr; 291 InterfacePtr<TypeParam> ptr;
157 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); 292 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
158 293
159 base::RunLoop run_loop; 294 base::RunLoop run_loop;
160 ptr->Echo(123, [&run_loop](int32_t result) { 295 ptr->Echo(123, [&run_loop](int32_t result) {
161 EXPECT_EQ(123, result); 296 EXPECT_EQ(123, result);
162 run_loop.Quit(); 297 run_loop.Quit();
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 625
491 int32_t result_value = -1; 626 int32_t result_value = -1;
492 ASSERT_FALSE(ptr->Echo(456, &result_value)); 627 ASSERT_FALSE(ptr->Echo(456, &result_value));
493 EXPECT_EQ(-1, result_value); 628 EXPECT_EQ(-1, result_value);
494 ASSERT_FALSE(connection_error_dispatched); 629 ASSERT_FALSE(connection_error_dispatched);
495 630
496 run_loop.Run(); 631 run_loop.Run();
497 ASSERT_TRUE(connection_error_dispatched); 632 ASSERT_TRUE(connection_error_dispatched);
498 } 633 }
499 634
635 TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) {
636 // Test that an interface pointer waiting for a sync call response can be
637 // reentered by an associated binding serving sync methods on the same thread.
638 // The associated binding belongs to the same MultiplexRouter as the waiting
639 // interface pointer.
640
641 TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_));
642 TestSyncAssociatedPtr opposite_asso_ptr;
643 opposite_asso_ptr.Bind(std::move(opposite_asso_ptr_info_));
644
645 master_impl_->set_echo_handler([&opposite_asso_ptr](
646 int32_t value, const TestSyncMaster::EchoCallback& callback) {
647 int32_t result_value = -1;
648
649 ASSERT_TRUE(opposite_asso_ptr->Echo(123, &result_value));
650 EXPECT_EQ(123, result_value);
651 callback.Run(value);
652 });
653
654 int32_t result_value = -1;
655 ASSERT_TRUE(master_ptr_->Echo(456, &result_value));
656 EXPECT_EQ(456, result_value);
657 }
658
659 TEST_F(SyncMethodAssociatedTest,
660 ReenteredBySyncMethodAssoBindingOfDifferentRouter) {
661 // Test that an interface pointer waiting for a sync call response can be
662 // reentered by an associated binding serving sync methods on the same thread.
663 // The associated binding belongs to a different MultiplexRouter as the
664 // waiting interface pointer.
665
666 TestSyncAssociatedImpl asso_impl(std::move(asso_request_));
667 TestSyncAssociatedPtr asso_ptr;
668 asso_ptr.Bind(std::move(asso_ptr_info_));
669
670 master_impl_->set_echo_handler(
671 [&asso_ptr](int32_t value, const TestSyncMaster::EchoCallback& callback) {
672 int32_t result_value = -1;
673
674 ASSERT_TRUE(asso_ptr->Echo(123, &result_value));
675 EXPECT_EQ(123, result_value);
676 callback.Run(value);
677 });
678
679 int32_t result_value = -1;
680 ASSERT_TRUE(master_ptr_->Echo(456, &result_value));
681 EXPECT_EQ(456, result_value);
682 }
683
684 // TODO(yzshen): Add more tests related to associated interfaces.
685
500 } // namespace 686 } // namespace
501 } // namespace test 687 } // namespace test
502 } // namespace mojo 688 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698