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