Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: mojo/public/cpp/bindings/tests/sync_method_unittest.cc

Issue 2770153003: mojo: Support sync calls through ThreadSafeInterfacePtr (Closed)
Patch Set: afds Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | mojo/public/cpp/bindings/thread_safe_interface_ptr.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | mojo/public/cpp/bindings/thread_safe_interface_ptr.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698