Chromium Code Reviews| 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 { | |
|
yzshen1
2016/06/18 00:01:18
optional: Can this be shared with other tests? I l
Ken Rockot(use gerrit already)
2016/06/18 03:24:26
I would like to think so but decided against it fo
| |
| 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 |