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 |