| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 // Unit test for SyncChannel. | 5 // Unit test for SyncChannel. |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 void OverrideThread(base::Thread* overrided_thread) { | 97 void OverrideThread(base::Thread* overrided_thread) { |
| 98 DCHECK(overrided_thread_ == NULL); | 98 DCHECK(overrided_thread_ == NULL); |
| 99 overrided_thread_ = overrided_thread; | 99 overrided_thread_ = overrided_thread; |
| 100 } | 100 } |
| 101 bool SendAnswerToLife(bool pump, int timeout, bool succeed) { | 101 bool SendAnswerToLife(bool pump, int timeout, bool succeed) { |
| 102 int answer = 0; | 102 int answer = 0; |
| 103 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); | 103 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); |
| 104 if (pump) | 104 if (pump) |
| 105 msg->EnableMessagePumping(); | 105 msg->EnableMessagePumping(); |
| 106 bool result = SendWithTimeout(msg, timeout); | 106 bool result = SendWithTimeout(msg, timeout); |
| 107 DCHECK(result == succeed); | 107 DCHECK_EQ(result, succeed); |
| 108 DCHECK(answer == (succeed ? 42 : 0)); | 108 DCHECK_EQ(answer, (succeed ? 42 : 0)); |
| 109 return result; | 109 return result; |
| 110 } | 110 } |
| 111 bool SendDouble(bool pump, bool succeed) { | 111 bool SendDouble(bool pump, bool succeed) { |
| 112 int answer = 0; | 112 int answer = 0; |
| 113 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer); | 113 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer); |
| 114 if (pump) | 114 if (pump) |
| 115 msg->EnableMessagePumping(); | 115 msg->EnableMessagePumping(); |
| 116 bool result = Send(msg); | 116 bool result = Send(msg); |
| 117 DCHECK(result == succeed); | 117 DCHECK_EQ(result, succeed); |
| 118 DCHECK(answer == (succeed ? 10 : 0)); | 118 DCHECK_EQ(answer, (succeed ? 10 : 0)); |
| 119 return result; | 119 return result; |
| 120 } | 120 } |
| 121 Channel::Mode mode() { return mode_; } | 121 Channel::Mode mode() { return mode_; } |
| 122 WaitableEvent* done_event() { return done_.get(); } | 122 WaitableEvent* done_event() { return done_.get(); } |
| 123 void ResetChannel() { channel_.reset(); } |
| 123 | 124 |
| 124 protected: | 125 protected: |
| 125 // Derived classes need to call this when they've completed their part of | 126 // Derived classes need to call this when they've completed their part of |
| 126 // the test. | 127 // the test. |
| 127 void Done() { done_->Signal(); } | 128 void Done() { done_->Signal(); } |
| 128 // Functions for dervied classes to implement if they wish. | 129 // Functions for dervied classes to implement if they wish. |
| 129 virtual void Run() { } | 130 virtual void Run() { } |
| 130 virtual void OnAnswer(int* answer) { NOTREACHED(); } | 131 virtual void OnAnswer(int* answer) { NOTREACHED(); } |
| 131 virtual void OnAnswerDelay(Message* reply_msg) { | 132 virtual void OnAnswerDelay(Message* reply_msg) { |
| 132 // The message handler map below can only take one entry for | 133 // The message handler map below can only take one entry for |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 NoHang(false); | 383 NoHang(false); |
| 383 NoHang(true); | 384 NoHang(true); |
| 384 } | 385 } |
| 385 | 386 |
| 386 //----------------------------------------------------------------------------- | 387 //----------------------------------------------------------------------------- |
| 387 | 388 |
| 388 namespace { | 389 namespace { |
| 389 | 390 |
| 390 class UnblockServer : public Worker { | 391 class UnblockServer : public Worker { |
| 391 public: | 392 public: |
| 392 UnblockServer(bool pump_during_send) | 393 UnblockServer(bool pump_during_send, bool delete_during_send) |
| 393 : Worker(Channel::MODE_SERVER, "unblock_server"), | 394 : Worker(Channel::MODE_SERVER, "unblock_server"), |
| 394 pump_during_send_(pump_during_send) { } | 395 pump_during_send_(pump_during_send), |
| 396 delete_during_send_(delete_during_send) { } |
| 395 void Run() { | 397 void Run() { |
| 396 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true); | 398 if (delete_during_send_) { |
| 399 // Use custom code since race conditions mean the answer may or may not be |
| 400 // available. |
| 401 int answer = 0; |
| 402 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); |
| 403 if (pump_during_send_) |
| 404 msg->EnableMessagePumping(); |
| 405 Send(msg); |
| 406 } else { |
| 407 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true); |
| 408 } |
| 397 Done(); | 409 Done(); |
| 398 } | 410 } |
| 399 | 411 |
| 400 void OnDouble(int in, int* out) { | 412 void OnDoubleDelay(int in, Message* reply_msg) { |
| 401 *out = in * 2; | 413 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2); |
| 414 Send(reply_msg); |
| 415 if (delete_during_send_) |
| 416 ResetChannel(); |
| 402 } | 417 } |
| 403 | 418 |
| 404 bool pump_during_send_; | 419 bool pump_during_send_; |
| 420 bool delete_during_send_; |
| 405 }; | 421 }; |
| 406 | 422 |
| 407 class UnblockClient : public Worker { | 423 class UnblockClient : public Worker { |
| 408 public: | 424 public: |
| 409 UnblockClient(bool pump_during_send) | 425 UnblockClient(bool pump_during_send) |
| 410 : Worker(Channel::MODE_CLIENT, "unblock_client"), | 426 : Worker(Channel::MODE_CLIENT, "unblock_client"), |
| 411 pump_during_send_(pump_during_send) { } | 427 pump_during_send_(pump_during_send) { } |
| 412 | 428 |
| 413 void OnAnswer(int* answer) { | 429 void OnAnswer(int* answer) { |
| 414 SendDouble(pump_during_send_, true); | 430 SendDouble(pump_during_send_, true); |
| 415 *answer = 42; | 431 *answer = 42; |
| 416 Done(); | 432 Done(); |
| 417 } | 433 } |
| 418 | 434 |
| 419 bool pump_during_send_; | 435 bool pump_during_send_; |
| 420 }; | 436 }; |
| 421 | 437 |
| 422 void Unblock(bool server_pump, bool client_pump) { | 438 void Unblock(bool server_pump, bool client_pump, bool delete_during_send) { |
| 423 std::vector<Worker*> workers; | 439 std::vector<Worker*> workers; |
| 424 workers.push_back(new UnblockServer(server_pump)); | 440 workers.push_back(new UnblockServer(server_pump, delete_during_send)); |
| 425 workers.push_back(new UnblockClient(client_pump)); | 441 workers.push_back(new UnblockClient(client_pump)); |
| 426 RunTest(workers); | 442 RunTest(workers); |
| 427 } | 443 } |
| 428 | 444 |
| 429 } // namespace | 445 } // namespace |
| 430 | 446 |
| 431 // Tests that the caller unblocks to answer a sync message from the receiver. | 447 // Tests that the caller unblocks to answer a sync message from the receiver. |
| 432 TEST_F(IPCSyncChannelTest, Unblock) { | 448 TEST_F(IPCSyncChannelTest, Unblock) { |
| 433 Unblock(false, false); | 449 Unblock(false, false, false); |
| 434 Unblock(false, true); | 450 Unblock(false, true, false); |
| 435 Unblock(true, false); | 451 Unblock(true, false, false); |
| 436 Unblock(true, true); | 452 Unblock(true, true, false); |
| 453 } |
| 454 |
| 455 //----------------------------------------------------------------------------- |
| 456 |
| 457 // Tests that the the IPC::SyncChannel object can be deleted during a Send. |
| 458 TEST_F(IPCSyncChannelTest, ChannelDeleteDuringSend) { |
| 459 Unblock(false, false, true); |
| 460 Unblock(false, true, true); |
| 461 Unblock(true, false, true); |
| 462 Unblock(true, true, true); |
| 437 } | 463 } |
| 438 | 464 |
| 439 //----------------------------------------------------------------------------- | 465 //----------------------------------------------------------------------------- |
| 440 | 466 |
| 441 namespace { | 467 namespace { |
| 442 | 468 |
| 443 class RecursiveServer : public Worker { | 469 class RecursiveServer : public Worker { |
| 444 public: | 470 public: |
| 445 explicit RecursiveServer( | 471 explicit RecursiveServer( |
| 446 bool expected_send_result, bool pump_first, bool pump_second) | 472 bool expected_send_result, bool pump_first, bool pump_second) |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 Worker::OverrideThread(listener_thread); | 729 Worker::OverrideThread(listener_thread); |
| 704 } | 730 } |
| 705 | 731 |
| 706 virtual void Run() { | 732 virtual void Run() { |
| 707 std::string response; | 733 std::string response; |
| 708 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); | 734 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); |
| 709 if (pump_during_send_) | 735 if (pump_during_send_) |
| 710 msg->EnableMessagePumping(); | 736 msg->EnableMessagePumping(); |
| 711 bool result = Send(msg); | 737 bool result = Send(msg); |
| 712 DCHECK(result); | 738 DCHECK(result); |
| 713 DCHECK(response == expected_text_); | 739 DCHECK_EQ(response, expected_text_); |
| 714 | 740 |
| 715 LOG(INFO) << __FUNCTION__ << " Received reply: " | 741 LOG(INFO) << __FUNCTION__ << " Received reply: " |
| 716 << response.c_str(); | 742 << response.c_str(); |
| 717 Done(); | 743 Done(); |
| 718 } | 744 } |
| 719 | 745 |
| 720 private: | 746 private: |
| 721 bool pump_during_send_; | 747 bool pump_during_send_; |
| 722 std::string expected_text_; | 748 std::string expected_text_; |
| 723 }; | 749 }; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 // in ipc_message_utils doesn't fire. | 820 // in ipc_message_utils doesn't fire. |
| 795 int log_level = logging::GetMinLogLevel(); | 821 int log_level = logging::GetMinLogLevel(); |
| 796 logging::SetMinLogLevel(kint32max); | 822 logging::SetMinLogLevel(kint32max); |
| 797 bool result = Send(msg); | 823 bool result = Send(msg); |
| 798 logging::SetMinLogLevel(log_level); | 824 logging::SetMinLogLevel(log_level); |
| 799 DCHECK(!result); | 825 DCHECK(!result); |
| 800 | 826 |
| 801 // Need to send another message to get the client to call Done(). | 827 // Need to send another message to get the client to call Done(). |
| 802 result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); | 828 result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); |
| 803 DCHECK(result); | 829 DCHECK(result); |
| 804 DCHECK(answer == 42); | 830 DCHECK_EQ(answer, 42); |
| 805 | 831 |
| 806 Done(); | 832 Done(); |
| 807 } | 833 } |
| 808 | 834 |
| 809 bool pump_during_send_; | 835 bool pump_during_send_; |
| 810 }; | 836 }; |
| 811 | 837 |
| 812 void BadMessage(bool pump_during_send) { | 838 void BadMessage(bool pump_during_send) { |
| 813 std::vector<Worker*> workers; | 839 std::vector<Worker*> workers; |
| 814 workers.push_back(new BadServer(pump_during_send)); | 840 workers.push_back(new BadServer(pump_during_send)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 841 if (!SendDouble(false, true)) | 867 if (!SendDouble(false, true)) |
| 842 break; | 868 break; |
| 843 } | 869 } |
| 844 *answer = 42; | 870 *answer = 42; |
| 845 Done(); | 871 Done(); |
| 846 } | 872 } |
| 847 }; | 873 }; |
| 848 | 874 |
| 849 void ChattyServer(bool pump_during_send) { | 875 void ChattyServer(bool pump_during_send) { |
| 850 std::vector<Worker*> workers; | 876 std::vector<Worker*> workers; |
| 851 workers.push_back(new UnblockServer(pump_during_send)); | 877 workers.push_back(new UnblockServer(pump_during_send, false)); |
| 852 workers.push_back(new ChattyClient()); | 878 workers.push_back(new ChattyClient()); |
| 853 RunTest(workers); | 879 RunTest(workers); |
| 854 } | 880 } |
| 855 | 881 |
| 856 } // namespace | 882 } // namespace |
| 857 | 883 |
| 858 // Tests http://b/1093251 - that sending lots of sync messages while | 884 // Tests http://b/1093251 - that sending lots of sync messages while |
| 859 // the receiver is waiting for a sync reply does not overflow the PostMessage | 885 // the receiver is waiting for a sync reply does not overflow the PostMessage |
| 860 // queue. | 886 // queue. |
| 861 TEST_F(IPCSyncChannelTest, ChattyServer) { | 887 TEST_F(IPCSyncChannelTest, ChattyServer) { |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 | 1047 |
| 1022 // Tests http://b/1474092 - that if after the done_event is set but before | 1048 // Tests http://b/1474092 - that if after the done_event is set but before |
| 1023 // OnObjectSignaled is called another message is sent out, then after its | 1049 // OnObjectSignaled is called another message is sent out, then after its |
| 1024 // reply comes back OnObjectSignaled will be called for the first message. | 1050 // reply comes back OnObjectSignaled will be called for the first message. |
| 1025 TEST_F(IPCSyncChannelTest, DoneEventRace) { | 1051 TEST_F(IPCSyncChannelTest, DoneEventRace) { |
| 1026 std::vector<Worker*> workers; | 1052 std::vector<Worker*> workers; |
| 1027 workers.push_back(new DoneEventRaceServer()); | 1053 workers.push_back(new DoneEventRaceServer()); |
| 1028 workers.push_back(new SimpleClient()); | 1054 workers.push_back(new SimpleClient()); |
| 1029 RunTest(workers); | 1055 RunTest(workers); |
| 1030 } | 1056 } |
| OLD | NEW |