OLD | NEW |
---|---|
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 TestSyncAssoImpl : public TestSync, public TestSyncCommonImpl { | |
Ken Rockot(use gerrit already)
2016/03/29 06:36:50
nit: This name is a bit weird. Could it just be Te
yzshen1
2016/03/29 16:19:01
Done.
| |
136 public: | |
137 explicit TestSyncAssoImpl(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(TestSyncAssoImpl); | |
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 Loading... | |
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 Loading... | |
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 TestSyncAssoImpl 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 TestSyncAssoImpl 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 |
OLD | NEW |