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