| 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" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/sequence_token.h" |
| 13 #include "base/test/sequenced_worker_pool_owner.h" |
| 14 #include "base/threading/sequenced_worker_pool.h" |
| 12 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 13 #include "mojo/public/cpp/bindings/associated_binding.h" | 16 #include "mojo/public/cpp/bindings/associated_binding.h" |
| 14 #include "mojo/public/cpp/bindings/binding.h" | 17 #include "mojo/public/cpp/bindings/binding.h" |
| 18 #include "mojo/public/cpp/bindings/tests/thread_per_task_sequenced_task_runner.h
" |
| 15 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" | 19 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 21 |
| 18 namespace mojo { | 22 namespace mojo { |
| 19 namespace test { | 23 namespace test { |
| 20 namespace { | 24 namespace { |
| 21 | 25 |
| 22 template <typename... Args> | 26 template <typename... Args> |
| 23 struct LambdaBinder { | 27 struct LambdaBinder { |
| 24 using CallbackType = base::Callback<void(Args...)>; | 28 using CallbackType = base::Callback<void(Args...)>; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 } | 224 } |
| 221 callback.Run(); | 225 callback.Run(); |
| 222 }); | 226 }); |
| 223 } | 227 } |
| 224 | 228 |
| 225 void TearDown() { | 229 void TearDown() { |
| 226 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 230 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
| 227 impl_.reset(); | 231 impl_.reset(); |
| 228 } | 232 } |
| 229 | 233 |
| 230 base::Thread* thread() { return &thread_; } | 234 base::SequencedTaskRunner* task_runner() { |
| 235 return thread_.task_runner().get(); |
| 236 } |
| 231 bool ping_called() const { | 237 bool ping_called() const { |
| 232 base::AutoLock locker(lock_); | 238 base::AutoLock locker(lock_); |
| 233 return ping_called_; | 239 return ping_called_; |
| 234 } | 240 } |
| 235 | 241 |
| 236 private: | 242 private: |
| 237 base::Thread thread_; | 243 base::Thread thread_; |
| 238 | 244 |
| 239 std::unique_ptr<typename ImplTraits<Interface>::Type> impl_; | 245 std::unique_ptr<typename ImplTraits<Interface>::Type> impl_; |
| 240 | 246 |
| 241 mutable base::Lock lock_; | 247 mutable base::Lock lock_; |
| 242 bool ping_called_; | 248 bool ping_called_; |
| 243 | 249 |
| 244 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); | 250 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); |
| 245 }; | 251 }; |
| 246 | 252 |
| 253 template <typename Interface> |
| 254 class TestSyncServiceSequencedPool { |
| 255 public: |
| 256 TestSyncServiceSequencedPool() |
| 257 : pool_(2, "TestSyncServiceSequencedPool"), |
| 258 token_(base::SequencedWorkerPool::GetSequenceToken()), |
| 259 task_runner_(pool_.pool()->GetSequencedTaskRunner(token_)), |
| 260 ping_called_(false) {} |
| 261 |
| 262 void SetUp(InterfaceRequest<Interface> request) { |
| 263 CHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 264 impl_.reset(new typename ImplTraits<Interface>::Type(std::move(request))); |
| 265 impl_->set_ping_handler( |
| 266 [this](const typename Interface::PingCallback& callback) { |
| 267 { |
| 268 base::AutoLock locker(lock_); |
| 269 ping_called_ = true; |
| 270 } |
| 271 callback.Run(); |
| 272 }); |
| 273 } |
| 274 |
| 275 void TearDown() { |
| 276 CHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 277 impl_.reset(); |
| 278 } |
| 279 |
| 280 base::SequencedTaskRunner* task_runner() { return task_runner_.get(); } |
| 281 bool ping_called() const { |
| 282 base::AutoLock locker(lock_); |
| 283 return ping_called_; |
| 284 } |
| 285 |
| 286 private: |
| 287 base::SequencedWorkerPoolOwner pool_; |
| 288 base::SequencedWorkerPool::SequenceToken token_; |
| 289 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 290 |
| 291 std::unique_ptr<typename ImplTraits<Interface>::Type> impl_; |
| 292 |
| 293 mutable base::Lock lock_; |
| 294 bool ping_called_; |
| 295 |
| 296 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceSequencedPool); |
| 297 }; |
| 298 |
| 247 class SyncMethodTest : public testing::Test { | 299 class SyncMethodTest : public testing::Test { |
| 248 public: | 300 public: |
| 249 SyncMethodTest() {} | 301 SyncMethodTest() {} |
| 250 ~SyncMethodTest() override { base::RunLoop().RunUntilIdle(); } | 302 ~SyncMethodTest() override { base::RunLoop().RunUntilIdle(); } |
| 251 | 303 |
| 252 protected: | 304 protected: |
| 253 base::MessageLoop loop_; | 305 base::MessageLoop loop_; |
| 254 }; | 306 }; |
| 255 | 307 |
| 256 template <typename T> | 308 template <typename T> |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 | 379 |
| 328 template <typename Func> | 380 template <typename Func> |
| 329 void CallAsyncEchoCallback(Func func, int32_t value) { | 381 void CallAsyncEchoCallback(Func func, int32_t value) { |
| 330 func(value); | 382 func(value); |
| 331 } | 383 } |
| 332 | 384 |
| 333 template <typename Func> | 385 template <typename Func> |
| 334 TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) { | 386 TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) { |
| 335 return base::Bind(&CallAsyncEchoCallback<Func>, func); | 387 return base::Bind(&CallAsyncEchoCallback<Func>, func); |
| 336 } | 388 } |
| 389 class SequencedTaskRunnerTestBase; |
| 390 |
| 391 void RunTestOnSequencedTaskRunner( |
| 392 std::unique_ptr<SequencedTaskRunnerTestBase> test); |
| 393 |
| 394 class SequencedTaskRunnerTestBase { |
| 395 public: |
| 396 virtual ~SequencedTaskRunnerTestBase() = default; |
| 397 |
| 398 void RunTest() { |
| 399 SetUp(); |
| 400 Run(); |
| 401 } |
| 402 |
| 403 virtual void Run() = 0; |
| 404 |
| 405 virtual void SetUp() {} |
| 406 virtual void TearDown() {} |
| 407 |
| 408 protected: |
| 409 void Done() { |
| 410 TearDown(); |
| 411 task_runner_->PostTask(FROM_HERE, quit_closure_); |
| 412 delete this; |
| 413 } |
| 414 |
| 415 base::Closure DoneClosure() { |
| 416 return base::Bind(&SequencedTaskRunnerTestBase::Done, |
| 417 base::Unretained(this)); |
| 418 } |
| 419 |
| 420 private: |
| 421 friend void RunTestOnSequencedTaskRunner( |
| 422 std::unique_ptr<SequencedTaskRunnerTestBase> test); |
| 423 |
| 424 void Init(const base::Closure& quit_closure) { |
| 425 task_runner_ = base::SequencedTaskRunnerHandle::Get(); |
| 426 quit_closure_ = quit_closure; |
| 427 } |
| 428 |
| 429 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 430 base::Closure quit_closure_; |
| 431 }; |
| 432 |
| 433 template <typename TypeParam> |
| 434 class SyncMethodCommonOnSequencedTaskRunnerCommonTest : public testing::Test { |
| 435 base::MessageLoop message_loop_; |
| 436 }; |
| 437 |
| 438 template <typename TypeParam> |
| 439 class SyncMethodCommonOnSequencedTaskRunnerTest |
| 440 : public SequencedTaskRunnerTestBase { |
| 441 public: |
| 442 void SetUp() override { |
| 443 InterfacePtr<TypeParam> ptr; |
| 444 impl_ = base::MakeUnique<typename ImplTraits<TypeParam>::Type>( |
| 445 MakeRequest(&ptr_)); |
| 446 } |
| 447 |
| 448 protected: |
| 449 InterfacePtr<TypeParam> ptr_; |
| 450 std::unique_ptr<typename ImplTraits<TypeParam>::Type> impl_; |
| 451 }; |
| 452 |
| 453 void RunTestOnSequencedTaskRunner( |
| 454 std::unique_ptr<SequencedTaskRunnerTestBase> test) { |
| 455 ThreadPerTaskSequencedTaskRunnerOwner task_runner_owner; |
| 456 base::RunLoop run_loop; |
| 457 test->Init(run_loop.QuitClosure()); |
| 458 task_runner_owner.GetSequencedTaskRunner()->PostTask( |
| 459 FROM_HERE, base::Bind(&SequencedTaskRunnerTestBase::RunTest, |
| 460 base::Unretained(test.release()))); |
| 461 run_loop.Run(); |
| 462 } |
| 337 | 463 |
| 338 // TestSync and TestSyncMaster exercise Router and MultiplexRouter, | 464 // TestSync and TestSyncMaster exercise Router and MultiplexRouter, |
| 339 // respectively. | 465 // respectively. |
| 340 using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>; | 466 using InterfaceTypes = testing::Types<TestSync, TestSyncMaster>; |
| 341 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); | 467 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); |
| 468 TYPED_TEST_CASE(SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 469 InterfaceTypes); |
| 342 | 470 |
| 343 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { | 471 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { |
| 344 InterfacePtr<TypeParam> ptr; | 472 InterfacePtr<TypeParam> ptr; |
| 345 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 473 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 346 | 474 |
| 347 base::RunLoop run_loop; | 475 base::RunLoop run_loop; |
| 348 ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123, | 476 ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123, |
| 349 run_loop.QuitClosure())); | 477 run_loop.QuitClosure())); |
| 350 run_loop.Run(); | 478 run_loop.Run(); |
| 351 } | 479 } |
| 352 | 480 |
| 481 #define SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name) \ |
| 482 fixture_name##name##_SequencedTaskRunnerTestSuffix |
| 483 |
| 484 #define SEQUENCED_TASK_RUNNER_TYPED_TEST(base_fixture, fixture_name, name) \ |
| 485 template <typename TypeParam> \ |
| 486 class SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name) \ |
| 487 : public fixture_name<TypeParam> { \ |
| 488 void Run() override; \ |
| 489 }; \ |
| 490 TYPED_TEST(base_fixture, name) { \ |
| 491 RunTestOnSequencedTaskRunner( \ |
| 492 base::MakeUnique<SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME( \ |
| 493 fixture_name, name) < TypeParam>> ()); \ |
| 494 } \ |
| 495 template <typename TypeParam> \ |
| 496 void SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, \ |
| 497 name)<TypeParam>::Run() |
| 498 |
| 499 #define SEQUENCED_TASK_RUNNER_TYPED_TEST_F(base_fixture, fixture_name, name) \ |
| 500 template <typename TypeParam> \ |
| 501 class SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name); \ |
| 502 TYPED_TEST(base_fixture, name) { \ |
| 503 RunTestOnSequencedTaskRunner( \ |
| 504 base::MakeUnique<SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME( \ |
| 505 fixture_name, name) < TypeParam>> ()); \ |
| 506 } \ |
| 507 template <typename TypeParam> \ |
| 508 class SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name) \ |
| 509 : public fixture_name<TypeParam> |
| 510 |
| 511 SEQUENCED_TASK_RUNNER_TYPED_TEST( |
| 512 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 513 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 514 CallSyncMethodAsynchronously) { |
| 515 this->ptr_->Echo( |
| 516 123, base::Bind(&ExpectValueAndRunClosure, 123, this->DoneClosure())); |
| 517 } |
| 518 |
| 353 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { | 519 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { |
| 354 InterfacePtr<TypeParam> ptr; | 520 InterfacePtr<TypeParam> ptr; |
| 355 | 521 |
| 356 TestSyncServiceThread<TypeParam> service_thread; | 522 TestSyncServiceThread<TypeParam> service_thread; |
| 357 service_thread.thread()->task_runner()->PostTask( | 523 service_thread.task_runner()->PostTask( |
| 358 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, | 524 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, |
| 359 base::Unretained(&service_thread), | 525 base::Unretained(&service_thread), |
| 360 base::Passed(MakeRequest(&ptr)))); | 526 base::Passed(MakeRequest(&ptr)))); |
| 361 ASSERT_TRUE(ptr->Ping()); | 527 ASSERT_TRUE(ptr->Ping()); |
| 362 ASSERT_TRUE(service_thread.ping_called()); | 528 ASSERT_TRUE(service_thread.ping_called()); |
| 363 | 529 |
| 364 int32_t output_value = -1; | 530 int32_t output_value = -1; |
| 365 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 531 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
| 366 ASSERT_EQ(42, output_value); | 532 ASSERT_EQ(42, output_value); |
| 367 | 533 |
| 368 base::RunLoop run_loop; | 534 base::RunLoop run_loop; |
| 369 service_thread.thread()->task_runner()->PostTaskAndReply( | 535 service_thread.task_runner()->PostTaskAndReply( |
| 370 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::TearDown, | 536 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::TearDown, |
| 371 base::Unretained(&service_thread)), | 537 base::Unretained(&service_thread)), |
| 372 run_loop.QuitClosure()); | 538 run_loop.QuitClosure()); |
| 373 run_loop.Run(); | 539 run_loop.Run(); |
| 374 } | 540 } |
| 375 | 541 |
| 542 TYPED_TEST(SyncMethodCommonTest, BasicSyncCallsOnSequencedTaskRunner) { |
| 543 InterfacePtr<TypeParam> ptr; |
| 544 |
| 545 TestSyncServiceSequencedPool<TypeParam> service_pool; |
| 546 service_pool.task_runner()->PostTask( |
| 547 FROM_HERE, base::Bind(&TestSyncServiceSequencedPool<TypeParam>::SetUp, |
| 548 base::Unretained(&service_pool), |
| 549 base::Passed(MakeRequest(&ptr)))); |
| 550 ASSERT_TRUE(ptr->Ping()); |
| 551 ASSERT_TRUE(service_pool.ping_called()); |
| 552 |
| 553 int32_t output_value = -1; |
| 554 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
| 555 ASSERT_EQ(42, output_value); |
| 556 |
| 557 base::RunLoop run_loop; |
| 558 service_pool.task_runner()->PostTaskAndReply( |
| 559 FROM_HERE, base::Bind(&TestSyncServiceSequencedPool<TypeParam>::TearDown, |
| 560 base::Unretained(&service_pool)), |
| 561 run_loop.QuitClosure()); |
| 562 run_loop.Run(); |
| 563 } |
| 564 |
| 376 TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { | 565 TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { |
| 377 // Test that an interface pointer waiting for a sync call response can be | 566 // Test that an interface pointer waiting for a sync call response can be |
| 378 // reentered by a binding serving sync methods on the same thread. | 567 // reentered by a binding serving sync methods on the same thread. |
| 379 | 568 |
| 380 InterfacePtr<TypeParam> ptr; | 569 InterfacePtr<TypeParam> ptr; |
| 381 // The binding lives on the same thread as the interface pointer. | 570 // The binding lives on the same thread as the interface pointer. |
| 382 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 571 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 383 int32_t output_value = -1; | 572 int32_t output_value = -1; |
| 384 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 573 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
| 385 EXPECT_EQ(42, output_value); | 574 EXPECT_EQ(42, output_value); |
| 386 } | 575 } |
| 387 | 576 |
| 577 SEQUENCED_TASK_RUNNER_TYPED_TEST( |
| 578 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 579 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 580 ReenteredBySyncMethodBinding) { |
| 581 // Test that an interface pointer waiting for a sync call response can be |
| 582 // reentered by a binding serving sync methods on the same thread. |
| 583 |
| 584 int32_t output_value = -1; |
| 585 ASSERT_TRUE(this->ptr_->Echo(42, &output_value)); |
| 586 EXPECT_EQ(42, output_value); |
| 587 this->Done(); |
| 588 } |
| 589 |
| 388 TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { | 590 TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { |
| 389 // Test that it won't result in crash or hang if an interface pointer is | 591 // Test that it won't result in crash or hang if an interface pointer is |
| 390 // destroyed while it is waiting for a sync call response. | 592 // destroyed while it is waiting for a sync call response. |
| 391 | 593 |
| 392 InterfacePtr<TypeParam> ptr; | 594 InterfacePtr<TypeParam> ptr; |
| 393 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 595 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 394 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { | 596 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { |
| 395 ptr.reset(); | 597 ptr.reset(); |
| 396 callback.Run(); | 598 callback.Run(); |
| 397 }); | 599 }); |
| 398 ASSERT_FALSE(ptr->Ping()); | 600 ASSERT_FALSE(ptr->Ping()); |
| 399 } | 601 } |
| 400 | 602 |
| 603 SEQUENCED_TASK_RUNNER_TYPED_TEST( |
| 604 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 605 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 606 InterfacePtrDestroyedDuringSyncCall) { |
| 607 // Test that it won't result in crash or hang if an interface pointer is |
| 608 // destroyed while it is waiting for a sync call response. |
| 609 |
| 610 auto* ptr = &this->ptr_; |
| 611 this->impl_->set_ping_handler([ptr](const TestSync::PingCallback& callback) { |
| 612 ptr->reset(); |
| 613 callback.Run(); |
| 614 }); |
| 615 ASSERT_FALSE(this->ptr_->Ping()); |
| 616 this->Done(); |
| 617 } |
| 618 |
| 401 TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { | 619 TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { |
| 402 // Test that it won't result in crash or hang if a binding is | 620 // Test that it won't result in crash or hang if a binding is |
| 403 // closed (and therefore the message pipe handle is closed) while the | 621 // closed (and therefore the message pipe handle is closed) while the |
| 404 // corresponding interface pointer is waiting for a sync call response. | 622 // corresponding interface pointer is waiting for a sync call response. |
| 405 | 623 |
| 406 InterfacePtr<TypeParam> ptr; | 624 InterfacePtr<TypeParam> ptr; |
| 407 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 625 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 408 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { | 626 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { |
| 409 impl.binding()->Close(); | 627 impl.binding()->Close(); |
| 410 callback.Run(); | 628 callback.Run(); |
| 411 }); | 629 }); |
| 412 ASSERT_FALSE(ptr->Ping()); | 630 ASSERT_FALSE(ptr->Ping()); |
| 413 } | 631 } |
| 414 | 632 |
| 633 SEQUENCED_TASK_RUNNER_TYPED_TEST( |
| 634 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 635 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 636 BindingDestroyedDuringSyncCall) { |
| 637 // Test that it won't result in crash or hang if a binding is |
| 638 // closed (and therefore the message pipe handle is closed) while the |
| 639 // corresponding interface pointer is waiting for a sync call response. |
| 640 |
| 641 auto& impl = *this->impl_; |
| 642 this->impl_->set_ping_handler( |
| 643 [&impl](const TestSync::PingCallback& callback) { |
| 644 impl.binding()->Close(); |
| 645 callback.Run(); |
| 646 }); |
| 647 ASSERT_FALSE(this->ptr_->Ping()); |
| 648 this->Done(); |
| 649 } |
| 650 |
| 415 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { | 651 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { |
| 416 // Test that we can call a sync method on an interface ptr, while there is | 652 // Test that we can call a sync method on an interface ptr, while there is |
| 417 // already a sync call ongoing. The responses arrive in order. | 653 // already a sync call ongoing. The responses arrive in order. |
| 418 | 654 |
| 419 InterfacePtr<TypeParam> ptr; | 655 InterfacePtr<TypeParam> ptr; |
| 420 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 656 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 421 | 657 |
| 422 // The same variable is used to store the output of the two sync calls, in | 658 // The same variable is used to store the output of the two sync calls, in |
| 423 // order to test that responses are handled in the correct order. | 659 // order to test that responses are handled in the correct order. |
| 424 int32_t result_value = -1; | 660 int32_t result_value = -1; |
| 425 | 661 |
| 426 bool first_call = true; | 662 bool first_call = true; |
| 427 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 663 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
| 428 int32_t value, const TestSync::EchoCallback& callback) { | 664 int32_t value, const TestSync::EchoCallback& callback) { |
| 429 if (first_call) { | 665 if (first_call) { |
| 430 first_call = false; | 666 first_call = false; |
| 431 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 667 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
| 432 EXPECT_EQ(456, result_value); | 668 EXPECT_EQ(456, result_value); |
| 433 } | 669 } |
| 434 callback.Run(value); | 670 callback.Run(value); |
| 435 }); | 671 }); |
| 436 | 672 |
| 437 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 673 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
| 438 EXPECT_EQ(123, result_value); | 674 EXPECT_EQ(123, result_value); |
| 439 } | 675 } |
| 440 | 676 |
| 677 SEQUENCED_TASK_RUNNER_TYPED_TEST( |
| 678 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 679 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 680 NestedSyncCallsWithInOrderResponses) { |
| 681 // Test that we can call a sync method on an interface ptr, while there is |
| 682 // already a sync call ongoing. The responses arrive in order. |
| 683 |
| 684 // The same variable is used to store the output of the two sync calls, in |
| 685 // order to test that responses are handled in the correct order. |
| 686 int32_t result_value = -1; |
| 687 |
| 688 bool first_call = true; |
| 689 auto& ptr = this->ptr_; |
| 690 auto& impl = *this->impl_; |
| 691 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
| 692 int32_t value, const TestSync::EchoCallback& callback) { |
| 693 if (first_call) { |
| 694 first_call = false; |
| 695 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
| 696 EXPECT_EQ(456, result_value); |
| 697 } |
| 698 callback.Run(value); |
| 699 }); |
| 700 |
| 701 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
| 702 EXPECT_EQ(123, result_value); |
| 703 this->Done(); |
| 704 } |
| 705 |
| 441 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { | 706 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { |
| 442 // Test that we can call a sync method on an interface ptr, while there is | 707 // Test that we can call a sync method on an interface ptr, while there is |
| 443 // already a sync call ongoing. The responses arrive out of order. | 708 // already a sync call ongoing. The responses arrive out of order. |
| 444 | 709 |
| 445 InterfacePtr<TypeParam> ptr; | 710 InterfacePtr<TypeParam> ptr; |
| 446 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 711 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 447 | 712 |
| 448 // The same variable is used to store the output of the two sync calls, in | 713 // The same variable is used to store the output of the two sync calls, in |
| 449 // order to test that responses are handled in the correct order. | 714 // order to test that responses are handled in the correct order. |
| 450 int32_t result_value = -1; | 715 int32_t result_value = -1; |
| 451 | 716 |
| 452 bool first_call = true; | 717 bool first_call = true; |
| 453 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 718 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
| 454 int32_t value, const TestSync::EchoCallback& callback) { | 719 int32_t value, const TestSync::EchoCallback& callback) { |
| 455 callback.Run(value); | 720 callback.Run(value); |
| 456 if (first_call) { | 721 if (first_call) { |
| 457 first_call = false; | 722 first_call = false; |
| 458 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 723 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
| 459 EXPECT_EQ(456, result_value); | 724 EXPECT_EQ(456, result_value); |
| 460 } | 725 } |
| 461 }); | 726 }); |
| 462 | 727 |
| 463 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 728 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
| 464 EXPECT_EQ(123, result_value); | 729 EXPECT_EQ(123, result_value); |
| 465 } | 730 } |
| 466 | 731 |
| 732 SEQUENCED_TASK_RUNNER_TYPED_TEST( |
| 733 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 734 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 735 NestedSyncCallsWithOutOfOrderResponses) { |
| 736 // Test that we can call a sync method on an interface ptr, while there is |
| 737 // already a sync call ongoing. The responses arrive out of order. |
| 738 |
| 739 // The same variable is used to store the output of the two sync calls, in |
| 740 // order to test that responses are handled in the correct order. |
| 741 int32_t result_value = -1; |
| 742 |
| 743 bool first_call = true; |
| 744 auto& ptr = this->ptr_; |
| 745 auto& impl = *this->impl_; |
| 746 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
| 747 int32_t value, const TestSync::EchoCallback& callback) { |
| 748 callback.Run(value); |
| 749 if (first_call) { |
| 750 first_call = false; |
| 751 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
| 752 EXPECT_EQ(456, result_value); |
| 753 } |
| 754 }); |
| 755 |
| 756 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
| 757 EXPECT_EQ(123, result_value); |
| 758 this->Done(); |
| 759 } |
| 760 |
| 467 TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { | 761 TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { |
| 468 // Test that while an interface pointer is waiting for the response to a sync | 762 // Test that while an interface pointer is waiting for the response to a sync |
| 469 // call, async responses are queued until the sync call completes. | 763 // call, async responses are queued until the sync call completes. |
| 470 | 764 |
| 471 InterfacePtr<TypeParam> ptr; | 765 InterfacePtr<TypeParam> ptr; |
| 472 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 766 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 473 | 767 |
| 474 int32_t async_echo_request_value = -1; | 768 int32_t async_echo_request_value = -1; |
| 475 TestSync::AsyncEchoCallback async_echo_request_callback; | 769 TestSync::AsyncEchoCallback async_echo_request_callback; |
| 476 base::RunLoop run_loop1; | 770 base::RunLoop run_loop1; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 // Although the AsyncEcho response arrives before the Echo response, it should | 806 // Although the AsyncEcho response arrives before the Echo response, it should |
| 513 // be queued and not yet dispatched. | 807 // be queued and not yet dispatched. |
| 514 EXPECT_FALSE(async_echo_response_dispatched); | 808 EXPECT_FALSE(async_echo_response_dispatched); |
| 515 | 809 |
| 516 // Run until the AsyncEcho response is dispatched. | 810 // Run until the AsyncEcho response is dispatched. |
| 517 run_loop2.Run(); | 811 run_loop2.Run(); |
| 518 | 812 |
| 519 EXPECT_TRUE(async_echo_response_dispatched); | 813 EXPECT_TRUE(async_echo_response_dispatched); |
| 520 } | 814 } |
| 521 | 815 |
| 816 SEQUENCED_TASK_RUNNER_TYPED_TEST_F( |
| 817 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 818 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 819 AsyncResponseQueuedDuringSyncCall) { |
| 820 // Test that while an interface pointer is waiting for the response to a sync |
| 821 // call, async responses are queued until the sync call completes. |
| 822 |
| 823 void Run() override { |
| 824 this->impl_->set_async_echo_handler( |
| 825 [this](int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 826 async_echo_request_value_ = value; |
| 827 async_echo_request_callback_ = callback; |
| 828 OnAsyncEchoReceived(); |
| 829 }); |
| 830 |
| 831 this->ptr_->AsyncEcho(123, BindAsyncEchoCallback([this](int32_t result) { |
| 832 async_echo_response_dispatched_ = true; |
| 833 EXPECT_EQ(123, result); |
| 834 EXPECT_TRUE(async_echo_response_dispatched_); |
| 835 this->Done(); |
| 836 })); |
| 837 } |
| 838 |
| 839 // Called when the AsyncEcho request reaches the service side. |
| 840 void OnAsyncEchoReceived() { |
| 841 this->impl_->set_echo_handler( |
| 842 [this](int32_t value, const TestSync::EchoCallback& callback) { |
| 843 // Send back the async response first. |
| 844 EXPECT_FALSE(async_echo_request_callback_.is_null()); |
| 845 async_echo_request_callback_.Run(async_echo_request_value_); |
| 846 |
| 847 callback.Run(value); |
| 848 }); |
| 849 |
| 850 int32_t result_value = -1; |
| 851 ASSERT_TRUE(this->ptr_->Echo(456, &result_value)); |
| 852 EXPECT_EQ(456, result_value); |
| 853 |
| 854 // Although the AsyncEcho response arrives before the Echo response, it |
| 855 // should be queued and not yet dispatched. |
| 856 EXPECT_FALSE(async_echo_response_dispatched_); |
| 857 } |
| 858 |
| 859 int32_t async_echo_request_value_ = -1; |
| 860 TestSync::AsyncEchoCallback async_echo_request_callback_; |
| 861 bool async_echo_response_dispatched_ = false; |
| 862 }; |
| 863 |
| 522 TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { | 864 TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { |
| 523 // Test that while an interface pointer is waiting for the response to a sync | 865 // Test that while an interface pointer is waiting for the response to a sync |
| 524 // call, async requests for a binding running on the same thread are queued | 866 // call, async requests for a binding running on the same thread are queued |
| 525 // until the sync call completes. | 867 // until the sync call completes. |
| 526 | 868 |
| 527 InterfacePtr<TypeParam> ptr; | 869 InterfacePtr<TypeParam> ptr; |
| 528 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 870 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 529 | 871 |
| 530 bool async_echo_request_dispatched = false; | 872 bool async_echo_request_dispatched = false; |
| 531 impl.set_async_echo_handler([&async_echo_request_dispatched]( | 873 impl.set_async_echo_handler([&async_echo_request_dispatched]( |
| (...skipping 29 matching lines...) Expand all Loading... |
| 561 // Although the AsyncEcho request is sent before the Echo request, it | 903 // Although the AsyncEcho request is sent before the Echo request, it |
| 562 // shouldn't be dispatched yet. | 904 // shouldn't be dispatched yet. |
| 563 EXPECT_FALSE(async_echo_request_dispatched); | 905 EXPECT_FALSE(async_echo_request_dispatched); |
| 564 | 906 |
| 565 // Run until the AsyncEcho response is dispatched. | 907 // Run until the AsyncEcho response is dispatched. |
| 566 run_loop.Run(); | 908 run_loop.Run(); |
| 567 | 909 |
| 568 EXPECT_TRUE(async_echo_response_dispatched); | 910 EXPECT_TRUE(async_echo_response_dispatched); |
| 569 } | 911 } |
| 570 | 912 |
| 913 SEQUENCED_TASK_RUNNER_TYPED_TEST_F( |
| 914 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 915 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 916 AsyncRequestQueuedDuringSyncCall) { |
| 917 // Test that while an interface pointer is waiting for the response to a sync |
| 918 // call, async requests for a binding running on the same thread are queued |
| 919 // until the sync call completes. |
| 920 void Run() override { |
| 921 this->impl_->set_async_echo_handler( |
| 922 [this](int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 923 async_echo_request_dispatched_ = true; |
| 924 callback.Run(value); |
| 925 }); |
| 926 |
| 927 this->ptr_->AsyncEcho(123, BindAsyncEchoCallback([this](int32_t result) { |
| 928 EXPECT_EQ(123, result); |
| 929 this->Done(); |
| 930 })); |
| 931 |
| 932 this->impl_->set_echo_handler( |
| 933 [this](int32_t value, const TestSync::EchoCallback& callback) { |
| 934 // Although the AsyncEcho request is sent before the Echo request, it |
| 935 // shouldn't be dispatched yet at this point, because there is an |
| 936 // ongoing |
| 937 // sync call on the same thread. |
| 938 EXPECT_FALSE(async_echo_request_dispatched_); |
| 939 callback.Run(value); |
| 940 }); |
| 941 |
| 942 int32_t result_value = -1; |
| 943 ASSERT_TRUE(this->ptr_->Echo(456, &result_value)); |
| 944 EXPECT_EQ(456, result_value); |
| 945 |
| 946 // Although the AsyncEcho request is sent before the Echo request, it |
| 947 // shouldn't be dispatched yet. |
| 948 EXPECT_FALSE(async_echo_request_dispatched_); |
| 949 } |
| 950 bool async_echo_request_dispatched_ = false; |
| 951 }; |
| 952 |
| 571 TYPED_TEST(SyncMethodCommonTest, | 953 TYPED_TEST(SyncMethodCommonTest, |
| 572 QueuedMessagesProcessedBeforeErrorNotification) { | 954 QueuedMessagesProcessedBeforeErrorNotification) { |
| 573 // Test that while an interface pointer is waiting for the response to a sync | 955 // Test that while an interface pointer is waiting for the response to a sync |
| 574 // call, async responses are queued. If the message pipe is disconnected | 956 // call, async responses are queued. If the message pipe is disconnected |
| 575 // before the queued messages are processed, the connection error | 957 // before the queued messages are processed, the connection error |
| 576 // notification is delayed until all the queued messages are processed. | 958 // notification is delayed until all the queued messages are processed. |
| 577 | 959 |
| 578 InterfacePtr<TypeParam> ptr; | 960 InterfacePtr<TypeParam> ptr; |
| 579 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); | 961 typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| 580 | 962 |
| 581 int32_t async_echo_request_value = -1; | 963 int32_t async_echo_request_value = -1; |
| 582 TestSync::AsyncEchoCallback async_echo_request_callback; | 964 TestSync::AsyncEchoCallback async_echo_request_callback; |
| 583 base::RunLoop run_loop1; | 965 base::RunLoop run_loop1; |
| 584 impl.set_async_echo_handler( | 966 impl.set_async_echo_handler( |
| 585 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 967 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
| 586 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 968 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 587 async_echo_request_value = value; | 969 async_echo_request_value = value; |
| 588 async_echo_request_callback = callback; | 970 async_echo_request_callback = callback; |
| 589 run_loop1.Quit(); | 971 run_loop1.Quit(); |
| 590 }); | 972 }); |
| 591 | 973 |
| 592 bool async_echo_response_dispatched = false; | 974 bool async_echo_response_dispatched = false; |
| 593 bool connection_error_dispatched = false; | 975 bool connection_error_dispatched = false; |
| 594 base::RunLoop run_loop2; | 976 base::RunLoop run_loop2; |
| 595 ptr->AsyncEcho( | 977 ptr->AsyncEcho(123, BindAsyncEchoCallback([&async_echo_response_dispatched, |
| 596 123, | 978 &connection_error_dispatched, &ptr, |
| 597 BindAsyncEchoCallback( | 979 &run_loop2](int32_t result) { |
| 598 [&async_echo_response_dispatched, &connection_error_dispatched, &ptr, | 980 async_echo_response_dispatched = true; |
| 599 &run_loop2](int32_t result) { | 981 // At this point, error notification should not be dispatched |
| 600 async_echo_response_dispatched = true; | 982 // yet. |
| 601 // At this point, error notification should not be dispatched | 983 EXPECT_FALSE(connection_error_dispatched); |
| 602 // yet. | 984 EXPECT_FALSE(ptr.encountered_error()); |
| 603 EXPECT_FALSE(connection_error_dispatched); | 985 EXPECT_EQ(123, result); |
| 604 EXPECT_FALSE(ptr.encountered_error()); | 986 run_loop2.Quit(); |
| 605 EXPECT_EQ(123, result); | 987 })); |
| 606 run_loop2.Quit(); | |
| 607 })); | |
| 608 // Run until the AsyncEcho request reaches the service side. | 988 // Run until the AsyncEcho request reaches the service side. |
| 609 run_loop1.Run(); | 989 run_loop1.Run(); |
| 610 | 990 |
| 611 impl.set_echo_handler( | 991 impl.set_echo_handler( |
| 612 [&impl, &async_echo_request_value, &async_echo_request_callback]( | 992 [&impl, &async_echo_request_value, &async_echo_request_callback]( |
| 613 int32_t value, const TestSync::EchoCallback& callback) { | 993 int32_t value, const TestSync::EchoCallback& callback) { |
| 614 // Send back the async response first. | 994 // Send back the async response first. |
| 615 EXPECT_FALSE(async_echo_request_callback.is_null()); | 995 EXPECT_FALSE(async_echo_request_callback.is_null()); |
| 616 async_echo_request_callback.Run(async_echo_request_value); | 996 async_echo_request_callback.Run(async_echo_request_value); |
| 617 | 997 |
| 618 impl.binding()->Close(); | 998 impl.binding()->Close(); |
| 619 }); | 999 }); |
| 620 | 1000 |
| 621 base::RunLoop run_loop3; | 1001 base::RunLoop run_loop3; |
| 622 ptr.set_connection_error_handler( | 1002 ptr.set_connection_error_handler(base::Bind(&SetFlagAndRunClosure, |
| 623 base::Bind(&SetFlagAndRunClosure, &connection_error_dispatched, | 1003 &connection_error_dispatched, |
| 624 run_loop3.QuitClosure())); | 1004 run_loop3.QuitClosure())); |
| 625 | 1005 |
| 626 int32_t result_value = -1; | 1006 int32_t result_value = -1; |
| 627 ASSERT_FALSE(ptr->Echo(456, &result_value)); | 1007 ASSERT_FALSE(ptr->Echo(456, &result_value)); |
| 628 EXPECT_EQ(-1, result_value); | 1008 EXPECT_EQ(-1, result_value); |
| 629 ASSERT_FALSE(connection_error_dispatched); | 1009 ASSERT_FALSE(connection_error_dispatched); |
| 630 EXPECT_FALSE(ptr.encountered_error()); | 1010 EXPECT_FALSE(ptr.encountered_error()); |
| 631 | 1011 |
| 632 // Although the AsyncEcho response arrives before the Echo response, it should | 1012 // Although the AsyncEcho response arrives before the Echo response, it should |
| 633 // be queued and not yet dispatched. | 1013 // be queued and not yet dispatched. |
| 634 EXPECT_FALSE(async_echo_response_dispatched); | 1014 EXPECT_FALSE(async_echo_response_dispatched); |
| 635 | 1015 |
| 636 // Run until the AsyncEcho response is dispatched. | 1016 // Run until the AsyncEcho response is dispatched. |
| 637 run_loop2.Run(); | 1017 run_loop2.Run(); |
| 638 | 1018 |
| 639 EXPECT_TRUE(async_echo_response_dispatched); | 1019 EXPECT_TRUE(async_echo_response_dispatched); |
| 640 | 1020 |
| 641 // Run until the error notification is dispatched. | 1021 // Run until the error notification is dispatched. |
| 642 run_loop3.Run(); | 1022 run_loop3.Run(); |
| 643 | 1023 |
| 644 ASSERT_TRUE(connection_error_dispatched); | 1024 ASSERT_TRUE(connection_error_dispatched); |
| 645 EXPECT_TRUE(ptr.encountered_error()); | 1025 EXPECT_TRUE(ptr.encountered_error()); |
| 646 } | 1026 } |
| 647 | 1027 |
| 1028 SEQUENCED_TASK_RUNNER_TYPED_TEST_F( |
| 1029 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 1030 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 1031 QueuedMessagesProcessedBeforeErrorNotification) { |
| 1032 // Test that while an interface pointer is waiting for the response to a sync |
| 1033 // call, async responses are queued. If the message pipe is disconnected |
| 1034 // before the queued messages are processed, the connection error |
| 1035 // notification is delayed until all the queued messages are processed. |
| 1036 |
| 1037 void Run() override { |
| 1038 this->impl_->set_async_echo_handler( |
| 1039 [this](int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 1040 async_echo_request_value_ = value; |
| 1041 async_echo_request_callback_ = callback; |
| 1042 Run2(); |
| 1043 }); |
| 1044 |
| 1045 this->ptr_->AsyncEcho(123, BindAsyncEchoCallback([this](int32_t result) { |
| 1046 async_echo_response_dispatched_ = true; |
| 1047 // At this point, error notification should not be |
| 1048 // dispatched |
| 1049 // yet. |
| 1050 EXPECT_FALSE(connection_error_dispatched_); |
| 1051 EXPECT_FALSE(this->ptr_.encountered_error()); |
| 1052 EXPECT_EQ(123, result); |
| 1053 EXPECT_TRUE(async_echo_response_dispatched_); |
| 1054 })); |
| 1055 } |
| 1056 |
| 1057 // Invoked when the AsyncEcho request reaches the service side. |
| 1058 void Run2() { |
| 1059 this->impl_->set_echo_handler( |
| 1060 [this](int32_t value, const TestSync::EchoCallback& callback) { |
| 1061 // Send back the async response first. |
| 1062 EXPECT_FALSE(async_echo_request_callback_.is_null()); |
| 1063 async_echo_request_callback_.Run(async_echo_request_value_); |
| 1064 |
| 1065 this->impl_->binding()->Close(); |
| 1066 }); |
| 1067 |
| 1068 this->ptr_.set_connection_error_handler( |
| 1069 base::Bind(&SetFlagAndRunClosure, &connection_error_dispatched_, |
| 1070 LambdaBinder<>::BindLambda([this]() { Run4(); }))); |
| 1071 |
| 1072 int32_t result_value = -1; |
| 1073 ASSERT_FALSE(this->ptr_->Echo(456, &result_value)); |
| 1074 EXPECT_EQ(-1, result_value); |
| 1075 ASSERT_FALSE(connection_error_dispatched_); |
| 1076 EXPECT_FALSE(this->ptr_.encountered_error()); |
| 1077 |
| 1078 // Although the AsyncEcho response arrives before the Echo response, it |
| 1079 // should |
| 1080 // be queued and not yet dispatched. |
| 1081 EXPECT_FALSE(async_echo_response_dispatched_); |
| 1082 } |
| 1083 |
| 1084 // Invoked when the error notification is dispatched. |
| 1085 void Run4() { |
| 1086 ASSERT_TRUE(connection_error_dispatched_); |
| 1087 EXPECT_TRUE(this->ptr_.encountered_error()); |
| 1088 this->Done(); |
| 1089 } |
| 1090 |
| 1091 int32_t async_echo_request_value_ = -1; |
| 1092 TestSync::AsyncEchoCallback async_echo_request_callback_; |
| 1093 bool async_echo_response_dispatched_ = false; |
| 1094 bool connection_error_dispatched_ = false; |
| 1095 }; |
| 1096 |
| 648 TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { | 1097 TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { |
| 649 // Test that while an interface pointer is waiting for the response to a sync | 1098 // Test that while an interface pointer is waiting for the response to a sync |
| 650 // call, an invalid incoming message will disconnect the message pipe, cause | 1099 // call, an invalid incoming message will disconnect the message pipe, cause |
| 651 // the sync call to return false, and run the connection error handler | 1100 // the sync call to return false, and run the connection error handler |
| 652 // asynchronously. | 1101 // asynchronously. |
| 653 | 1102 |
| 654 MessagePipe pipe; | 1103 MessagePipe pipe; |
| 655 | 1104 |
| 656 InterfacePtr<TypeParam> ptr; | 1105 InterfacePtr<TypeParam> ptr; |
| 657 ptr.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u)); | 1106 ptr.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 679 | 1128 |
| 680 int32_t result_value = -1; | 1129 int32_t result_value = -1; |
| 681 ASSERT_FALSE(ptr->Echo(456, &result_value)); | 1130 ASSERT_FALSE(ptr->Echo(456, &result_value)); |
| 682 EXPECT_EQ(-1, result_value); | 1131 EXPECT_EQ(-1, result_value); |
| 683 ASSERT_FALSE(connection_error_dispatched); | 1132 ASSERT_FALSE(connection_error_dispatched); |
| 684 | 1133 |
| 685 run_loop.Run(); | 1134 run_loop.Run(); |
| 686 ASSERT_TRUE(connection_error_dispatched); | 1135 ASSERT_TRUE(connection_error_dispatched); |
| 687 } | 1136 } |
| 688 | 1137 |
| 1138 SEQUENCED_TASK_RUNNER_TYPED_TEST_F( |
| 1139 SyncMethodCommonOnSequencedTaskRunnerCommonTest, |
| 1140 SyncMethodCommonOnSequencedTaskRunnerTest, |
| 1141 InvalidMessageDuringSyncCall) { |
| 1142 // Test that while an interface pointer is waiting for the response to a sync |
| 1143 // call, an invalid incoming message will disconnect the message pipe, cause |
| 1144 // the sync call to return false, and run the connection error handler |
| 1145 // asynchronously. |
| 1146 |
| 1147 void Run() override { |
| 1148 MessagePipe pipe; |
| 1149 |
| 1150 this->ptr_.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u)); |
| 1151 |
| 1152 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); |
| 1153 this->impl_ = base::MakeUnique<typename ImplTraits<TypeParam>::Type>( |
| 1154 MakeRequest<TypeParam>(std::move(pipe.handle1))); |
| 1155 |
| 1156 this->impl_->set_echo_handler([raw_binding_handle]( |
| 1157 int32_t value, const TestSync::EchoCallback& callback) { |
| 1158 // Write a 1-byte message, which is considered invalid. |
| 1159 char invalid_message = 0; |
| 1160 MojoResult result = |
| 1161 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, |
| 1162 MOJO_WRITE_MESSAGE_FLAG_NONE); |
| 1163 ASSERT_EQ(MOJO_RESULT_OK, result); |
| 1164 callback.Run(value); |
| 1165 }); |
| 1166 |
| 1167 this->ptr_.set_connection_error_handler( |
| 1168 LambdaBinder<>::BindLambda([this]() { |
| 1169 connection_error_dispatched_ = true; |
| 1170 this->Done(); |
| 1171 })); |
| 1172 |
| 1173 int32_t result_value = -1; |
| 1174 ASSERT_FALSE(this->ptr_->Echo(456, &result_value)); |
| 1175 EXPECT_EQ(-1, result_value); |
| 1176 ASSERT_FALSE(connection_error_dispatched_); |
| 1177 } |
| 1178 bool connection_error_dispatched_ = false; |
| 1179 }; |
| 1180 |
| 689 TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) { | 1181 TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) { |
| 690 // Test that an interface pointer waiting for a sync call response can be | 1182 // Test that an interface pointer waiting for a sync call response can be |
| 691 // reentered by an associated binding serving sync methods on the same thread. | 1183 // reentered by an associated binding serving sync methods on the same thread. |
| 692 // The associated binding belongs to the same MultiplexRouter as the waiting | 1184 // The associated binding belongs to the same MultiplexRouter as the waiting |
| 693 // interface pointer. | 1185 // interface pointer. |
| 694 | 1186 |
| 695 TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_)); | 1187 TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_)); |
| 696 TestSyncAssociatedPtr opposite_asso_ptr; | 1188 TestSyncAssociatedPtr opposite_asso_ptr; |
| 697 opposite_asso_ptr.Bind(std::move(opposite_asso_ptr_info_)); | 1189 opposite_asso_ptr.Bind(std::move(opposite_asso_ptr_info_)); |
| 698 | 1190 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 int32_t result_value = -1; | 1225 int32_t result_value = -1; |
| 734 ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); | 1226 ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); |
| 735 EXPECT_EQ(456, result_value); | 1227 EXPECT_EQ(456, result_value); |
| 736 } | 1228 } |
| 737 | 1229 |
| 738 // TODO(yzshen): Add more tests related to associated interfaces. | 1230 // TODO(yzshen): Add more tests related to associated interfaces. |
| 739 | 1231 |
| 740 } // namespace | 1232 } // namespace |
| 741 } // namespace test | 1233 } // namespace test |
| 742 } // namespace mojo | 1234 } // namespace mojo |
| OLD | NEW |