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 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 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 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 |
OLD | NEW |