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> |
| 6 |
5 #include "base/bind.h" | 7 #include "base/bind.h" |
6 #include "base/logging.h" | 8 #include "base/logging.h" |
7 #include "base/macros.h" | 9 #include "base/macros.h" |
8 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
10 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
11 #include "mojo/public/cpp/bindings/associated_binding.h" | 13 #include "mojo/public/cpp/bindings/associated_binding.h" |
12 #include "mojo/public/cpp/bindings/binding.h" | 14 #include "mojo/public/cpp/bindings/binding.h" |
13 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" | 15 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
15 | 17 |
16 namespace mojo { | 18 namespace mojo { |
17 namespace test { | 19 namespace test { |
18 namespace { | 20 namespace { |
19 | 21 |
| 22 template <typename... Args> |
| 23 struct LambdaBinder { |
| 24 using CallbackType = base::Callback<void(Args...)>; |
| 25 |
| 26 template <typename Func> |
| 27 static void RunLambda(Func func, Args... args) { |
| 28 func(std::move(args)...); |
| 29 } |
| 30 |
| 31 template <typename Func> |
| 32 static CallbackType BindLambda(Func func) { |
| 33 return base::Bind(&LambdaBinder::RunLambda<Func>, func); |
| 34 } |
| 35 }; |
| 36 |
20 class TestSyncCommonImpl { | 37 class TestSyncCommonImpl { |
21 public: | 38 public: |
22 TestSyncCommonImpl() {} | 39 TestSyncCommonImpl() {} |
23 | 40 |
24 using PingHandler = Callback<void(const Callback<void()>&)>; | 41 using PingHandler = Callback<void(const Callback<void()>&)>; |
25 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; } | 42 using PingBinder = LambdaBinder<const Callback<void()>&>; |
| 43 template <typename Func> |
| 44 void set_ping_handler(Func handler) { |
| 45 ping_handler_ = PingBinder::BindLambda(handler); |
| 46 } |
26 | 47 |
27 using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>; | 48 using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>; |
28 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } | 49 using EchoBinder = LambdaBinder<int32_t, const Callback<void(int32_t)>&>; |
| 50 template <typename Func> |
| 51 void set_echo_handler(Func handler) { |
| 52 echo_handler_ = EchoBinder::BindLambda(handler); |
| 53 } |
29 | 54 |
30 using AsyncEchoHandler = | 55 using AsyncEchoHandler = |
31 Callback<void(int32_t, const Callback<void(int32_t)>&)>; | 56 Callback<void(int32_t, const Callback<void(int32_t)>&)>; |
32 void set_async_echo_handler(const AsyncEchoHandler& handler) { | 57 using AsyncEchoBinder = LambdaBinder<int32_t, const Callback<void(int32_t)>&>; |
33 async_echo_handler_ = handler; | 58 template <typename Func> |
| 59 void set_async_echo_handler(Func handler) { |
| 60 async_echo_handler_ = AsyncEchoBinder::BindLambda(handler); |
34 } | 61 } |
35 | 62 |
36 using SendInterfaceHandler = Callback<void(TestSyncAssociatedPtrInfo)>; | 63 using SendInterfaceHandler = Callback<void(TestSyncAssociatedPtrInfo)>; |
37 void set_send_interface_handler(const SendInterfaceHandler& handler) { | 64 using SendInterfaceBinder = LambdaBinder<TestSyncAssociatedPtrInfo>; |
38 send_interface_handler_ = handler; | 65 template <typename Func> |
| 66 void set_send_interface_handler(Func handler) { |
| 67 send_interface_handler_ = SendInterfaceBinder::BindLambda(handler); |
39 } | 68 } |
40 | 69 |
41 using SendRequestHandler = Callback<void(TestSyncAssociatedRequest)>; | 70 using SendRequestHandler = Callback<void(TestSyncAssociatedRequest)>; |
42 void set_send_request_handler(const SendRequestHandler& handler) { | 71 using SendRequestBinder = LambdaBinder<TestSyncAssociatedRequest>; |
43 send_request_handler_ = handler; | 72 template <typename Func> |
| 73 void set_send_request_handler(Func handler) { |
| 74 send_request_handler_ = SendRequestBinder::BindLambda(handler); |
44 } | 75 } |
45 | 76 |
46 void PingImpl(const Callback<void()>& callback) { | 77 void PingImpl(const Callback<void()>& callback) { |
47 if (ping_handler_.is_null()) { | 78 if (ping_handler_.is_null()) { |
48 callback.Run(); | 79 callback.Run(); |
49 return; | 80 return; |
50 } | 81 } |
51 ping_handler_.Run(callback); | 82 ping_handler_.Run(callback); |
52 } | 83 } |
53 void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { | 84 void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 302 |
272 // An associated interface whose binding lives at the |master_impl_| side. | 303 // An associated interface whose binding lives at the |master_impl_| side. |
273 TestSyncAssociatedPtrInfo asso_ptr_info_; | 304 TestSyncAssociatedPtrInfo asso_ptr_info_; |
274 TestSyncAssociatedRequest asso_request_; | 305 TestSyncAssociatedRequest asso_request_; |
275 | 306 |
276 // An associated interface whose binding lives at the |master_ptr_| side. | 307 // An associated interface whose binding lives at the |master_ptr_| side. |
277 TestSyncAssociatedPtrInfo opposite_asso_ptr_info_; | 308 TestSyncAssociatedPtrInfo opposite_asso_ptr_info_; |
278 TestSyncAssociatedRequest opposite_asso_request_; | 309 TestSyncAssociatedRequest opposite_asso_request_; |
279 }; | 310 }; |
280 | 311 |
| 312 void SetFlagAndRunClosure(bool* flag, const base::Closure& closure) { |
| 313 *flag = true; |
| 314 closure.Run(); |
| 315 } |
| 316 |
| 317 void ExpectValueAndRunClosure(int32_t expected_value, |
| 318 const base::Closure& closure, |
| 319 int32_t value) { |
| 320 EXPECT_EQ(expected_value, value); |
| 321 closure.Run(); |
| 322 } |
| 323 |
| 324 template <typename Func> |
| 325 void CallAsyncEchoCallback(Func func, int32_t value) { |
| 326 func(value); |
| 327 } |
| 328 |
| 329 template <typename Func> |
| 330 TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) { |
| 331 return base::Bind(&CallAsyncEchoCallback<Func>, func); |
| 332 } |
| 333 |
281 // TestSync and TestSyncMaster exercise Router and MultiplexRouter, | 334 // TestSync and TestSyncMaster exercise Router and MultiplexRouter, |
282 // respectively. | 335 // respectively. |
283 using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>; | 336 using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>; |
284 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); | 337 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); |
285 | 338 |
286 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { | 339 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { |
287 InterfacePtr<TypeParam> ptr; | 340 InterfacePtr<TypeParam> ptr; |
288 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); | 341 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
289 | 342 |
290 base::RunLoop run_loop; | 343 base::RunLoop run_loop; |
291 ptr->Echo(123, [&run_loop](int32_t result) { | 344 ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123, |
292 EXPECT_EQ(123, result); | 345 run_loop.QuitClosure())); |
293 run_loop.Quit(); | |
294 }); | |
295 run_loop.Run(); | 346 run_loop.Run(); |
296 } | 347 } |
297 | 348 |
298 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { | 349 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { |
299 InterfacePtr<TypeParam> ptr; | 350 InterfacePtr<TypeParam> ptr; |
300 | 351 |
301 TestSyncServiceThread<TypeParam> service_thread; | 352 TestSyncServiceThread<TypeParam> service_thread; |
302 service_thread.thread()->task_runner()->PostTask( | 353 service_thread.thread()->task_runner()->PostTask( |
303 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, | 354 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, |
304 base::Unretained(&service_thread), | 355 base::Unretained(&service_thread), |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 impl.set_async_echo_handler( | 473 impl.set_async_echo_handler( |
423 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 474 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
424 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 475 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
425 async_echo_request_value = value; | 476 async_echo_request_value = value; |
426 async_echo_request_callback = callback; | 477 async_echo_request_callback = callback; |
427 run_loop1.Quit(); | 478 run_loop1.Quit(); |
428 }); | 479 }); |
429 | 480 |
430 bool async_echo_response_dispatched = false; | 481 bool async_echo_response_dispatched = false; |
431 base::RunLoop run_loop2; | 482 base::RunLoop run_loop2; |
432 ptr->AsyncEcho(123, | 483 ptr->AsyncEcho( |
433 [&async_echo_response_dispatched, &run_loop2](int32_t result) { | 484 123, |
434 async_echo_response_dispatched = true; | 485 BindAsyncEchoCallback( |
435 EXPECT_EQ(123, result); | 486 [&async_echo_response_dispatched, &run_loop2](int32_t result) { |
436 run_loop2.Quit(); | 487 async_echo_response_dispatched = true; |
437 }); | 488 EXPECT_EQ(123, result); |
| 489 run_loop2.Quit(); |
| 490 })); |
438 // Run until the AsyncEcho request reaches the service side. | 491 // Run until the AsyncEcho request reaches the service side. |
439 run_loop1.Run(); | 492 run_loop1.Run(); |
440 | 493 |
441 impl.set_echo_handler( | 494 impl.set_echo_handler( |
442 [&async_echo_request_value, &async_echo_request_callback]( | 495 [&async_echo_request_value, &async_echo_request_callback]( |
443 int32_t value, const TestSync::EchoCallback& callback) { | 496 int32_t value, const TestSync::EchoCallback& callback) { |
444 // Send back the async response first. | 497 // Send back the async response first. |
445 EXPECT_FALSE(async_echo_request_callback.is_null()); | 498 EXPECT_FALSE(async_echo_request_callback.is_null()); |
446 async_echo_request_callback.Run(async_echo_request_value); | 499 async_echo_request_callback.Run(async_echo_request_value); |
447 | 500 |
(...skipping 24 matching lines...) Expand all Loading... |
472 | 525 |
473 bool async_echo_request_dispatched = false; | 526 bool async_echo_request_dispatched = false; |
474 impl.set_async_echo_handler([&async_echo_request_dispatched]( | 527 impl.set_async_echo_handler([&async_echo_request_dispatched]( |
475 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 528 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
476 async_echo_request_dispatched = true; | 529 async_echo_request_dispatched = true; |
477 callback.Run(value); | 530 callback.Run(value); |
478 }); | 531 }); |
479 | 532 |
480 bool async_echo_response_dispatched = false; | 533 bool async_echo_response_dispatched = false; |
481 base::RunLoop run_loop; | 534 base::RunLoop run_loop; |
482 ptr->AsyncEcho(123, | 535 ptr->AsyncEcho( |
483 [&async_echo_response_dispatched, &run_loop](int32_t result) { | 536 123, |
484 async_echo_response_dispatched = true; | 537 BindAsyncEchoCallback( |
485 EXPECT_EQ(123, result); | 538 [&async_echo_response_dispatched, &run_loop](int32_t result) { |
486 run_loop.Quit(); | 539 async_echo_response_dispatched = true; |
487 }); | 540 EXPECT_EQ(123, result); |
| 541 run_loop.Quit(); |
| 542 })); |
488 | 543 |
489 impl.set_echo_handler([&async_echo_request_dispatched]( | 544 impl.set_echo_handler([&async_echo_request_dispatched]( |
490 int32_t value, const TestSync::EchoCallback& callback) { | 545 int32_t value, const TestSync::EchoCallback& callback) { |
491 // Although the AsyncEcho request is sent before the Echo request, it | 546 // Although the AsyncEcho request is sent before the Echo request, it |
492 // shouldn't be dispatched yet at this point, because there is an ongoing | 547 // shouldn't be dispatched yet at this point, because there is an ongoing |
493 // sync call on the same thread. | 548 // sync call on the same thread. |
494 EXPECT_FALSE(async_echo_request_dispatched); | 549 EXPECT_FALSE(async_echo_request_dispatched); |
495 callback.Run(value); | 550 callback.Run(value); |
496 }); | 551 }); |
497 | 552 |
(...skipping 29 matching lines...) Expand all Loading... |
527 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 582 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
528 async_echo_request_value = value; | 583 async_echo_request_value = value; |
529 async_echo_request_callback = callback; | 584 async_echo_request_callback = callback; |
530 run_loop1.Quit(); | 585 run_loop1.Quit(); |
531 }); | 586 }); |
532 | 587 |
533 bool async_echo_response_dispatched = false; | 588 bool async_echo_response_dispatched = false; |
534 bool connection_error_dispatched = false; | 589 bool connection_error_dispatched = false; |
535 base::RunLoop run_loop2; | 590 base::RunLoop run_loop2; |
536 ptr->AsyncEcho( | 591 ptr->AsyncEcho( |
537 123, [&async_echo_response_dispatched, &connection_error_dispatched, &ptr, | 592 123, |
538 &run_loop2](int32_t result) { | 593 BindAsyncEchoCallback( |
539 async_echo_response_dispatched = true; | 594 [&async_echo_response_dispatched, &connection_error_dispatched, &ptr, |
540 // At this point, error notification should not be dispatched | 595 &run_loop2](int32_t result) { |
541 // yet. | 596 async_echo_response_dispatched = true; |
542 EXPECT_FALSE(connection_error_dispatched); | 597 // At this point, error notification should not be dispatched |
543 EXPECT_FALSE(ptr.encountered_error()); | 598 // yet. |
544 EXPECT_EQ(123, result); | 599 EXPECT_FALSE(connection_error_dispatched); |
545 run_loop2.Quit(); | 600 EXPECT_FALSE(ptr.encountered_error()); |
546 }); | 601 EXPECT_EQ(123, result); |
| 602 run_loop2.Quit(); |
| 603 })); |
547 // Run until the AsyncEcho request reaches the service side. | 604 // Run until the AsyncEcho request reaches the service side. |
548 run_loop1.Run(); | 605 run_loop1.Run(); |
549 | 606 |
550 impl.set_echo_handler( | 607 impl.set_echo_handler( |
551 [&impl, &async_echo_request_value, &async_echo_request_callback]( | 608 [&impl, &async_echo_request_value, &async_echo_request_callback]( |
552 int32_t value, const TestSync::EchoCallback& callback) { | 609 int32_t value, const TestSync::EchoCallback& callback) { |
553 // Send back the async response first. | 610 // Send back the async response first. |
554 EXPECT_FALSE(async_echo_request_callback.is_null()); | 611 EXPECT_FALSE(async_echo_request_callback.is_null()); |
555 async_echo_request_callback.Run(async_echo_request_value); | 612 async_echo_request_callback.Run(async_echo_request_value); |
556 | 613 |
557 impl.binding()->Close(); | 614 impl.binding()->Close(); |
558 }); | 615 }); |
559 | 616 |
560 base::RunLoop run_loop3; | 617 base::RunLoop run_loop3; |
561 ptr.set_connection_error_handler( | 618 ptr.set_connection_error_handler( |
562 [&connection_error_dispatched, &run_loop3]() { | 619 base::Bind(&SetFlagAndRunClosure, &connection_error_dispatched, |
563 connection_error_dispatched = true; | 620 run_loop3.QuitClosure())); |
564 run_loop3.Quit(); | |
565 }); | |
566 | 621 |
567 int32_t result_value = -1; | 622 int32_t result_value = -1; |
568 ASSERT_FALSE(ptr->Echo(456, &result_value)); | 623 ASSERT_FALSE(ptr->Echo(456, &result_value)); |
569 EXPECT_EQ(-1, result_value); | 624 EXPECT_EQ(-1, result_value); |
570 ASSERT_FALSE(connection_error_dispatched); | 625 ASSERT_FALSE(connection_error_dispatched); |
571 EXPECT_FALSE(ptr.encountered_error()); | 626 EXPECT_FALSE(ptr.encountered_error()); |
572 | 627 |
573 // Although the AsyncEcho response arrives before the Echo response, it should | 628 // Although the AsyncEcho response arrives before the Echo response, it should |
574 // be queued and not yet dispatched. | 629 // be queued and not yet dispatched. |
575 EXPECT_FALSE(async_echo_response_dispatched); | 630 EXPECT_FALSE(async_echo_response_dispatched); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 char invalid_message = 0; | 662 char invalid_message = 0; |
608 MojoResult result = | 663 MojoResult result = |
609 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, | 664 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, |
610 MOJO_WRITE_MESSAGE_FLAG_NONE); | 665 MOJO_WRITE_MESSAGE_FLAG_NONE); |
611 ASSERT_EQ(MOJO_RESULT_OK, result); | 666 ASSERT_EQ(MOJO_RESULT_OK, result); |
612 callback.Run(value); | 667 callback.Run(value); |
613 }); | 668 }); |
614 | 669 |
615 bool connection_error_dispatched = false; | 670 bool connection_error_dispatched = false; |
616 base::RunLoop run_loop; | 671 base::RunLoop run_loop; |
617 ptr.set_connection_error_handler([&connection_error_dispatched, &run_loop]() { | 672 ptr.set_connection_error_handler( |
618 connection_error_dispatched = true; | 673 base::Bind(&SetFlagAndRunClosure, &connection_error_dispatched, |
619 run_loop.Quit(); | 674 run_loop.QuitClosure())); |
620 }); | |
621 | 675 |
622 int32_t result_value = -1; | 676 int32_t result_value = -1; |
623 ASSERT_FALSE(ptr->Echo(456, &result_value)); | 677 ASSERT_FALSE(ptr->Echo(456, &result_value)); |
624 EXPECT_EQ(-1, result_value); | 678 EXPECT_EQ(-1, result_value); |
625 ASSERT_FALSE(connection_error_dispatched); | 679 ASSERT_FALSE(connection_error_dispatched); |
626 | 680 |
627 run_loop.Run(); | 681 run_loop.Run(); |
628 ASSERT_TRUE(connection_error_dispatched); | 682 ASSERT_TRUE(connection_error_dispatched); |
629 } | 683 } |
630 | 684 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 int32_t result_value = -1; | 729 int32_t result_value = -1; |
676 ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); | 730 ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); |
677 EXPECT_EQ(456, result_value); | 731 EXPECT_EQ(456, result_value); |
678 } | 732 } |
679 | 733 |
680 // TODO(yzshen): Add more tests related to associated interfaces. | 734 // TODO(yzshen): Add more tests related to associated interfaces. |
681 | 735 |
682 } // namespace | 736 } // namespace |
683 } // namespace test | 737 } // namespace test |
684 } // namespace mojo | 738 } // namespace mojo |
OLD | NEW |