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