OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <stdint.h> | |
6 #include <stdio.h> | |
7 #include <string.h> | |
8 | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/bind.h" | 5 #include "base/bind.h" |
13 #include "base/location.h" | |
14 #include "base/logging.h" | 6 #include "base/logging.h" |
15 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
16 #include "base/test/perf_time_logger.h" | 8 #include "base/test/perf_time_logger.h" |
| 9 #include "mojo/edk/embedder/embedder.h" |
| 10 #include "mojo/edk/embedder/scoped_platform_handle.h" |
| 11 #include "mojo/edk/system/handle_signals_state.h" |
| 12 #include "mojo/edk/system/message_pipe_test_utils.h" |
| 13 #include "mojo/edk/system/test_utils.h" |
| 14 #include "mojo/edk/test/test_utils.h" |
| 15 #include "mojo/public/c/system/functions.h" |
| 16 #include "mojo/public/cpp/system/message_pipe.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 #include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h" | |
19 #include "third_party/mojo/src/mojo/edk/system/channel.h" | |
20 #include "third_party/mojo/src/mojo/edk/system/local_message_pipe_endpoint.h" | |
21 #include "third_party/mojo/src/mojo/edk/system/message_pipe.h" | |
22 #include "third_party/mojo/src/mojo/edk/system/message_pipe_test_utils.h" | |
23 #include "third_party/mojo/src/mojo/edk/system/proxy_message_pipe_endpoint.h" | |
24 #include "third_party/mojo/src/mojo/edk/system/raw_channel.h" | |
25 #include "third_party/mojo/src/mojo/edk/system/test_utils.h" | |
26 #include "third_party/mojo/src/mojo/edk/test/test_utils.h" | |
27 | 18 |
28 namespace mojo { | 19 namespace mojo { |
29 namespace system { | 20 namespace edk { |
30 namespace { | 21 namespace { |
31 | 22 |
32 class MultiprocessMessagePipePerfTest | 23 class MultiprocessMessagePipePerfTest |
33 : public test::MultiprocessMessagePipeTestBase { | 24 : public test::MultiprocessMessagePipeTestBase { |
34 public: | 25 public: |
35 MultiprocessMessagePipePerfTest() : message_count_(0), message_size_(0) {} | 26 MultiprocessMessagePipePerfTest() |
| 27 : test::MultiprocessMessagePipeTestBase(base::MessageLoop::TYPE_IO), |
| 28 message_count_(0), |
| 29 message_size_(0) {} |
36 | 30 |
37 void SetUpMeasurement(int message_count, size_t message_size) { | 31 void SetUpMeasurement(int message_count, size_t message_size) { |
38 message_count_ = message_count; | 32 message_count_ = message_count; |
39 message_size_ = message_size; | 33 message_size_ = message_size; |
40 payload_ = std::string(message_size, '*'); | 34 payload_ = std::string(message_size, '*'); |
41 read_buffer_.resize(message_size * 2); | 35 read_buffer_.resize(message_size * 2); |
42 } | 36 } |
43 | 37 |
44 protected: | 38 protected: |
45 void WriteWaitThenRead(scoped_refptr<MessagePipe> mp) { | 39 void WriteWaitThenRead(MojoHandle mp) { |
46 CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(payload_.data()), | 40 CHECK_EQ(MojoWriteMessage(mp, payload_.data(), |
47 static_cast<uint32_t>(payload_.size()), nullptr, | 41 static_cast<uint32_t>(payload_.size()), nullptr, |
48 MOJO_WRITE_MESSAGE_FLAG_NONE), | 42 0, MOJO_WRITE_MESSAGE_FLAG_NONE), |
49 MOJO_RESULT_OK); | 43 MOJO_RESULT_OK); |
50 HandleSignalsState hss; | 44 HandleSignalsState hss; |
51 CHECK_EQ(test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss), | 45 CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, |
| 46 &hss), |
52 MOJO_RESULT_OK); | 47 MOJO_RESULT_OK); |
53 uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer_.size()); | 48 uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer_.size()); |
54 CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer_[0]), | 49 CHECK_EQ(MojoReadMessage(mp, &read_buffer_[0], &read_buffer_size, nullptr, |
55 MakeUserPointer(&read_buffer_size), nullptr, | |
56 nullptr, MOJO_READ_MESSAGE_FLAG_NONE), | 50 nullptr, MOJO_READ_MESSAGE_FLAG_NONE), |
57 MOJO_RESULT_OK); | 51 MOJO_RESULT_OK); |
58 CHECK_EQ(read_buffer_size, static_cast<uint32_t>(payload_.size())); | 52 CHECK_EQ(read_buffer_size, static_cast<uint32_t>(payload_.size())); |
59 } | 53 } |
60 | 54 |
61 void SendQuitMessage(scoped_refptr<MessagePipe> mp) { | 55 void SendQuitMessage(MojoHandle mp) { |
62 CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(""), 0, nullptr, | 56 CHECK_EQ(MojoWriteMessage(mp, "", 0, nullptr, 0, |
63 MOJO_WRITE_MESSAGE_FLAG_NONE), | 57 MOJO_WRITE_MESSAGE_FLAG_NONE), |
64 MOJO_RESULT_OK); | 58 MOJO_RESULT_OK); |
65 } | 59 } |
66 | 60 |
67 void Measure(scoped_refptr<MessagePipe> mp) { | 61 void Measure(MojoHandle mp) { |
68 // Have one ping-pong to ensure channel being established. | 62 // Have one ping-pong to ensure channel being established. |
69 WriteWaitThenRead(mp); | 63 WriteWaitThenRead(mp); |
70 | 64 |
71 std::string test_name = | 65 std::string test_name = |
72 base::StringPrintf("IPC_Perf_%dx_%u", message_count_, | 66 base::StringPrintf("IPC_Perf_%dx_%u", message_count_, |
73 static_cast<unsigned>(message_size_)); | 67 static_cast<unsigned>(message_size_)); |
74 base::PerfTimeLogger logger(test_name.c_str()); | 68 base::PerfTimeLogger logger(test_name.c_str()); |
75 | 69 |
76 for (int i = 0; i < message_count_; ++i) | 70 for (int i = 0; i < message_count_; ++i) |
77 WriteWaitThenRead(mp); | 71 WriteWaitThenRead(mp); |
78 | 72 |
79 logger.Done(); | 73 logger.Done(); |
80 } | 74 } |
81 | 75 |
82 private: | 76 private: |
83 int message_count_; | 77 int message_count_; |
84 size_t message_size_; | 78 size_t message_size_; |
85 std::string payload_; | 79 std::string payload_; |
86 std::string read_buffer_; | 80 std::string read_buffer_; |
87 scoped_ptr<base::PerfTimeLogger> perf_logger_; | 81 scoped_ptr<base::PerfTimeLogger> perf_logger_; |
88 }; | 82 }; |
89 | 83 |
90 // For each message received, sends a reply message with the same contents | 84 // For each message received, sends a reply message with the same contents |
91 // repeated twice, until the other end is closed or it receives "quitquitquit" | 85 // repeated twice, until the other end is closed or it receives "quitquitquit" |
92 // (which it doesn't reply to). It'll return the number of messages received, | 86 // (which it doesn't reply to). It'll return the number of messages received, |
93 // not including any "quitquitquit" message, modulo 100. | 87 // not including any "quitquitquit" message, modulo 100. |
94 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PingPongClient) { | 88 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PingPongClient) { |
95 embedder::SimplePlatformSupport platform_support; | 89 SimplePlatformSupport platform_support; |
96 test::ChannelThread channel_thread(&platform_support); | 90 base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); |
97 embedder::ScopedPlatformHandle client_platform_handle = | 91 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart); |
98 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); | 92 test::ScopedIPCSupport ipc_support(test_io_thread.task_runner()); |
| 93 |
| 94 ScopedPlatformHandle client_platform_handle = |
| 95 test::MultiprocessTestHelper::client_platform_handle.Pass(); |
99 CHECK(client_platform_handle.is_valid()); | 96 CHECK(client_platform_handle.is_valid()); |
100 scoped_refptr<ChannelEndpoint> ep; | 97 ScopedMessagePipeHandle mp = |
101 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep)); | 98 CreateMessagePipe(client_platform_handle.Pass()); |
102 channel_thread.Start(client_platform_handle.Pass(), ep); | |
103 | 99 |
104 std::string buffer(1000000, '\0'); | 100 std::string buffer(1000000, '\0'); |
105 int rv = 0; | 101 int rv = 0; |
106 while (true) { | 102 while (true) { |
107 // Wait for our end of the message pipe to be readable. | 103 // Wait for our end of the message pipe to be readable. |
108 HandleSignalsState hss; | 104 HandleSignalsState hss; |
109 MojoResult result = | 105 MojoResult result = |
110 test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss); | 106 MojoWait(mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE, |
| 107 MOJO_DEADLINE_INDEFINITE, &hss); |
111 if (result != MOJO_RESULT_OK) { | 108 if (result != MOJO_RESULT_OK) { |
112 rv = result; | 109 rv = result; |
113 break; | 110 break; |
114 } | 111 } |
115 | 112 |
116 uint32_t read_size = static_cast<uint32_t>(buffer.size()); | 113 uint32_t read_size = static_cast<uint32_t>(buffer.size()); |
117 CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&buffer[0]), | 114 CHECK_EQ(MojoReadMessage(mp.get().value(), &buffer[0], |
118 MakeUserPointer(&read_size), nullptr, nullptr, | 115 &read_size, nullptr, |
119 MOJO_READ_MESSAGE_FLAG_NONE), | 116 0, MOJO_READ_MESSAGE_FLAG_NONE), |
120 MOJO_RESULT_OK); | 117 MOJO_RESULT_OK); |
121 | 118 |
122 // Empty message indicates quit. | 119 // Empty message indicates quit. |
123 if (read_size == 0) | 120 if (read_size == 0) |
124 break; | 121 break; |
125 | 122 |
126 CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(&buffer[0]), | 123 CHECK_EQ(MojoWriteMessage(mp.get().value(), &buffer[0], |
127 static_cast<uint32_t>(read_size), nullptr, | 124 read_size, |
128 MOJO_WRITE_MESSAGE_FLAG_NONE), | 125 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE), |
129 MOJO_RESULT_OK); | 126 MOJO_RESULT_OK); |
130 } | 127 } |
131 | 128 |
132 mp->Close(0); | |
133 return rv; | 129 return rv; |
134 } | 130 } |
135 | 131 |
136 // Repeatedly sends messages as previous one got replied by the child. | 132 // Repeatedly sends messages as previous one got replied by the child. |
137 // Waits for the child to close its end before quitting once specified | 133 // Waits for the child to close its end before quitting once specified |
138 // number of messages has been sent. | 134 // number of messages has been sent. |
139 #if defined(OS_ANDROID) | 135 #if defined(OS_ANDROID) |
140 // Android multi-process tests are not executing the new process. This is flaky. | 136 // Android multi-process tests are not executing the new process. This is flaky. |
141 #define MAYBE_PingPong DISABLED_PingPong | 137 #define MAYBE_PingPong DISABLED_PingPong |
142 #else | 138 #else |
143 #define MAYBE_PingPong PingPong | 139 #define MAYBE_PingPong PingPong |
144 #endif // defined(OS_ANDROID) | 140 #endif // defined(OS_ANDROID) |
145 TEST_F(MultiprocessMessagePipePerfTest, MAYBE_PingPong) { | 141 TEST_F(MultiprocessMessagePipePerfTest, MAYBE_PingPong) { |
146 helper()->StartChild("PingPongClient"); | 142 helper()->StartChild("PingPongClient"); |
147 | 143 |
148 scoped_refptr<ChannelEndpoint> ep; | 144 ScopedMessagePipeHandle mp = CreateMessagePipe( |
149 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep)); | 145 helper()->server_platform_handle.Pass()); |
150 Init(ep); | |
151 | 146 |
152 // This values are set to align with one at ipc_pertests.cc for comparison. | 147 // This values are set to align with one at ipc_pertests.cc for comparison. |
153 const size_t kMsgSize[5] = {12, 144, 1728, 20736, 248832}; | 148 const size_t kMsgSize[5] = {12, 144, 1728, 20736, 248832}; |
154 const int kMessageCount[5] = {50000, 50000, 50000, 12000, 1000}; | 149 const int kMessageCount[5] = {50000, 50000, 50000, 12000, 1000}; |
155 | 150 |
156 for (size_t i = 0; i < 5; i++) { | 151 for (size_t i = 0; i < 5; i++) { |
157 SetUpMeasurement(kMessageCount[i], kMsgSize[i]); | 152 SetUpMeasurement(kMessageCount[i], kMsgSize[i]); |
158 Measure(mp); | 153 Measure(mp.get().value()); |
159 } | 154 } |
160 | 155 |
161 SendQuitMessage(mp); | 156 SendQuitMessage(mp.get().value()); |
162 mp->Close(0); | |
163 EXPECT_EQ(0, helper()->WaitForChildShutdown()); | 157 EXPECT_EQ(0, helper()->WaitForChildShutdown()); |
164 } | 158 } |
165 | 159 |
166 } // namespace | 160 } // namespace |
167 } // namespace system | 161 } // namespace edk |
168 } // namespace mojo | 162 } // namespace mojo |
OLD | NEW |