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 <utility> | 5 #include <utility> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 struct ImplTraits<TestSync> { | 195 struct ImplTraits<TestSync> { |
196 using Type = TestSyncImpl; | 196 using Type = TestSyncImpl; |
197 }; | 197 }; |
198 | 198 |
199 template <> | 199 template <> |
200 struct ImplTraits<TestSyncMaster> { | 200 struct ImplTraits<TestSyncMaster> { |
201 using Type = TestSyncMasterImpl; | 201 using Type = TestSyncMasterImpl; |
202 }; | 202 }; |
203 | 203 |
204 template <typename Interface> | 204 template <typename Interface> |
| 205 using ImplTypeFor = typename ImplTraits<Interface>::Type; |
| 206 |
| 207 // A wrapper for either an InterfacePtr or scoped_refptr<ThreadSafeInterfacePtr> |
| 208 // that exposes the InterfacePtr interface. |
| 209 template <typename Interface> |
| 210 class PtrWrapper { |
| 211 public: |
| 212 explicit PtrWrapper(InterfacePtr<Interface> ptr) : ptr_(std::move(ptr)) {} |
| 213 |
| 214 explicit PtrWrapper( |
| 215 scoped_refptr<ThreadSafeInterfacePtr<Interface>> thread_safe_ptr) |
| 216 : thread_safe_ptr_(thread_safe_ptr) {} |
| 217 |
| 218 PtrWrapper(PtrWrapper&& other) = default; |
| 219 |
| 220 Interface* operator->() { |
| 221 return thread_safe_ptr_ ? thread_safe_ptr_->get() : ptr_.get(); |
| 222 } |
| 223 |
| 224 void set_connection_error_handler(const base::Closure& error_handler) { |
| 225 DCHECK(!thread_safe_ptr_); |
| 226 ptr_.set_connection_error_handler(error_handler); |
| 227 } |
| 228 |
| 229 void reset() { |
| 230 ptr_ = nullptr; |
| 231 thread_safe_ptr_ = nullptr; |
| 232 } |
| 233 |
| 234 private: |
| 235 InterfacePtr<Interface> ptr_; |
| 236 scoped_refptr<ThreadSafeInterfacePtr<Interface>> thread_safe_ptr_; |
| 237 |
| 238 DISALLOW_COPY_AND_ASSIGN(PtrWrapper); |
| 239 }; |
| 240 |
| 241 // The type parameter for SyncMethodCommonTests for varying the Interface and |
| 242 // whether to use InterfacePtr or ThreadSafeInterfacePtr. |
| 243 template <typename InterfaceT, bool use_thread_safe_ptr> |
| 244 struct TestParams { |
| 245 using Interface = InterfaceT; |
| 246 static const bool kIsThreadSafeInterfacePtrTest = use_thread_safe_ptr; |
| 247 |
| 248 static PtrWrapper<InterfaceT> Wrap(InterfacePtr<Interface> ptr) { |
| 249 if (kIsThreadSafeInterfacePtrTest) { |
| 250 return PtrWrapper<Interface>( |
| 251 ThreadSafeInterfacePtr<Interface>::Create(std::move(ptr))); |
| 252 } else { |
| 253 return PtrWrapper<Interface>(std::move(ptr)); |
| 254 } |
| 255 } |
| 256 }; |
| 257 |
| 258 template <typename Interface> |
205 class TestSyncServiceThread { | 259 class TestSyncServiceThread { |
206 public: | 260 public: |
207 TestSyncServiceThread() | 261 TestSyncServiceThread() |
208 : thread_("TestSyncServiceThread"), ping_called_(false) { | 262 : thread_("TestSyncServiceThread"), ping_called_(false) { |
209 thread_.Start(); | 263 thread_.Start(); |
210 } | 264 } |
211 | 265 |
212 void SetUp(InterfaceRequest<Interface> request) { | 266 void SetUp(InterfaceRequest<Interface> request) { |
213 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 267 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
214 impl_.reset(new typename ImplTraits<Interface>::Type(std::move(request))); | 268 impl_.reset(new ImplTypeFor<Interface>(std::move(request))); |
215 impl_->set_ping_handler( | 269 impl_->set_ping_handler( |
216 [this](const typename Interface::PingCallback& callback) { | 270 [this](const typename Interface::PingCallback& callback) { |
217 { | 271 { |
218 base::AutoLock locker(lock_); | 272 base::AutoLock locker(lock_); |
219 ping_called_ = true; | 273 ping_called_ = true; |
220 } | 274 } |
221 callback.Run(); | 275 callback.Run(); |
222 }); | 276 }); |
223 } | 277 } |
224 | 278 |
225 void TearDown() { | 279 void TearDown() { |
226 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 280 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
227 impl_.reset(); | 281 impl_.reset(); |
228 } | 282 } |
229 | 283 |
230 base::Thread* thread() { return &thread_; } | 284 base::Thread* thread() { return &thread_; } |
231 bool ping_called() const { | 285 bool ping_called() const { |
232 base::AutoLock locker(lock_); | 286 base::AutoLock locker(lock_); |
233 return ping_called_; | 287 return ping_called_; |
234 } | 288 } |
235 | 289 |
236 private: | 290 private: |
237 base::Thread thread_; | 291 base::Thread thread_; |
238 | 292 |
239 std::unique_ptr<typename ImplTraits<Interface>::Type> impl_; | 293 std::unique_ptr<ImplTypeFor<Interface>> impl_; |
240 | 294 |
241 mutable base::Lock lock_; | 295 mutable base::Lock lock_; |
242 bool ping_called_; | 296 bool ping_called_; |
243 | 297 |
244 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); | 298 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); |
245 }; | 299 }; |
246 | 300 |
247 class SyncMethodTest : public testing::Test { | 301 class SyncMethodTest : public testing::Test { |
248 public: | 302 public: |
249 SyncMethodTest() {} | 303 SyncMethodTest() {} |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 func(value); | 381 func(value); |
328 } | 382 } |
329 | 383 |
330 template <typename Func> | 384 template <typename Func> |
331 TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) { | 385 TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) { |
332 return base::Bind(&CallAsyncEchoCallback<Func>, func); | 386 return base::Bind(&CallAsyncEchoCallback<Func>, func); |
333 } | 387 } |
334 | 388 |
335 // TestSync (without associated interfaces) and TestSyncMaster (with associated | 389 // TestSync (without associated interfaces) and TestSyncMaster (with associated |
336 // interfaces) exercise MultiplexRouter with different configurations. | 390 // interfaces) exercise MultiplexRouter with different configurations. |
337 using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>; | 391 // Each test is run once with an InterfacePtr and once with a |
| 392 // ThreadSafeInterfacePtr to ensure that they behave the same with respect to |
| 393 // sync calls. |
| 394 using InterfaceTypes = testing::Types<TestParams<TestSync, true>, |
| 395 TestParams<TestSync, false>, |
| 396 TestParams<TestSyncMaster, true>, |
| 397 TestParams<TestSyncMaster, false>>; |
338 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); | 398 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); |
339 | 399 |
340 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { | 400 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { |
341 InterfacePtr<TypeParam> ptr; | 401 using Interface = typename TypeParam::Interface; |
342 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 402 InterfacePtr<Interface> interface_ptr; |
| 403 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 404 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
343 | 405 |
344 base::RunLoop run_loop; | 406 base::RunLoop run_loop; |
345 ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123, | 407 ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123, |
346 run_loop.QuitClosure())); | 408 run_loop.QuitClosure())); |
347 run_loop.Run(); | 409 run_loop.Run(); |
348 } | 410 } |
349 | 411 |
350 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { | 412 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { |
351 InterfacePtr<TypeParam> ptr; | 413 using Interface = typename TypeParam::Interface; |
| 414 InterfacePtr<Interface> interface_ptr; |
| 415 InterfaceRequest<Interface> request = MakeRequest(&interface_ptr); |
| 416 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
352 | 417 |
353 TestSyncServiceThread<TypeParam> service_thread; | 418 TestSyncServiceThread<Interface> service_thread; |
354 service_thread.thread()->task_runner()->PostTask( | 419 service_thread.thread()->task_runner()->PostTask( |
355 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, | 420 FROM_HERE, |
356 base::Unretained(&service_thread), | 421 base::Bind(&TestSyncServiceThread<Interface>::SetUp, |
357 base::Passed(MakeRequest(&ptr)))); | 422 base::Unretained(&service_thread), base::Passed(&request))); |
358 ASSERT_TRUE(ptr->Ping()); | 423 ASSERT_TRUE(ptr->Ping()); |
359 ASSERT_TRUE(service_thread.ping_called()); | 424 ASSERT_TRUE(service_thread.ping_called()); |
360 | 425 |
361 int32_t output_value = -1; | 426 int32_t output_value = -1; |
362 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 427 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
363 ASSERT_EQ(42, output_value); | 428 ASSERT_EQ(42, output_value); |
364 | 429 |
365 base::RunLoop run_loop; | 430 base::RunLoop run_loop; |
366 service_thread.thread()->task_runner()->PostTaskAndReply( | 431 service_thread.thread()->task_runner()->PostTaskAndReply( |
367 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::TearDown, | 432 FROM_HERE, |
368 base::Unretained(&service_thread)), | 433 base::Bind(&TestSyncServiceThread<Interface>::TearDown, |
| 434 base::Unretained(&service_thread)), |
369 run_loop.QuitClosure()); | 435 run_loop.QuitClosure()); |
370 run_loop.Run(); | 436 run_loop.Run(); |
371 } | 437 } |
372 | 438 |
373 TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { | 439 TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { |
374 // Test that an interface pointer waiting for a sync call response can be | 440 // Test that an interface pointer waiting for a sync call response can be |
375 // reentered by a binding serving sync methods on the same thread. | 441 // reentered by a binding serving sync methods on the same thread. |
376 | 442 |
377 InterfacePtr<TypeParam> ptr; | 443 using Interface = typename TypeParam::Interface; |
| 444 InterfacePtr<Interface> interface_ptr; |
378 // The binding lives on the same thread as the interface pointer. | 445 // The binding lives on the same thread as the interface pointer. |
379 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 446 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 447 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
380 int32_t output_value = -1; | 448 int32_t output_value = -1; |
381 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 449 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
382 EXPECT_EQ(42, output_value); | 450 EXPECT_EQ(42, output_value); |
383 } | 451 } |
384 | 452 |
385 TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { | 453 TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { |
386 // Test that it won't result in crash or hang if an interface pointer is | 454 // Test that it won't result in crash or hang if an interface pointer is |
387 // destroyed while it is waiting for a sync call response. | 455 // destroyed while it is waiting for a sync call response. |
388 | 456 |
389 InterfacePtr<TypeParam> ptr; | 457 using Interface = typename TypeParam::Interface; |
390 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 458 InterfacePtr<Interface> interface_ptr; |
| 459 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 460 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
391 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { | 461 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { |
392 ptr.reset(); | 462 ptr.reset(); |
393 callback.Run(); | 463 callback.Run(); |
394 }); | 464 }); |
395 ASSERT_FALSE(ptr->Ping()); | 465 ASSERT_FALSE(ptr->Ping()); |
396 } | 466 } |
397 | 467 |
398 TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { | 468 TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { |
399 // Test that it won't result in crash or hang if a binding is | 469 // Test that it won't result in crash or hang if a binding is |
400 // closed (and therefore the message pipe handle is closed) while the | 470 // closed (and therefore the message pipe handle is closed) while the |
401 // corresponding interface pointer is waiting for a sync call response. | 471 // corresponding interface pointer is waiting for a sync call response. |
402 | 472 |
403 InterfacePtr<TypeParam> ptr; | 473 using Interface = typename TypeParam::Interface; |
404 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 474 InterfacePtr<Interface> interface_ptr; |
| 475 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 476 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
405 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { | 477 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { |
406 impl.binding()->Close(); | 478 impl.binding()->Close(); |
407 callback.Run(); | 479 callback.Run(); |
408 }); | 480 }); |
409 ASSERT_FALSE(ptr->Ping()); | 481 ASSERT_FALSE(ptr->Ping()); |
410 } | 482 } |
411 | 483 |
412 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { | 484 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { |
413 // Test that we can call a sync method on an interface ptr, while there is | 485 // Test that we can call a sync method on an interface ptr, while there is |
414 // already a sync call ongoing. The responses arrive in order. | 486 // already a sync call ongoing. The responses arrive in order. |
415 | 487 |
416 InterfacePtr<TypeParam> ptr; | 488 using Interface = typename TypeParam::Interface; |
417 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 489 InterfacePtr<Interface> interface_ptr; |
| 490 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 491 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
418 | 492 |
419 // The same variable is used to store the output of the two sync calls, in | 493 // The same variable is used to store the output of the two sync calls, in |
420 // order to test that responses are handled in the correct order. | 494 // order to test that responses are handled in the correct order. |
421 int32_t result_value = -1; | 495 int32_t result_value = -1; |
422 | 496 |
423 bool first_call = true; | 497 bool first_call = true; |
424 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 498 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
425 int32_t value, const TestSync::EchoCallback& callback) { | 499 int32_t value, const TestSync::EchoCallback& callback) { |
426 if (first_call) { | 500 if (first_call) { |
427 first_call = false; | 501 first_call = false; |
428 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 502 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
429 EXPECT_EQ(456, result_value); | 503 EXPECT_EQ(456, result_value); |
430 } | 504 } |
431 callback.Run(value); | 505 callback.Run(value); |
432 }); | 506 }); |
433 | 507 |
434 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 508 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
435 EXPECT_EQ(123, result_value); | 509 EXPECT_EQ(123, result_value); |
436 } | 510 } |
437 | 511 |
438 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { | 512 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { |
439 // Test that we can call a sync method on an interface ptr, while there is | 513 // Test that we can call a sync method on an interface ptr, while there is |
440 // already a sync call ongoing. The responses arrive out of order. | 514 // already a sync call ongoing. The responses arrive out of order. |
441 | 515 |
442 InterfacePtr<TypeParam> ptr; | 516 using Interface = typename TypeParam::Interface; |
443 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 517 InterfacePtr<Interface> interface_ptr; |
| 518 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 519 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
444 | 520 |
445 // The same variable is used to store the output of the two sync calls, in | 521 // The same variable is used to store the output of the two sync calls, in |
446 // order to test that responses are handled in the correct order. | 522 // order to test that responses are handled in the correct order. |
447 int32_t result_value = -1; | 523 int32_t result_value = -1; |
448 | 524 |
449 bool first_call = true; | 525 bool first_call = true; |
450 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 526 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
451 int32_t value, const TestSync::EchoCallback& callback) { | 527 int32_t value, const TestSync::EchoCallback& callback) { |
452 callback.Run(value); | 528 callback.Run(value); |
453 if (first_call) { | 529 if (first_call) { |
454 first_call = false; | 530 first_call = false; |
455 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 531 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
456 EXPECT_EQ(456, result_value); | 532 EXPECT_EQ(456, result_value); |
457 } | 533 } |
458 }); | 534 }); |
459 | 535 |
460 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 536 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
461 EXPECT_EQ(123, result_value); | 537 EXPECT_EQ(123, result_value); |
462 } | 538 } |
463 | 539 |
464 TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { | 540 TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { |
465 // Test that while an interface pointer is waiting for the response to a sync | 541 // Test that while an interface pointer is waiting for the response to a sync |
466 // call, async responses are queued until the sync call completes. | 542 // call, async responses are queued until the sync call completes. |
467 | 543 |
468 InterfacePtr<TypeParam> ptr; | 544 using Interface = typename TypeParam::Interface; |
469 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 545 InterfacePtr<Interface> interface_ptr; |
| 546 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 547 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
470 | 548 |
471 int32_t async_echo_request_value = -1; | 549 int32_t async_echo_request_value = -1; |
472 TestSync::AsyncEchoCallback async_echo_request_callback; | 550 TestSync::AsyncEchoCallback async_echo_request_callback; |
473 base::RunLoop run_loop1; | 551 base::RunLoop run_loop1; |
474 impl.set_async_echo_handler( | 552 impl.set_async_echo_handler( |
475 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 553 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
476 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 554 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
477 async_echo_request_value = value; | 555 async_echo_request_value = value; |
478 async_echo_request_callback = callback; | 556 async_echo_request_callback = callback; |
479 run_loop1.Quit(); | 557 run_loop1.Quit(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 run_loop2.Run(); | 592 run_loop2.Run(); |
515 | 593 |
516 EXPECT_TRUE(async_echo_response_dispatched); | 594 EXPECT_TRUE(async_echo_response_dispatched); |
517 } | 595 } |
518 | 596 |
519 TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { | 597 TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { |
520 // Test that while an interface pointer is waiting for the response to a sync | 598 // Test that while an interface pointer is waiting for the response to a sync |
521 // call, async requests for a binding running on the same thread are queued | 599 // call, async requests for a binding running on the same thread are queued |
522 // until the sync call completes. | 600 // until the sync call completes. |
523 | 601 |
524 InterfacePtr<TypeParam> ptr; | 602 using Interface = typename TypeParam::Interface; |
525 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 603 InterfacePtr<Interface> interface_ptr; |
| 604 ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); |
| 605 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
526 | 606 |
527 bool async_echo_request_dispatched = false; | 607 bool async_echo_request_dispatched = false; |
528 impl.set_async_echo_handler([&async_echo_request_dispatched]( | 608 impl.set_async_echo_handler([&async_echo_request_dispatched]( |
529 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 609 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
530 async_echo_request_dispatched = true; | 610 async_echo_request_dispatched = true; |
531 callback.Run(value); | 611 callback.Run(value); |
532 }); | 612 }); |
533 | 613 |
534 bool async_echo_response_dispatched = false; | 614 bool async_echo_response_dispatched = false; |
535 base::RunLoop run_loop; | 615 base::RunLoop run_loop; |
(...skipping 29 matching lines...) Expand all Loading... |
565 EXPECT_TRUE(async_echo_response_dispatched); | 645 EXPECT_TRUE(async_echo_response_dispatched); |
566 } | 646 } |
567 | 647 |
568 TYPED_TEST(SyncMethodCommonTest, | 648 TYPED_TEST(SyncMethodCommonTest, |
569 QueuedMessagesProcessedBeforeErrorNotification) { | 649 QueuedMessagesProcessedBeforeErrorNotification) { |
570 // Test that while an interface pointer is waiting for the response to a sync | 650 // Test that while an interface pointer is waiting for the response to a sync |
571 // call, async responses are queued. If the message pipe is disconnected | 651 // call, async responses are queued. If the message pipe is disconnected |
572 // before the queued messages are processed, the connection error | 652 // before the queued messages are processed, the connection error |
573 // notification is delayed until all the queued messages are processed. | 653 // notification is delayed until all the queued messages are processed. |
574 | 654 |
575 InterfacePtr<TypeParam> ptr; | 655 // ThreadSafeInterfacePtr doesn't guarantee that messages are delivered before |
576 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 656 // error notifications, so skip it for this test. |
| 657 if (TypeParam::kIsThreadSafeInterfacePtrTest) |
| 658 return; |
| 659 |
| 660 using Interface = typename TypeParam::Interface; |
| 661 InterfacePtr<Interface> ptr; |
| 662 ImplTypeFor<Interface> impl(MakeRequest(&ptr)); |
577 | 663 |
578 int32_t async_echo_request_value = -1; | 664 int32_t async_echo_request_value = -1; |
579 TestSync::AsyncEchoCallback async_echo_request_callback; | 665 TestSync::AsyncEchoCallback async_echo_request_callback; |
580 base::RunLoop run_loop1; | 666 base::RunLoop run_loop1; |
581 impl.set_async_echo_handler( | 667 impl.set_async_echo_handler( |
582 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 668 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
583 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 669 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
584 async_echo_request_value = value; | 670 async_echo_request_value = value; |
585 async_echo_request_callback = callback; | 671 async_echo_request_callback = callback; |
586 run_loop1.Quit(); | 672 run_loop1.Quit(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 ASSERT_TRUE(connection_error_dispatched); | 727 ASSERT_TRUE(connection_error_dispatched); |
642 EXPECT_TRUE(ptr.encountered_error()); | 728 EXPECT_TRUE(ptr.encountered_error()); |
643 } | 729 } |
644 | 730 |
645 TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { | 731 TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { |
646 // Test that while an interface pointer is waiting for the response to a sync | 732 // Test that while an interface pointer is waiting for the response to a sync |
647 // call, an invalid incoming message will disconnect the message pipe, cause | 733 // call, an invalid incoming message will disconnect the message pipe, cause |
648 // the sync call to return false, and run the connection error handler | 734 // the sync call to return false, and run the connection error handler |
649 // asynchronously. | 735 // asynchronously. |
650 | 736 |
| 737 using Interface = typename TypeParam::Interface; |
651 MessagePipe pipe; | 738 MessagePipe pipe; |
652 | 739 |
653 InterfacePtr<TypeParam> ptr; | 740 InterfacePtr<Interface> interface_ptr; |
654 ptr.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u)); | 741 interface_ptr.Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u)); |
| 742 auto ptr = TypeParam::Wrap(std::move(interface_ptr)); |
655 | 743 |
656 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); | 744 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); |
657 typename ImplTraits<TypeParam>::Type impl( | 745 ImplTypeFor<Interface> impl(MakeRequest<Interface>(std::move(pipe.handle1))); |
658 MakeRequest<TypeParam>(std::move(pipe.handle1))); | |
659 | 746 |
660 impl.set_echo_handler([&raw_binding_handle]( | 747 impl.set_echo_handler([&raw_binding_handle]( |
661 int32_t value, const TestSync::EchoCallback& callback) { | 748 int32_t value, const TestSync::EchoCallback& callback) { |
662 // Write a 1-byte message, which is considered invalid. | 749 // Write a 1-byte message, which is considered invalid. |
663 char invalid_message = 0; | 750 char invalid_message = 0; |
664 MojoResult result = | 751 MojoResult result = |
665 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, | 752 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, |
666 MOJO_WRITE_MESSAGE_FLAG_NONE); | 753 MOJO_WRITE_MESSAGE_FLAG_NONE); |
667 ASSERT_EQ(MOJO_RESULT_OK, result); | 754 ASSERT_EQ(MOJO_RESULT_OK, result); |
668 callback.Run(value); | 755 callback.Run(value); |
669 }); | 756 }); |
670 | 757 |
671 bool connection_error_dispatched = false; | 758 bool connection_error_dispatched = false; |
672 base::RunLoop run_loop; | 759 base::RunLoop run_loop; |
673 ptr.set_connection_error_handler( | 760 // ThreadSafeInterfacePtr doesn't support setting connection error handlers. |
674 base::Bind(&SetFlagAndRunClosure, &connection_error_dispatched, | 761 if (!TypeParam::kIsThreadSafeInterfacePtrTest) { |
675 run_loop.QuitClosure())); | 762 ptr.set_connection_error_handler(base::Bind(&SetFlagAndRunClosure, |
| 763 &connection_error_dispatched, |
| 764 run_loop.QuitClosure())); |
| 765 } |
676 | 766 |
677 int32_t result_value = -1; | 767 int32_t result_value = -1; |
678 ASSERT_FALSE(ptr->Echo(456, &result_value)); | 768 ASSERT_FALSE(ptr->Echo(456, &result_value)); |
679 EXPECT_EQ(-1, result_value); | 769 EXPECT_EQ(-1, result_value); |
680 ASSERT_FALSE(connection_error_dispatched); | 770 ASSERT_FALSE(connection_error_dispatched); |
681 | 771 |
682 run_loop.Run(); | 772 if (!TypeParam::kIsThreadSafeInterfacePtrTest) { |
683 ASSERT_TRUE(connection_error_dispatched); | 773 run_loop.Run(); |
| 774 ASSERT_TRUE(connection_error_dispatched); |
| 775 } |
684 } | 776 } |
685 | 777 |
686 TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) { | 778 TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) { |
687 // Test that an interface pointer waiting for a sync call response can be | 779 // Test that an interface pointer waiting for a sync call response can be |
688 // reentered by an associated binding serving sync methods on the same thread. | 780 // reentered by an associated binding serving sync methods on the same thread. |
689 // The associated binding belongs to the same MultiplexRouter as the waiting | 781 // The associated binding belongs to the same MultiplexRouter as the waiting |
690 // interface pointer. | 782 // interface pointer. |
691 | 783 |
692 TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_)); | 784 TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_)); |
693 TestSyncAssociatedPtr opposite_asso_ptr; | 785 TestSyncAssociatedPtr opposite_asso_ptr; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 int32_t result_value = -1; | 822 int32_t result_value = -1; |
731 ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); | 823 ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); |
732 EXPECT_EQ(456, result_value); | 824 EXPECT_EQ(456, result_value); |
733 } | 825 } |
734 | 826 |
735 // TODO(yzshen): Add more tests related to associated interfaces. | 827 // TODO(yzshen): Add more tests related to associated interfaces. |
736 | 828 |
737 } // namespace | 829 } // namespace |
738 } // namespace test | 830 } // namespace test |
739 } // namespace mojo | 831 } // namespace mojo |
OLD | NEW |