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 |