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/binding.h" | 12 #include "mojo/public/cpp/bindings/binding.h" |
13 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" | 13 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 | 15 |
16 namespace mojo { | 16 namespace mojo { |
17 namespace test { | 17 namespace test { |
18 namespace { | 18 namespace { |
19 | 19 |
20 class SyncMethodTest : public testing::Test { | 20 class TestSyncCommonImpl { |
21 public: | 21 public: |
22 SyncMethodTest() : loop_(common::MessagePumpMojo::Create()) {} | 22 TestSyncCommonImpl() {} |
23 ~SyncMethodTest() override { loop_.RunUntilIdle(); } | |
24 | 23 |
25 private: | 24 using PingHandler = Callback<void(const Callback<void()>&)>; |
26 base::MessageLoop loop_; | |
27 }; | |
28 | |
29 class TestSyncImpl : public TestSync { | |
30 public: | |
31 TestSyncImpl(TestSyncRequest request) : binding_(this, std::move(request)) {} | |
32 | |
33 using PingHandler = Callback<void(const PingCallback&)>; | |
34 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; } | 25 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; } |
35 | 26 |
36 using EchoHandler = Callback<void(int32_t, const EchoCallback&)>; | 27 using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>; |
37 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } | 28 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } |
38 | 29 |
39 using AsyncEchoHandler = Callback<void(int32_t, const AsyncEchoCallback&)>; | 30 using AsyncEchoHandler = |
| 31 Callback<void(int32_t, const Callback<void(int32_t)>&)>; |
40 void set_async_echo_handler(const AsyncEchoHandler& handler) { | 32 void set_async_echo_handler(const AsyncEchoHandler& handler) { |
41 async_echo_handler_ = handler; | 33 async_echo_handler_ = handler; |
42 } | 34 } |
43 | 35 |
44 // TestSync implementation: | 36 void PingImpl(const Callback<void()>& callback) { |
45 void Ping(const PingCallback& callback) override { | |
46 if (ping_handler_.is_null()) { | 37 if (ping_handler_.is_null()) { |
47 callback.Run(); | 38 callback.Run(); |
48 return; | 39 return; |
49 } | 40 } |
50 ping_handler_.Run(callback); | 41 ping_handler_.Run(callback); |
51 } | 42 } |
52 void Echo(int32_t value, const EchoCallback& callback) override { | 43 void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { |
53 if (echo_handler_.is_null()) { | 44 if (echo_handler_.is_null()) { |
54 callback.Run(value); | 45 callback.Run(value); |
55 return; | 46 return; |
56 } | 47 } |
57 echo_handler_.Run(value, callback); | 48 echo_handler_.Run(value, callback); |
58 } | 49 } |
59 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { | 50 void AsyncEchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { |
60 if (async_echo_handler_.is_null()) { | 51 if (async_echo_handler_.is_null()) { |
61 callback.Run(value); | 52 callback.Run(value); |
62 return; | 53 return; |
63 } | 54 } |
64 async_echo_handler_.Run(value, callback); | 55 async_echo_handler_.Run(value, callback); |
65 } | 56 } |
66 | 57 |
| 58 private: |
| 59 PingHandler ping_handler_; |
| 60 EchoHandler echo_handler_; |
| 61 AsyncEchoHandler async_echo_handler_; |
| 62 |
| 63 DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl); |
| 64 }; |
| 65 |
| 66 class TestSyncImpl : public TestSync, public TestSyncCommonImpl { |
| 67 public: |
| 68 explicit TestSyncImpl(TestSyncRequest request) |
| 69 : binding_(this, std::move(request)) {} |
| 70 |
| 71 // TestSync implementation: |
| 72 void Ping(const PingCallback& callback) override { PingImpl(callback); } |
| 73 void Echo(int32_t value, const EchoCallback& callback) override { |
| 74 EchoImpl(value, callback); |
| 75 } |
| 76 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { |
| 77 AsyncEchoImpl(value, callback); |
| 78 } |
| 79 |
67 Binding<TestSync>* binding() { return &binding_; } | 80 Binding<TestSync>* binding() { return &binding_; } |
68 | 81 |
69 private: | 82 private: |
70 Binding<TestSync> binding_; | 83 Binding<TestSync> binding_; |
71 PingHandler ping_handler_; | |
72 EchoHandler echo_handler_; | |
73 AsyncEchoHandler async_echo_handler_; | |
74 | 84 |
75 DISALLOW_COPY_AND_ASSIGN(TestSyncImpl); | 85 DISALLOW_COPY_AND_ASSIGN(TestSyncImpl); |
76 }; | 86 }; |
77 | 87 |
| 88 template <typename Interface> |
| 89 struct ImplTraits; |
| 90 |
| 91 template <> |
| 92 struct ImplTraits<TestSync> { |
| 93 using Type = TestSyncImpl; |
| 94 }; |
| 95 |
| 96 template <typename Interface> |
78 class TestSyncServiceThread { | 97 class TestSyncServiceThread { |
79 public: | 98 public: |
80 TestSyncServiceThread() | 99 TestSyncServiceThread() |
81 : thread_("TestSyncServiceThread"), ping_called_(false) { | 100 : thread_("TestSyncServiceThread"), ping_called_(false) { |
82 base::Thread::Options thread_options; | 101 base::Thread::Options thread_options; |
83 thread_options.message_pump_factory = | 102 thread_options.message_pump_factory = |
84 base::Bind(&common::MessagePumpMojo::Create); | 103 base::Bind(&common::MessagePumpMojo::Create); |
85 thread_.StartWithOptions(thread_options); | 104 thread_.StartWithOptions(thread_options); |
86 } | 105 } |
87 | 106 |
88 void SetUp(TestSyncRequest request) { | 107 void SetUp(InterfaceRequest<Interface> request) { |
89 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 108 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
90 impl_.reset(new TestSyncImpl(std::move(request))); | 109 impl_.reset(new typename ImplTraits<Interface>::Type(std::move(request))); |
91 impl_->set_ping_handler([this](const TestSync::PingCallback& callback) { | 110 impl_->set_ping_handler( |
92 { | 111 [this](const typename Interface::PingCallback& callback) { |
93 base::AutoLock locker(lock_); | 112 { |
94 ping_called_ = true; | 113 base::AutoLock locker(lock_); |
95 } | 114 ping_called_ = true; |
96 callback.Run(); | 115 } |
97 }); | 116 callback.Run(); |
| 117 }); |
98 } | 118 } |
99 | 119 |
100 void TearDown() { | 120 void TearDown() { |
101 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 121 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
102 impl_.reset(); | 122 impl_.reset(); |
103 } | 123 } |
104 | 124 |
105 base::Thread* thread() { return &thread_; } | 125 base::Thread* thread() { return &thread_; } |
106 bool ping_called() const { | 126 bool ping_called() const { |
107 base::AutoLock locker(lock_); | 127 base::AutoLock locker(lock_); |
108 return ping_called_; | 128 return ping_called_; |
109 } | 129 } |
110 | 130 |
111 private: | 131 private: |
112 base::Thread thread_; | 132 base::Thread thread_; |
113 | 133 |
114 scoped_ptr<TestSyncImpl> impl_; | 134 scoped_ptr<typename ImplTraits<Interface>::Type> impl_; |
115 | 135 |
116 mutable base::Lock lock_; | 136 mutable base::Lock lock_; |
117 bool ping_called_; | 137 bool ping_called_; |
118 | 138 |
119 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); | 139 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); |
120 }; | 140 }; |
121 | 141 |
122 TEST_F(SyncMethodTest, CallSyncMethodAsynchronously) { | 142 template <typename T> |
123 TestSyncPtr ptr; | 143 class SyncMethodCommonTest : public testing::Test { |
124 TestSyncImpl impl(GetProxy(&ptr)); | 144 public: |
| 145 SyncMethodCommonTest() : loop_(common::MessagePumpMojo::Create()) {} |
| 146 ~SyncMethodCommonTest() override { loop_.RunUntilIdle(); } |
| 147 |
| 148 private: |
| 149 base::MessageLoop loop_; |
| 150 }; |
| 151 |
| 152 using InterfaceTypes = testing::Types<TestSync>; |
| 153 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); |
| 154 |
| 155 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { |
| 156 InterfacePtr<TypeParam> ptr; |
| 157 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
125 | 158 |
126 base::RunLoop run_loop; | 159 base::RunLoop run_loop; |
127 ptr->Echo(123, [&run_loop](int32_t result) { | 160 ptr->Echo(123, [&run_loop](int32_t result) { |
128 EXPECT_EQ(123, result); | 161 EXPECT_EQ(123, result); |
129 run_loop.Quit(); | 162 run_loop.Quit(); |
130 }); | 163 }); |
131 run_loop.Run(); | 164 run_loop.Run(); |
132 } | 165 } |
133 | 166 |
134 TEST_F(SyncMethodTest, BasicSyncCalls) { | 167 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { |
135 TestSyncPtr ptr; | 168 InterfacePtr<TypeParam> ptr; |
136 | 169 |
137 TestSyncServiceThread service_thread; | 170 TestSyncServiceThread<TypeParam> service_thread; |
138 service_thread.thread()->task_runner()->PostTask( | 171 service_thread.thread()->task_runner()->PostTask( |
139 FROM_HERE, base::Bind(&TestSyncServiceThread::SetUp, | 172 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, |
140 base::Unretained(&service_thread), | 173 base::Unretained(&service_thread), |
141 base::Passed(GetProxy(&ptr)))); | 174 base::Passed(GetProxy(&ptr)))); |
142 ASSERT_TRUE(ptr->Ping()); | 175 ASSERT_TRUE(ptr->Ping()); |
143 ASSERT_TRUE(service_thread.ping_called()); | 176 ASSERT_TRUE(service_thread.ping_called()); |
144 | 177 |
145 int32_t output_value = -1; | 178 int32_t output_value = -1; |
146 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 179 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
147 ASSERT_EQ(42, output_value); | 180 ASSERT_EQ(42, output_value); |
148 | 181 |
149 base::RunLoop run_loop; | 182 base::RunLoop run_loop; |
150 service_thread.thread()->task_runner()->PostTaskAndReply( | 183 service_thread.thread()->task_runner()->PostTaskAndReply( |
151 FROM_HERE, base::Bind(&TestSyncServiceThread::TearDown, | 184 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::TearDown, |
152 base::Unretained(&service_thread)), | 185 base::Unretained(&service_thread)), |
153 run_loop.QuitClosure()); | 186 run_loop.QuitClosure()); |
154 run_loop.Run(); | 187 run_loop.Run(); |
155 } | 188 } |
156 | 189 |
157 TEST_F(SyncMethodTest, ReenteredBySyncMethodBinding) { | 190 TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { |
158 // Test that an interface pointer waiting for a sync call response can be | 191 // Test that an interface pointer waiting for a sync call response can be |
159 // reentered by a binding serving sync methods on the same thread. | 192 // reentered by a binding serving sync methods on the same thread. |
160 | 193 |
161 TestSyncPtr ptr; | 194 InterfacePtr<TypeParam> ptr; |
162 // The binding lives on the same thread as the interface pointer. | 195 // The binding lives on the same thread as the interface pointer. |
163 TestSyncImpl impl(GetProxy(&ptr)); | 196 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
164 int32_t output_value = -1; | 197 int32_t output_value = -1; |
165 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 198 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
166 EXPECT_EQ(42, output_value); | 199 EXPECT_EQ(42, output_value); |
167 } | 200 } |
168 | 201 |
169 TEST_F(SyncMethodTest, InterefacePtrDestroyedDuringSyncCall) { | 202 TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { |
170 // Test that it won't result in crash or hang if an interface pointer is | 203 // Test that it won't result in crash or hang if an interface pointer is |
171 // destroyed while it is waiting for a sync call response. | 204 // destroyed while it is waiting for a sync call response. |
172 | 205 |
173 TestSyncPtr ptr; | 206 InterfacePtr<TypeParam> ptr; |
174 TestSyncImpl impl(GetProxy(&ptr)); | 207 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
175 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { | 208 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { |
176 ptr.reset(); | 209 ptr.reset(); |
177 callback.Run(); | 210 callback.Run(); |
178 }); | 211 }); |
179 ASSERT_FALSE(ptr->Ping()); | 212 ASSERT_FALSE(ptr->Ping()); |
180 } | 213 } |
181 | 214 |
182 TEST_F(SyncMethodTest, BindingDestroyedDuringSyncCall) { | 215 TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { |
183 // Test that it won't result in crash or hang if a binding is | 216 // Test that it won't result in crash or hang if a binding is |
184 // closed (and therefore the message pipe handle is closed) while the | 217 // closed (and therefore the message pipe handle is closed) while the |
185 // corresponding interface pointer is waiting for a sync call response. | 218 // corresponding interface pointer is waiting for a sync call response. |
186 | 219 |
187 TestSyncPtr ptr; | 220 InterfacePtr<TypeParam> ptr; |
188 TestSyncImpl impl(GetProxy(&ptr)); | 221 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
189 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { | 222 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { |
190 impl.binding()->Close(); | 223 impl.binding()->Close(); |
191 callback.Run(); | 224 callback.Run(); |
192 }); | 225 }); |
193 ASSERT_FALSE(ptr->Ping()); | 226 ASSERT_FALSE(ptr->Ping()); |
194 } | 227 } |
195 | 228 |
196 TEST_F(SyncMethodTest, NestedSyncCallsWithInOrderResponses) { | 229 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { |
197 // Test that we can call a sync method on an interface ptr, while there is | 230 // Test that we can call a sync method on an interface ptr, while there is |
198 // already a sync call ongoing. The responses arrive in order. | 231 // already a sync call ongoing. The responses arrive in order. |
199 | 232 |
200 TestSyncPtr ptr; | 233 InterfacePtr<TypeParam> ptr; |
201 TestSyncImpl impl(GetProxy(&ptr)); | 234 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
202 | 235 |
203 // The same variable is used to store the output of the two sync calls, in | 236 // The same variable is used to store the output of the two sync calls, in |
204 // order to test that responses are handled in the correct order. | 237 // order to test that responses are handled in the correct order. |
205 int32_t result_value = -1; | 238 int32_t result_value = -1; |
206 | 239 |
207 bool first_call = true; | 240 bool first_call = true; |
208 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 241 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
209 int32_t value, const TestSync::EchoCallback& callback) { | 242 int32_t value, const TestSync::EchoCallback& callback) { |
210 if (first_call) { | 243 if (first_call) { |
211 first_call = false; | 244 first_call = false; |
212 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 245 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
213 EXPECT_EQ(456, result_value); | 246 EXPECT_EQ(456, result_value); |
214 } | 247 } |
215 callback.Run(value); | 248 callback.Run(value); |
216 }); | 249 }); |
217 | 250 |
218 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 251 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
219 EXPECT_EQ(123, result_value); | 252 EXPECT_EQ(123, result_value); |
220 } | 253 } |
221 | 254 |
222 TEST_F(SyncMethodTest, NestedSyncCallsWithOutOfOrderResponses) { | 255 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { |
223 // Test that we can call a sync method on an interface ptr, while there is | 256 // Test that we can call a sync method on an interface ptr, while there is |
224 // already a sync call ongoing. The responses arrive out of order. | 257 // already a sync call ongoing. The responses arrive out of order. |
225 | 258 |
226 TestSyncPtr ptr; | 259 InterfacePtr<TypeParam> ptr; |
227 TestSyncImpl impl(GetProxy(&ptr)); | 260 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
228 | 261 |
229 // The same variable is used to store the output of the two sync calls, in | 262 // The same variable is used to store the output of the two sync calls, in |
230 // order to test that responses are handled in the correct order. | 263 // order to test that responses are handled in the correct order. |
231 int32_t result_value = -1; | 264 int32_t result_value = -1; |
232 | 265 |
233 bool first_call = true; | 266 bool first_call = true; |
234 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 267 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
235 int32_t value, const TestSync::EchoCallback& callback) { | 268 int32_t value, const TestSync::EchoCallback& callback) { |
236 callback.Run(value); | 269 callback.Run(value); |
237 if (first_call) { | 270 if (first_call) { |
238 first_call = false; | 271 first_call = false; |
239 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 272 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
240 EXPECT_EQ(456, result_value); | 273 EXPECT_EQ(456, result_value); |
241 } | 274 } |
242 }); | 275 }); |
243 | 276 |
244 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 277 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
245 EXPECT_EQ(123, result_value); | 278 EXPECT_EQ(123, result_value); |
246 } | 279 } |
247 | 280 |
248 TEST_F(SyncMethodTest, AsyncResponseQueuedDuringSyncCall) { | 281 TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { |
249 // Test that while an interface pointer is waiting for the response to a sync | 282 // Test that while an interface pointer is waiting for the response to a sync |
250 // call, async responses are queued until the sync call completes. | 283 // call, async responses are queued until the sync call completes. |
251 | 284 |
252 TestSyncPtr ptr; | 285 InterfacePtr<TypeParam> ptr; |
253 TestSyncImpl impl(GetProxy(&ptr)); | 286 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
254 | 287 |
255 int32_t async_echo_request_value = -1; | 288 int32_t async_echo_request_value = -1; |
256 TestSync::AsyncEchoCallback async_echo_request_callback; | 289 TestSync::AsyncEchoCallback async_echo_request_callback; |
257 base::RunLoop run_loop1; | 290 base::RunLoop run_loop1; |
258 impl.set_async_echo_handler( | 291 impl.set_async_echo_handler( |
259 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 292 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
260 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 293 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
261 async_echo_request_value = value; | 294 async_echo_request_value = value; |
262 async_echo_request_callback = callback; | 295 async_echo_request_callback = callback; |
263 run_loop1.Quit(); | 296 run_loop1.Quit(); |
(...skipping 27 matching lines...) Expand all Loading... |
291 // Although the AsyncEcho response arrives before the Echo response, it should | 324 // Although the AsyncEcho response arrives before the Echo response, it should |
292 // be queued and not yet dispatched. | 325 // be queued and not yet dispatched. |
293 EXPECT_FALSE(async_echo_response_dispatched); | 326 EXPECT_FALSE(async_echo_response_dispatched); |
294 | 327 |
295 // Run until the AsyncEcho response is dispatched. | 328 // Run until the AsyncEcho response is dispatched. |
296 run_loop2.Run(); | 329 run_loop2.Run(); |
297 | 330 |
298 EXPECT_TRUE(async_echo_response_dispatched); | 331 EXPECT_TRUE(async_echo_response_dispatched); |
299 } | 332 } |
300 | 333 |
301 TEST_F(SyncMethodTest, AsyncRequestQueuedDuringSyncCall) { | 334 TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { |
302 // Test that while an interface pointer is waiting for the response to a sync | 335 // Test that while an interface pointer is waiting for the response to a sync |
303 // call, async requests for a binding running on the same thread are queued | 336 // call, async requests for a binding running on the same thread are queued |
304 // until the sync call completes. | 337 // until the sync call completes. |
305 | 338 |
306 TestSyncPtr ptr; | 339 InterfacePtr<TypeParam> ptr; |
307 TestSyncImpl impl(GetProxy(&ptr)); | 340 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
308 | 341 |
309 bool async_echo_request_dispatched = false; | 342 bool async_echo_request_dispatched = false; |
310 impl.set_async_echo_handler([&async_echo_request_dispatched]( | 343 impl.set_async_echo_handler([&async_echo_request_dispatched]( |
311 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 344 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
312 async_echo_request_dispatched = true; | 345 async_echo_request_dispatched = true; |
313 callback.Run(value); | 346 callback.Run(value); |
314 }); | 347 }); |
315 | 348 |
316 bool async_echo_response_dispatched = false; | 349 bool async_echo_response_dispatched = false; |
317 base::RunLoop run_loop; | 350 base::RunLoop run_loop; |
(...skipping 20 matching lines...) Expand all Loading... |
338 // Although the AsyncEcho request is sent before the Echo request, it | 371 // Although the AsyncEcho request is sent before the Echo request, it |
339 // shouldn't be dispatched yet. | 372 // shouldn't be dispatched yet. |
340 EXPECT_FALSE(async_echo_request_dispatched); | 373 EXPECT_FALSE(async_echo_request_dispatched); |
341 | 374 |
342 // Run until the AsyncEcho response is dispatched. | 375 // Run until the AsyncEcho response is dispatched. |
343 run_loop.Run(); | 376 run_loop.Run(); |
344 | 377 |
345 EXPECT_TRUE(async_echo_response_dispatched); | 378 EXPECT_TRUE(async_echo_response_dispatched); |
346 } | 379 } |
347 | 380 |
348 TEST_F(SyncMethodTest, QueuedMessagesProcessedBeforeErrorNotification) { | 381 TYPED_TEST(SyncMethodCommonTest, |
| 382 QueuedMessagesProcessedBeforeErrorNotification) { |
349 // Test that while an interface pointer is waiting for the response to a sync | 383 // Test that while an interface pointer is waiting for the response to a sync |
350 // call, async responses are queued. If the message pipe is disconnected | 384 // call, async responses are queued. If the message pipe is disconnected |
351 // before the queued messages are processed, the connection error | 385 // before the queued messages are processed, the connection error |
352 // notification is delayed until all the queued messages are processed. | 386 // notification is delayed until all the queued messages are processed. |
353 | 387 |
354 TestSyncPtr ptr; | 388 InterfacePtr<TypeParam> ptr; |
355 TestSyncImpl impl(GetProxy(&ptr)); | 389 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
356 | 390 |
357 int32_t async_echo_request_value = -1; | 391 int32_t async_echo_request_value = -1; |
358 TestSync::AsyncEchoCallback async_echo_request_callback; | 392 TestSync::AsyncEchoCallback async_echo_request_callback; |
359 base::RunLoop run_loop1; | 393 base::RunLoop run_loop1; |
360 impl.set_async_echo_handler( | 394 impl.set_async_echo_handler( |
361 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 395 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
362 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 396 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
363 async_echo_request_value = value; | 397 async_echo_request_value = value; |
364 async_echo_request_callback = callback; | 398 async_echo_request_callback = callback; |
365 run_loop1.Quit(); | 399 run_loop1.Quit(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 | 448 |
415 EXPECT_TRUE(async_echo_response_dispatched); | 449 EXPECT_TRUE(async_echo_response_dispatched); |
416 | 450 |
417 // Run until the error notification is dispatched. | 451 // Run until the error notification is dispatched. |
418 run_loop3.Run(); | 452 run_loop3.Run(); |
419 | 453 |
420 ASSERT_TRUE(connection_error_dispatched); | 454 ASSERT_TRUE(connection_error_dispatched); |
421 EXPECT_TRUE(ptr.encountered_error()); | 455 EXPECT_TRUE(ptr.encountered_error()); |
422 } | 456 } |
423 | 457 |
424 TEST_F(SyncMethodTest, InvalidMessageDuringSyncCall) { | 458 TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { |
425 // Test that while an interface pointer is waiting for the response to a sync | 459 // Test that while an interface pointer is waiting for the response to a sync |
426 // call, an invalid incoming message will disconnect the message pipe, cause | 460 // call, an invalid incoming message will disconnect the message pipe, cause |
427 // the sync call to return false, and run the connection error handler | 461 // the sync call to return false, and run the connection error handler |
428 // asynchronously. | 462 // asynchronously. |
429 | 463 |
430 MessagePipe pipe; | 464 MessagePipe pipe; |
431 | 465 |
432 TestSyncPtr ptr; | 466 InterfacePtr<TypeParam> ptr; |
433 ptr.Bind(TestSyncPtrInfo(std::move(pipe.handle0), 0u)); | 467 ptr.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u)); |
434 | 468 |
435 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); | 469 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); |
436 TestSyncImpl impl(MakeRequest<TestSync>(std::move(pipe.handle1))); | 470 typename ImplTraits<TypeParam>::Type impl( |
| 471 MakeRequest<TypeParam>(std::move(pipe.handle1))); |
437 | 472 |
438 impl.set_echo_handler([&raw_binding_handle]( | 473 impl.set_echo_handler([&raw_binding_handle]( |
439 int32_t value, const TestSync::EchoCallback& callback) { | 474 int32_t value, const TestSync::EchoCallback& callback) { |
440 // Write a 1-byte message, which is considered invalid. | 475 // Write a 1-byte message, which is considered invalid. |
441 char invalid_message = 0; | 476 char invalid_message = 0; |
442 MojoResult result = | 477 MojoResult result = |
443 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, | 478 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, |
444 MOJO_WRITE_MESSAGE_FLAG_NONE); | 479 MOJO_WRITE_MESSAGE_FLAG_NONE); |
445 ASSERT_EQ(MOJO_RESULT_OK, result); | 480 ASSERT_EQ(MOJO_RESULT_OK, result); |
446 callback.Run(value); | 481 callback.Run(value); |
(...skipping 11 matching lines...) Expand all Loading... |
458 EXPECT_EQ(-1, result_value); | 493 EXPECT_EQ(-1, result_value); |
459 ASSERT_FALSE(connection_error_dispatched); | 494 ASSERT_FALSE(connection_error_dispatched); |
460 | 495 |
461 run_loop.Run(); | 496 run_loop.Run(); |
462 ASSERT_TRUE(connection_error_dispatched); | 497 ASSERT_TRUE(connection_error_dispatched); |
463 } | 498 } |
464 | 499 |
465 } // namespace | 500 } // namespace |
466 } // namespace test | 501 } // namespace test |
467 } // namespace mojo | 502 } // namespace mojo |
OLD | NEW |