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 |