summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/BUILD.gn2
-rw-r--r--ipc/ipc.gyp2
-rw-r--r--ipc/ipc_channel.h2
-rw-r--r--ipc/ipc_channel_factory.h2
-rw-r--r--ipc/ipc_perftest_support.cc342
-rw-r--r--ipc/ipc_perftest_support.h59
-rw-r--r--ipc/ipc_perftests.cc313
-rw-r--r--ipc/ipc_test_base.cc22
-rw-r--r--ipc/ipc_test_base.h4
-rw-r--r--ipc/mojo/BUILD.gn19
-rw-r--r--ipc/mojo/ipc_channel_mojo.cc12
-rw-r--r--ipc/mojo/ipc_channel_mojo.h5
-rw-r--r--ipc/mojo/ipc_channel_mojo_unittest.cc49
-rw-r--r--ipc/mojo/ipc_mojo.gyp25
-rw-r--r--ipc/mojo/ipc_mojo_perftest.cc87
15 files changed, 575 insertions, 370 deletions
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn
index 4d547431..e7e08b5 100644
--- a/ipc/BUILD.gn
+++ b/ipc/BUILD.gn
@@ -162,6 +162,8 @@ static_library("test_support") {
sources = [
"ipc_multiprocess_test.cc",
"ipc_multiprocess_test.h",
+ "ipc_perftest_support.cc",
+ "ipc_perftest_support.h",
"ipc_test_sink.cc",
"ipc_test_sink.h",
"ipc_test_base.cc",
diff --git a/ipc/ipc.gyp b/ipc/ipc.gyp
index 6d90ab6..28c112b 100644
--- a/ipc/ipc.gyp
+++ b/ipc/ipc.gyp
@@ -130,6 +130,8 @@
'sources': [
'ipc_multiprocess_test.cc',
'ipc_multiprocess_test.h',
+ 'ipc_perftest_support.cc',
+ 'ipc_perftest_support.h',
'ipc_test_base.cc',
'ipc_test_base.h',
'ipc_test_channel_listener.cc',
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
index fbd4ae0..d27af58 100644
--- a/ipc/ipc_channel.h
+++ b/ipc/ipc_channel.h
@@ -118,7 +118,7 @@ class IPC_EXPORT Channel : public Sender {
// TODO(morrita): Replace CreateByModeForProxy() with one of above Create*().
//
static scoped_ptr<Channel> Create(
- const IPC::ChannelHandle &channel_handle, Mode mode,Listener* listener);
+ const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener);
static scoped_ptr<Channel> CreateClient(
const IPC::ChannelHandle &channel_handle, Listener* listener);
diff --git a/ipc/ipc_channel_factory.h b/ipc/ipc_channel_factory.h
index 30bfd8c..84bcf97 100644
--- a/ipc/ipc_channel_factory.h
+++ b/ipc/ipc_channel_factory.h
@@ -16,7 +16,7 @@ namespace IPC {
// Encapsulates how a Channel is created. A ChannelFactory can be
// passed to the constructor of ChannelProxy or SyncChannel to tell them
// how to create underlying channel.
-class ChannelFactory {
+class IPC_EXPORT ChannelFactory {
public:
// Creates a factory for "native" channel built through
// IPC::Channel::Create().
diff --git a/ipc/ipc_perftest_support.cc b/ipc/ipc_perftest_support.cc
new file mode 100644
index 0000000..b826420
--- /dev/null
+++ b/ipc/ipc_perftest_support.cc
@@ -0,0 +1,342 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ipc/ipc_perftest_support.h"
+
+#include <algorithm>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/pickle.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/perf_time_logger.h"
+#include "base/test/test_io_thread.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_channel_proxy.h"
+#include "ipc/ipc_descriptors.h"
+#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_sender.h"
+
+namespace IPC {
+namespace test {
+
+// This class simply collects stats about abstract "events" (each of which has a
+// start time and an end time).
+class EventTimeTracker {
+ public:
+ explicit EventTimeTracker(const char* name)
+ : name_(name),
+ count_(0) {
+ }
+
+ void AddEvent(const base::TimeTicks& start, const base::TimeTicks& end) {
+ DCHECK(end >= start);
+ count_++;
+ base::TimeDelta duration = end - start;
+ total_duration_ += duration;
+ max_duration_ = std::max(max_duration_, duration);
+ }
+
+ void ShowResults() const {
+ VLOG(1) << name_ << " count: " << count_;
+ VLOG(1) << name_ << " total duration: "
+ << total_duration_.InMillisecondsF() << " ms";
+ VLOG(1) << name_ << " average duration: "
+ << (total_duration_.InMillisecondsF() / static_cast<double>(count_))
+ << " ms";
+ VLOG(1) << name_ << " maximum duration: "
+ << max_duration_.InMillisecondsF() << " ms";
+ }
+
+ void Reset() {
+ count_ = 0;
+ total_duration_ = base::TimeDelta();
+ max_duration_ = base::TimeDelta();
+ }
+
+ private:
+ const std::string name_;
+
+ uint64 count_;
+ base::TimeDelta total_duration_;
+ base::TimeDelta max_duration_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventTimeTracker);
+};
+
+// This channel listener just replies to all messages with the exact same
+// message. It assumes each message has one string parameter. When the string
+// "quit" is sent, it will exit.
+class ChannelReflectorListener : public Listener {
+ public:
+ ChannelReflectorListener()
+ : channel_(NULL),
+ latency_tracker_("Client messages") {
+ VLOG(1) << "Client listener up";
+ }
+
+ virtual ~ChannelReflectorListener() {
+ VLOG(1) << "Client listener down";
+ latency_tracker_.ShowResults();
+ }
+
+ void Init(Channel* channel) {
+ DCHECK(!channel_);
+ channel_ = channel;
+ }
+
+ virtual bool OnMessageReceived(const Message& message) OVERRIDE {
+ CHECK(channel_);
+
+ PickleIterator iter(message);
+ int64 time_internal;
+ EXPECT_TRUE(iter.ReadInt64(&time_internal));
+ int msgid;
+ EXPECT_TRUE(iter.ReadInt(&msgid));
+ std::string payload;
+ EXPECT_TRUE(iter.ReadString(&payload));
+
+ // Include message deserialization in latency.
+ base::TimeTicks now = base::TimeTicks::Now();
+
+ if (payload == "hello") {
+ latency_tracker_.Reset();
+ } else if (payload == "quit") {
+ latency_tracker_.ShowResults();
+ base::MessageLoop::current()->QuitWhenIdle();
+ return true;
+ } else {
+ // Don't track hello and quit messages.
+ latency_tracker_.AddEvent(
+ base::TimeTicks::FromInternalValue(time_internal), now);
+ }
+
+ Message* msg = new Message(0, 2, Message::PRIORITY_NORMAL);
+ msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
+ msg->WriteInt(msgid);
+ msg->WriteString(payload);
+ channel_->Send(msg);
+ return true;
+ }
+
+ private:
+ Channel* channel_;
+ EventTimeTracker latency_tracker_;
+};
+
+class PerformanceChannelListener : public Listener {
+ public:
+ explicit PerformanceChannelListener(const std::string& label)
+ : label_(label),
+ sender_(NULL),
+ msg_count_(0),
+ msg_size_(0),
+ count_down_(0),
+ latency_tracker_("Server messages") {
+ VLOG(1) << "Server listener up";
+ }
+
+ virtual ~PerformanceChannelListener() {
+ VLOG(1) << "Server listener down";
+ }
+
+ void Init(Sender* sender) {
+ DCHECK(!sender_);
+ sender_ = sender;
+ }
+
+ // Call this before running the message loop.
+ void SetTestParams(int msg_count, size_t msg_size) {
+ DCHECK_EQ(0, count_down_);
+ msg_count_ = msg_count;
+ msg_size_ = msg_size;
+ count_down_ = msg_count_;
+ payload_ = std::string(msg_size_, 'a');
+ }
+
+ virtual bool OnMessageReceived(const Message& message) OVERRIDE {
+ CHECK(sender_);
+
+ PickleIterator iter(message);
+ int64 time_internal;
+ EXPECT_TRUE(iter.ReadInt64(&time_internal));
+ int msgid;
+ EXPECT_TRUE(iter.ReadInt(&msgid));
+ std::string reflected_payload;
+ EXPECT_TRUE(iter.ReadString(&reflected_payload));
+
+ // Include message deserialization in latency.
+ base::TimeTicks now = base::TimeTicks::Now();
+
+ if (reflected_payload == "hello") {
+ // Start timing on hello.
+ latency_tracker_.Reset();
+ DCHECK(!perf_logger_.get());
+ std::string test_name =
+ base::StringPrintf("IPC_%s_Perf_%dx_%u",
+ label_.c_str(),
+ msg_count_,
+ static_cast<unsigned>(msg_size_));
+ perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+ } else {
+ DCHECK_EQ(payload_.size(), reflected_payload.size());
+
+ latency_tracker_.AddEvent(
+ base::TimeTicks::FromInternalValue(time_internal), now);
+
+ CHECK(count_down_ > 0);
+ count_down_--;
+ if (count_down_ == 0) {
+ perf_logger_.reset(); // Stop the perf timer now.
+ latency_tracker_.ShowResults();
+ base::MessageLoop::current()->QuitWhenIdle();
+ return true;
+ }
+ }
+
+ Message* msg = new Message(0, 2, Message::PRIORITY_NORMAL);
+ msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
+ msg->WriteInt(count_down_);
+ msg->WriteString(payload_);
+ sender_->Send(msg);
+ return true;
+ }
+
+ private:
+ std::string label_;
+ Sender* sender_;
+ int msg_count_;
+ size_t msg_size_;
+
+ int count_down_;
+ std::string payload_;
+ EventTimeTracker latency_tracker_;
+ scoped_ptr<base::PerfTimeLogger> perf_logger_;
+};
+
+std::vector<PingPongTestParams>
+IPCChannelPerfTestBase::GetDefaultTestParams() {
+ // Test several sizes. We use 12^N for message size, and limit the message
+ // count to keep the test duration reasonable.
+ std::vector<PingPongTestParams> list;
+ list.push_back(PingPongTestParams(12, 50000));
+ list.push_back(PingPongTestParams(144, 50000));
+ list.push_back(PingPongTestParams(1728, 50000));
+ list.push_back(PingPongTestParams(20736, 12000));
+ list.push_back(PingPongTestParams(248832, 100));
+ return list;
+}
+
+void IPCChannelPerfTestBase::RunTestChannelPingPong(
+ const std::vector<PingPongTestParams>& params) {
+ Init("PerformanceClient");
+
+ // Set up IPC channel and start client.
+ PerformanceChannelListener listener("Channel");
+ CreateChannel(&listener);
+ listener.Init(channel());
+ ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
+
+ for (size_t i = 0; i < params.size(); i++) {
+ listener.SetTestParams(params[i].message_count(),
+ params[i].message_size());
+
+ // This initial message will kick-start the ping-pong of messages.
+ Message* message =
+ new Message(0, 2, Message::PRIORITY_NORMAL);
+ message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
+ message->WriteInt(-1);
+ message->WriteString("hello");
+ sender()->Send(message);
+
+ // Run message loop.
+ base::MessageLoop::current()->Run();
+ }
+
+ // Send quit message.
+ Message* message = new Message(0, 2, Message::PRIORITY_NORMAL);
+ message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
+ message->WriteInt(-1);
+ message->WriteString("quit");
+ sender()->Send(message);
+
+ EXPECT_TRUE(WaitForClientShutdown());
+ DestroyChannel();
+}
+
+void IPCChannelPerfTestBase::RunTestChannelProxyPingPong(
+ const std::vector<PingPongTestParams>& params) {
+ InitWithCustomMessageLoop("PerformanceClient",
+ make_scoped_ptr(new base::MessageLoop()));
+
+ base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
+
+ // Set up IPC channel and start client.
+ PerformanceChannelListener listener("ChannelProxy");
+ CreateChannelProxy(&listener, io_thread.task_runner());
+ listener.Init(channel_proxy());
+ ASSERT_TRUE(StartClient());
+
+ for (size_t i = 0; i < params.size(); i++) {
+ listener.SetTestParams(params[i].message_count(),
+ params[i].message_size());
+
+ // This initial message will kick-start the ping-pong of messages.
+ Message* message =
+ new Message(0, 2, Message::PRIORITY_NORMAL);
+ message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
+ message->WriteInt(-1);
+ message->WriteString("hello");
+ sender()->Send(message);
+
+ // Run message loop.
+ base::MessageLoop::current()->Run();
+ }
+
+ // Send quit message.
+ Message* message = new Message(0, 2, Message::PRIORITY_NORMAL);
+ message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
+ message->WriteInt(-1);
+ message->WriteString("quit");
+ sender()->Send(message);
+
+ EXPECT_TRUE(WaitForClientShutdown());
+ DestroyChannelProxy();
+}
+
+
+PingPongTestClient::PingPongTestClient()
+ : listener_(new ChannelReflectorListener()) {
+}
+
+PingPongTestClient::~PingPongTestClient() {
+}
+
+scoped_ptr<Channel> PingPongTestClient::CreateChannel(
+ Listener* listener) {
+ return Channel::CreateClient(
+ IPCTestBase::GetChannelName("PerformanceClient"), listener);
+}
+
+int PingPongTestClient::RunMain() {
+ scoped_ptr<Channel> channel = CreateChannel(listener_.get());
+ listener_->Init(channel.get());
+ CHECK(channel->Connect());
+
+ base::MessageLoop::current()->Run();
+ return 0;
+}
+
+scoped_refptr<base::TaskRunner> PingPongTestClient::task_runner() {
+ return main_message_loop_.message_loop_proxy();
+}
+
+} // namespace test
+} // namespace IPC
diff --git a/ipc/ipc_perftest_support.h b/ipc/ipc_perftest_support.h
new file mode 100644
index 0000000..611a209
--- /dev/null
+++ b/ipc/ipc_perftest_support.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IPC_IPC_PERFTEST_SUPPORT_H_
+#define IPC_IPC_PERFTEST_SUPPORT_H_
+
+#include <vector>
+
+#include "ipc/ipc_test_base.h"
+
+namespace IPC {
+namespace test {
+
+class ChannelReflectorListener;
+
+class PingPongTestParams {
+ public:
+ PingPongTestParams(size_t size, int count)
+ : message_size_(size), message_count_(count) {
+ }
+
+ size_t message_size() const { return message_size_; }
+ int message_count() const { return message_count_; }
+
+ private:
+ size_t message_size_;
+ int message_count_;
+};
+
+class IPCChannelPerfTestBase : public IPCTestBase {
+ public:
+ static std::vector<PingPongTestParams> GetDefaultTestParams();
+
+ void RunTestChannelPingPong(
+ const std::vector<PingPongTestParams>& params_list);
+ void RunTestChannelProxyPingPong(
+ const std::vector<PingPongTestParams>& params_list);
+};
+
+class PingPongTestClient {
+ public:
+ PingPongTestClient();
+ virtual ~PingPongTestClient();
+
+ virtual scoped_ptr<Channel> CreateChannel(Listener* listener);
+ int RunMain();
+ scoped_refptr<base::TaskRunner> task_runner();
+
+ private:
+ base::MessageLoopForIO main_message_loop_;
+ scoped_ptr<ChannelReflectorListener> listener_;
+ scoped_ptr<Channel> channel_;
+};
+
+}
+}
+
+#endif // IPC_IPC_PERFTEST_SUPPORT_H_
diff --git a/ipc/ipc_perftests.cc b/ipc/ipc_perftests.cc
index 08a8d70..cb40626 100644
--- a/ipc/ipc_perftests.cc
+++ b/ipc/ipc_perftests.cc
@@ -2,26 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "build/build_config.h"
-
-#include <algorithm>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/pickle.h"
-#include "base/strings/stringprintf.h"
-#include "base/test/perf_time_logger.h"
-#include "base/test/test_io_thread.h"
-#include "base/threading/thread.h"
-#include "base/time/time.h"
-#include "ipc/ipc_channel.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_descriptors.h"
-#include "ipc/ipc_message_utils.h"
-#include "ipc/ipc_sender.h"
-#include "ipc/ipc_test_base.h"
+#include "ipc/ipc_perftest_support.h"
namespace {
@@ -29,298 +10,20 @@ namespace {
//
// TODO(brettw): Make this test run by default.
-class IPCChannelPerfTest : public IPCTestBase {
-};
-
-// This class simply collects stats about abstract "events" (each of which has a
-// start time and an end time).
-class EventTimeTracker {
- public:
- explicit EventTimeTracker(const char* name)
- : name_(name),
- count_(0) {
- }
-
- void AddEvent(const base::TimeTicks& start, const base::TimeTicks& end) {
- DCHECK(end >= start);
- count_++;
- base::TimeDelta duration = end - start;
- total_duration_ += duration;
- max_duration_ = std::max(max_duration_, duration);
- }
-
- void ShowResults() const {
- VLOG(1) << name_ << " count: " << count_;
- VLOG(1) << name_ << " total duration: "
- << total_duration_.InMillisecondsF() << " ms";
- VLOG(1) << name_ << " average duration: "
- << (total_duration_.InMillisecondsF() / static_cast<double>(count_))
- << " ms";
- VLOG(1) << name_ << " maximum duration: "
- << max_duration_.InMillisecondsF() << " ms";
- }
-
- void Reset() {
- count_ = 0;
- total_duration_ = base::TimeDelta();
- max_duration_ = base::TimeDelta();
- }
-
- private:
- const std::string name_;
-
- uint64 count_;
- base::TimeDelta total_duration_;
- base::TimeDelta max_duration_;
-
- DISALLOW_COPY_AND_ASSIGN(EventTimeTracker);
-};
-
-// This channel listener just replies to all messages with the exact same
-// message. It assumes each message has one string parameter. When the string
-// "quit" is sent, it will exit.
-class ChannelReflectorListener : public IPC::Listener {
- public:
- ChannelReflectorListener()
- : channel_(NULL),
- latency_tracker_("Client messages") {
- VLOG(1) << "Client listener up";
- }
-
- virtual ~ChannelReflectorListener() {
- VLOG(1) << "Client listener down";
- latency_tracker_.ShowResults();
- }
-
- void Init(IPC::Channel* channel) {
- DCHECK(!channel_);
- channel_ = channel;
- }
-
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
- CHECK(channel_);
-
- PickleIterator iter(message);
- int64 time_internal;
- EXPECT_TRUE(iter.ReadInt64(&time_internal));
- int msgid;
- EXPECT_TRUE(iter.ReadInt(&msgid));
- std::string payload;
- EXPECT_TRUE(iter.ReadString(&payload));
-
- // Include message deserialization in latency.
- base::TimeTicks now = base::TimeTicks::Now();
-
- if (payload == "hello") {
- latency_tracker_.Reset();
- } else if (payload == "quit") {
- latency_tracker_.ShowResults();
- base::MessageLoop::current()->QuitWhenIdle();
- return true;
- } else {
- // Don't track hello and quit messages.
- latency_tracker_.AddEvent(
- base::TimeTicks::FromInternalValue(time_internal), now);
- }
-
- IPC::Message* msg = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- msg->WriteInt(msgid);
- msg->WriteString(payload);
- channel_->Send(msg);
- return true;
- }
-
- private:
- IPC::Channel* channel_;
- EventTimeTracker latency_tracker_;
-};
-
-class PerformanceChannelListener : public IPC::Listener {
- public:
- explicit PerformanceChannelListener(const std::string& label)
- : label_(label),
- sender_(NULL),
- msg_count_(0),
- msg_size_(0),
- count_down_(0),
- latency_tracker_("Server messages") {
- VLOG(1) << "Server listener up";
- }
-
- virtual ~PerformanceChannelListener() {
- VLOG(1) << "Server listener down";
- }
-
- void Init(IPC::Sender* sender) {
- DCHECK(!sender_);
- sender_ = sender;
- }
-
- // Call this before running the message loop.
- void SetTestParams(int msg_count, size_t msg_size) {
- DCHECK_EQ(0, count_down_);
- msg_count_ = msg_count;
- msg_size_ = msg_size;
- count_down_ = msg_count_;
- payload_ = std::string(msg_size_, 'a');
- }
-
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
- CHECK(sender_);
-
- PickleIterator iter(message);
- int64 time_internal;
- EXPECT_TRUE(iter.ReadInt64(&time_internal));
- int msgid;
- EXPECT_TRUE(iter.ReadInt(&msgid));
- std::string reflected_payload;
- EXPECT_TRUE(iter.ReadString(&reflected_payload));
-
- // Include message deserialization in latency.
- base::TimeTicks now = base::TimeTicks::Now();
-
- if (reflected_payload == "hello") {
- // Start timing on hello.
- latency_tracker_.Reset();
- DCHECK(!perf_logger_.get());
- std::string test_name =
- base::StringPrintf("IPC_%s_Perf_%dx_%u",
- label_.c_str(),
- msg_count_,
- static_cast<unsigned>(msg_size_));
- perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
- } else {
- DCHECK_EQ(payload_.size(), reflected_payload.size());
-
- latency_tracker_.AddEvent(
- base::TimeTicks::FromInternalValue(time_internal), now);
-
- CHECK(count_down_ > 0);
- count_down_--;
- if (count_down_ == 0) {
- perf_logger_.reset(); // Stop the perf timer now.
- latency_tracker_.ShowResults();
- base::MessageLoop::current()->QuitWhenIdle();
- return true;
- }
- }
-
- IPC::Message* msg = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- msg->WriteInt(count_down_);
- msg->WriteString(payload_);
- sender_->Send(msg);
- return true;
- }
-
- private:
- std::string label_;
- IPC::Sender* sender_;
- int msg_count_;
- size_t msg_size_;
-
- int count_down_;
- std::string payload_;
- EventTimeTracker latency_tracker_;
- scoped_ptr<base::PerfTimeLogger> perf_logger_;
+class IPCChannelPerfTest : public IPC::test::IPCChannelPerfTestBase {
};
TEST_F(IPCChannelPerfTest, ChannelPingPong) {
- Init("PerformanceClient");
-
- // Set up IPC channel and start client.
- PerformanceChannelListener listener("Channel");
- CreateChannel(&listener);
- listener.Init(channel());
- ASSERT_TRUE(ConnectChannel());
- ASSERT_TRUE(StartClient());
-
- // Test several sizes. We use 12^N for message size, and limit the message
- // count to keep the test duration reasonable.
- const size_t kMsgSize[5] = {12, 144, 1728, 20736, 248832};
- const int kMessageCount[5] = {50000, 50000, 50000, 12000, 1000};
-
- for (size_t i = 0; i < 5; i++) {
- listener.SetTestParams(kMessageCount[i], kMsgSize[i]);
-
- // This initial message will kick-start the ping-pong of messages.
- IPC::Message* message =
- new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("hello");
- sender()->Send(message);
-
- // Run message loop.
- base::MessageLoop::current()->Run();
- }
-
- // Send quit message.
- IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("quit");
- sender()->Send(message);
-
- EXPECT_TRUE(WaitForClientShutdown());
- DestroyChannel();
-}
-
-// This message loop bounces all messages back to the sender.
-MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) {
- base::MessageLoopForIO main_message_loop;
- ChannelReflectorListener listener;
- scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
- IPCTestBase::GetChannelName("PerformanceClient"), &listener));
- listener.Init(channel.get());
- CHECK(channel->Connect());
-
- base::MessageLoop::current()->Run();
- return 0;
+ RunTestChannelPingPong(GetDefaultTestParams());
}
TEST_F(IPCChannelPerfTest, ChannelProxyPingPong) {
- InitWithCustomMessageLoop("PerformanceClient",
- make_scoped_ptr(new base::MessageLoop()));
-
- base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
-
- // Set up IPC channel and start client.
- PerformanceChannelListener listener("ChannelProxy");
- CreateChannelProxy(&listener, io_thread.task_runner());
- listener.Init(channel_proxy());
- ASSERT_TRUE(StartClient());
-
- // Test several sizes. We use 12^N for message size, and limit the message
- // count to keep the test duration reasonable.
- const size_t kMsgSize[5] = {12, 144, 1728, 20736, 248832};
- const int kMessageCount[5] = {50000, 50000, 50000, 12000, 1000};
-
- for (size_t i = 0; i < 5; i++) {
- listener.SetTestParams(kMessageCount[i], kMsgSize[i]);
-
- // This initial message will kick-start the ping-pong of messages.
- IPC::Message* message =
- new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("hello");
- sender()->Send(message);
-
- // Run message loop.
- base::MessageLoop::current()->Run();
- }
-
- // Send quit message.
- IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("quit");
- sender()->Send(message);
+ RunTestChannelProxyPingPong(GetDefaultTestParams());
+}
- EXPECT_TRUE(WaitForClientShutdown());
- DestroyChannelProxy();
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) {
+ IPC::test::PingPongTestClient client;
+ return client.RunMain();
}
} // namespace
diff --git a/ipc/ipc_test_base.cc b/ipc/ipc_test_base.cc
index 80ddd2d..6abef0f 100644
--- a/ipc/ipc_test_base.cc
+++ b/ipc/ipc_test_base.cc
@@ -52,8 +52,8 @@ void IPCTestBase::InitWithCustomMessageLoop(
}
void IPCTestBase::CreateChannel(IPC::Listener* listener) {
- return CreateChannelFromChannelHandle(GetChannelName(test_client_name_),
- listener);
+ CreateChannelFromChannelHandle(
+ GetChannelName(test_client_name_), listener);
}
bool IPCTestBase::ConnectChannel() {
@@ -80,7 +80,8 @@ void IPCTestBase::CreateChannelFromChannelHandle(
IPC::Listener* listener) {
CHECK(!channel_.get());
CHECK(!channel_proxy_.get());
- channel_ = IPC::Channel::CreateServer(channel_handle, listener);
+ channel_ = CreateChannelFactory(
+ channel_handle, task_runner().get())->BuildChannel(listener);
}
void IPCTestBase::CreateChannelProxy(
@@ -88,10 +89,11 @@ void IPCTestBase::CreateChannelProxy(
const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
CHECK(!channel_.get());
CHECK(!channel_proxy_.get());
- channel_proxy_ = IPC::ChannelProxy::Create(GetChannelName(test_client_name_),
- IPC::Channel::MODE_SERVER,
- listener,
- ipc_task_runner);
+ channel_proxy_ = IPC::ChannelProxy::Create(
+ CreateChannelFactory(GetChannelName(test_client_name_),
+ ipc_task_runner.get()),
+ listener,
+ ipc_task_runner);
}
void IPCTestBase::DestroyChannelProxy() {
@@ -135,3 +137,9 @@ bool IPCTestBase::WaitForClientShutdown() {
scoped_refptr<base::TaskRunner> IPCTestBase::task_runner() {
return message_loop_->message_loop_proxy();
}
+
+scoped_ptr<IPC::ChannelFactory> IPCTestBase::CreateChannelFactory(
+ const IPC::ChannelHandle& handle,
+ base::TaskRunner* runner) {
+ return IPC::ChannelFactory::Create(handle, IPC::Channel::MODE_SERVER);
+}
diff --git a/ipc/ipc_test_base.h b/ipc/ipc_test_base.h
index ff34945..8fdcbb0 100644
--- a/ipc/ipc_test_base.h
+++ b/ipc/ipc_test_base.h
@@ -12,6 +12,7 @@
#include "base/process/process.h"
#include "base/test/multiprocess_test.h"
#include "ipc/ipc_channel.h"
+#include "ipc/ipc_channel_factory.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_multiprocess_test.h"
@@ -95,6 +96,9 @@ class IPCTestBase : public base::MultiProcessTest {
const base::ProcessHandle& client_process() const { return client_process_; }
scoped_refptr<base::TaskRunner> task_runner();
+ virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
+ const IPC::ChannelHandle& handle, base::TaskRunner* runner);
+
private:
std::string test_client_name_;
scoped_ptr<base::MessageLoop> message_loop_;
diff --git a/ipc/mojo/BUILD.gn b/ipc/mojo/BUILD.gn
index d059b48..58c1f03 100644
--- a/ipc/mojo/BUILD.gn
+++ b/ipc/mojo/BUILD.gn
@@ -40,3 +40,22 @@ test("ipc_mojo_unittests") {
"//url",
]
}
+
+test("ipc_mojo_perftests") {
+ sources = [
+ "ipc_mojo_perftest.cc",
+ ]
+
+ deps = [
+ "//base",
+ "//base/test:test_support",
+ "//base/test:test_support_perf",
+ "//base/third_party/dynamic_annotations",
+ "//ipc",
+ "//ipc:test_support",
+ "//ipc/mojo",
+ "//mojo/environment:chromium",
+ "//mojo/system",
+ "//url",
+ ]
+}
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index 88034f1..cdb9281 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -456,19 +456,11 @@ void ChannelMojo::ChannelInfoDeleter::operator()(
// static
scoped_ptr<ChannelMojo> ChannelMojo::Create(
- scoped_ptr<Channel> bootstrap, Mode mode, Listener* listener,
- scoped_refptr<base::TaskRunner> io_thread_task_runner) {
- return make_scoped_ptr(new ChannelMojo(
- bootstrap.Pass(), mode, listener, io_thread_task_runner));
-}
-
-// static
-scoped_ptr<ChannelMojo> ChannelMojo::Create(
const ChannelHandle &channel_handle, Mode mode, Listener* listener,
scoped_refptr<base::TaskRunner> io_thread_task_runner) {
- return Create(
+ return make_scoped_ptr(new ChannelMojo(
Channel::Create(channel_handle, mode, g_null_listener.Pointer()),
- mode, listener, io_thread_task_runner);
+ mode, listener, io_thread_task_runner));
}
// static
diff --git a/ipc/mojo/ipc_channel_mojo.h b/ipc/mojo/ipc_channel_mojo.h
index 4d4df63..dd57bc8 100644
--- a/ipc/mojo/ipc_channel_mojo.h
+++ b/ipc/mojo/ipc_channel_mojo.h
@@ -50,11 +50,6 @@ namespace IPC {
//
class IPC_MOJO_EXPORT ChannelMojo : public Channel {
public:
- // Create ChannelMojo on top of given |bootstrap| channel.
- static scoped_ptr<ChannelMojo> Create(
- scoped_ptr<Channel> bootstrap, Mode mode, Listener* listener,
- scoped_refptr<base::TaskRunner> io_thread_task_runner);
-
// Create ChannelMojo. A bootstrap channel is created as well.
static scoped_ptr<ChannelMojo> Create(
const ChannelHandle &channel_handle, Mode mode, Listener* listener,
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc
index 60069b7..8ea828f 100644
--- a/ipc/mojo/ipc_channel_mojo_unittest.cc
+++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -55,33 +55,11 @@ class ListenerThatExpectsOK : public IPC::Listener {
bool received_ok_;
};
-class ListenerThatShouldBeNeverCalled : public IPC::Listener {
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
- NOTREACHED();
- return true;
- }
-
- virtual void OnChannelError() OVERRIDE {
- NOTREACHED();
- }
-
- virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void OnBadMessageReceived(const IPC::Message& message) OVERRIDE {
- NOTREACHED();
- }
-};
-
class ChannelClient {
public:
explicit ChannelClient(IPC::Listener* listener, const char* name) {
- scoped_ptr<IPC::Channel> bootstrap(IPC::Channel::CreateClient(
- IPCTestBase::GetChannelName(name),
- &never_called_));
channel_ = IPC::ChannelMojo::Create(
- bootstrap.Pass(), IPC::Channel::MODE_CLIENT, listener,
+ IPCTestBase::GetChannelName(name), IPC::Channel::MODE_CLIENT, listener,
main_message_loop_.message_loop_proxy());
}
@@ -93,31 +71,20 @@ class ChannelClient {
private:
scoped_ptr<IPC::ChannelMojo> channel_;
- ListenerThatShouldBeNeverCalled never_called_;
base::MessageLoopForIO main_message_loop_;
};
class IPCChannelMojoTest : public IPCTestBase {
- public:
- void CreateMojoChannel(IPC::Listener* listener);
-
protected:
- virtual void SetUp() OVERRIDE {
- IPCTestBase::SetUp();
+ virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
+ const IPC::ChannelHandle& handle,
+ base::TaskRunner* runner) OVERRIDE {
+ return IPC::ChannelMojo::CreateFactory(
+ handle, IPC::Channel::MODE_SERVER, runner);
}
-
- ListenerThatShouldBeNeverCalled never_called_;
};
-void IPCChannelMojoTest::CreateMojoChannel(IPC::Listener* listener) {
- CreateChannel(&never_called_);
- scoped_ptr<IPC::Channel> mojo_channel = IPC::ChannelMojo::Create(
- ReleaseChannel(), IPC::Channel::MODE_SERVER, listener,
- task_runner()).PassAs<IPC::Channel>();
- SetChannel(mojo_channel.PassAs<IPC::Channel>());
-}
-
class TestChannelListenerWithExtraExpectations
: public IPC::TestChannelListener {
public:
@@ -142,7 +109,7 @@ TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
// Set up IPC channel and start client.
TestChannelListenerWithExtraExpectations listener;
- CreateMojoChannel(&listener);
+ CreateChannel(&listener);
listener.Init(sender());
ASSERT_TRUE(ConnectChannel());
ASSERT_TRUE(StartClient());
@@ -236,7 +203,7 @@ TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
Init("IPCChannelMojoTestSendPlatformHandleClient");
ListenerThatExpectsOK listener;
- CreateMojoChannel(&listener);
+ CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
ASSERT_TRUE(StartClient());
diff --git a/ipc/mojo/ipc_mojo.gyp b/ipc/mojo/ipc_mojo.gyp
index c408a17..f01d48f 100644
--- a/ipc/mojo/ipc_mojo.gyp
+++ b/ipc/mojo/ipc_mojo.gyp
@@ -64,5 +64,30 @@
'conditions': [
],
},
+ {
+ 'target_name': 'ipc_mojo_perftests',
+ 'type': '<(gtest_target_type)',
+ 'dependencies': [
+ '../ipc.gyp:ipc',
+ '../ipc.gyp:test_support_ipc',
+ '../../base/base.gyp:base',
+ '../../base/base.gyp:base_i18n',
+ '../../base/base.gyp:test_support_base',
+ '../../base/base.gyp:test_support_perf',
+ '../../mojo/mojo_base.gyp:mojo_cpp_bindings',
+ '../../mojo/mojo_base.gyp:mojo_environment_chromium',
+ '../../mojo/mojo_base.gyp:mojo_system_impl',
+ '../../testing/gtest.gyp:gtest',
+ 'ipc_mojo',
+ ],
+ 'include_dirs': [
+ '..'
+ ],
+ 'sources': [
+ 'ipc_mojo_perftest.cc',
+ ],
+ 'conditions': [
+ ],
+ },
],
}
diff --git a/ipc/mojo/ipc_mojo_perftest.cc b/ipc/mojo/ipc_mojo_perftest.cc
new file mode 100644
index 0000000..d433703
--- /dev/null
+++ b/ipc/mojo/ipc_mojo_perftest.cc
@@ -0,0 +1,87 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/lazy_instance.h"
+#include "ipc/ipc_perftest_support.h"
+#include "ipc/mojo/ipc_channel_mojo.h"
+#include "mojo/embedder/test_embedder.h"
+
+namespace {
+
+// This is needed because we rely on //base/test:test_support_perf and
+// it provides main() which doesn't have Mojo initialization. We need
+// some way to call InitWithSimplePlatformSupport() only once before
+// using Mojo.
+struct MojoInitialier {
+ MojoInitialier() {
+ mojo::embedder::test::InitWithSimplePlatformSupport();
+ }
+};
+
+base::LazyInstance<MojoInitialier> g_mojo_initializer
+ = LAZY_INSTANCE_INITIALIZER;
+
+class MojoChannelPerfTest : public IPC::test::IPCChannelPerfTestBase {
+public:
+ typedef IPC::test::IPCChannelPerfTestBase Super;
+
+ MojoChannelPerfTest();
+
+ virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
+ const IPC::ChannelHandle& handle,
+ base::TaskRunner* runner) OVERRIDE {
+ return IPC::ChannelMojo::CreateFactory(
+ handle, IPC::Channel::MODE_SERVER, runner);
+ }
+
+ void set_io_thread_task_runner(base::TaskRunner* runner) {
+ io_thread_task_runner_ = runner;
+ }
+
+ private:
+ base::TaskRunner* io_thread_task_runner_;
+};
+
+MojoChannelPerfTest::MojoChannelPerfTest()
+ : io_thread_task_runner_() {
+ g_mojo_initializer.Get();
+}
+
+
+TEST_F(MojoChannelPerfTest, ChannelPingPong) {
+ RunTestChannelPingPong(GetDefaultTestParams());
+}
+
+TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) {
+ RunTestChannelProxyPingPong(GetDefaultTestParams());
+}
+
+class MojoTestClient : public IPC::test::PingPongTestClient {
+ public:
+ typedef IPC::test::PingPongTestClient SuperType;
+
+ MojoTestClient();
+
+ virtual scoped_ptr<IPC::Channel> CreateChannel(
+ IPC::Listener* listener) OVERRIDE;
+};
+
+MojoTestClient::MojoTestClient() {
+ g_mojo_initializer.Get();
+}
+
+scoped_ptr<IPC::Channel> MojoTestClient::CreateChannel(
+ IPC::Listener* listener) {
+ return scoped_ptr<IPC::Channel>(IPC::ChannelMojo::Create(
+ IPCTestBase::GetChannelName("PerformanceClient"),
+ IPC::Channel::MODE_CLIENT, listener,
+ task_runner()));
+}
+
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) {
+ MojoTestClient client;
+ return client.RunMain();
+}
+
+} // namespace