| 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" |
| 17 #include "mojo/edk/embedder/scoped_platform_handle.h" | 10 #include "mojo/edk/embedder/scoped_platform_handle.h" |
| 18 #include "mojo/edk/system/channel.h" | 11 #include "mojo/edk/system/handle_signals_state.h" |
| 19 #include "mojo/edk/system/local_message_pipe_endpoint.h" | |
| 20 #include "mojo/edk/system/message_pipe.h" | |
| 21 #include "mojo/edk/system/message_pipe_test_utils.h" | 12 #include "mojo/edk/system/message_pipe_test_utils.h" |
| 22 #include "mojo/edk/system/proxy_message_pipe_endpoint.h" | |
| 23 #include "mojo/edk/system/raw_channel.h" | |
| 24 #include "mojo/edk/system/test_utils.h" | 13 #include "mojo/edk/system/test_utils.h" |
| 25 #include "mojo/edk/test/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" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 18 |
| 28 namespace mojo { | 19 namespace mojo { |
| 29 namespace system { | 20 namespace system { |
| 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 embedder::SimplePlatformSupport platform_support; |
| 96 test::ChannelThread channel_thread(&platform_support); | 90 base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); |
| 91 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart); |
| 92 mojo::test::ScopedIPCSupport ipc_support(test_io_thread.task_runner()); |
| 93 |
| 97 embedder::ScopedPlatformHandle client_platform_handle = | 94 embedder::ScopedPlatformHandle client_platform_handle = |
| 98 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); | 95 mojo::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 mojo::embedder::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 = mojo::embedder::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 system |
| 168 } // namespace mojo | 162 } // namespace mojo |
| OLD | NEW |