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

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

Issue 2770153003: mojo: Support sync calls through ThreadSafeInterfacePtr (Closed)
Patch Set: SyncMethodCommonTests now run with both IP and TSIP 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
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 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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698