From 0cb7d8c8ce8a7261743dbe613ad93495457dd174 Mon Sep 17 00:00:00 2001 From: "viettrungluu@chromium.org" Date: Fri, 11 Jan 2013 15:13:37 +0000 Subject: Make ipc_tests file structure a little saner and add an ipc_perftests target. This means that the (one, semi-manual) IPC perf test that we have will build without manual hackery (and do so separately from the ipc_tests target). Review URL: https://chromiumcodereview.appspot.com/11819041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176341 0039d316-1c4b-4281-b951-d872f2087c98 --- ipc/ipc.gyp | 49 +++- ipc/ipc_channel_unittest.cc | 336 ++++++++++++++++++++++++ ipc/ipc_fuzzing_tests.cc | 4 +- ipc/ipc_perftests.cc | 205 +++++++++++++++ ipc/ipc_send_fds_test.cc | 11 +- ipc/ipc_test_base.cc | 131 ++++++++++ ipc/ipc_test_base.h | 46 ++++ ipc/ipc_tests.cc | 615 -------------------------------------------- ipc/ipc_tests.h | 48 ---- ipc/sync_socket_unittest.cc | 4 +- 10 files changed, 775 insertions(+), 674 deletions(-) create mode 100644 ipc/ipc_channel_unittest.cc create mode 100644 ipc/ipc_perftests.cc create mode 100644 ipc/ipc_test_base.cc create mode 100644 ipc/ipc_test_base.h delete mode 100644 ipc/ipc_tests.cc delete mode 100644 ipc/ipc_tests.h (limited to 'ipc') diff --git a/ipc/ipc.gyp b/ipc/ipc.gyp index 678d166..c56f68a 100644 --- a/ipc/ipc.gyp +++ b/ipc/ipc.gyp @@ -37,6 +37,7 @@ 'test_support_ipc', '../base/base.gyp:base', '../base/base.gyp:base_i18n', + '../base/base.gyp:run_all_unittests', '../base/base.gyp:test_support_base', '../testing/gtest.gyp:gtest', ], @@ -46,6 +47,7 @@ 'sources': [ 'file_descriptor_set_posix_unittest.cc', 'ipc_channel_posix_unittest.cc', + 'ipc_channel_unittest.cc', 'ipc_fuzzing_tests.cc', 'ipc_message_unittest.cc', 'ipc_message_utils_unittest.cc', @@ -53,8 +55,8 @@ 'ipc_sync_channel_unittest.cc', 'ipc_sync_message_unittest.cc', 'ipc_sync_message_unittest.h', - 'ipc_tests.cc', - 'ipc_tests.h', + 'ipc_test_base.cc', + 'ipc_test_base.h', 'sync_socket_unittest.cc', ], 'conditions': [ @@ -80,6 +82,49 @@ ], }, { + 'target_name': 'ipc_perftests', + 'type': '<(gtest_target_type)', + # TODO(viettrungluu): Figure out which dependencies are really needed. + 'dependencies': [ + 'ipc', + 'test_support_ipc', + '../base/base.gyp:base', + '../base/base.gyp:base_i18n', + '../base/base.gyp:test_support_base', + '../base/base.gyp:test_support_perf', + '../testing/gtest.gyp:gtest', + ], + 'include_dirs': [ + '..' + ], + 'sources': [ + 'ipc_perftests.cc', + 'ipc_test_base.cc', + 'ipc_test_base.h', + ], + 'conditions': [ + ['toolkit_uses_gtk == 1', { + 'dependencies': [ + '../build/linux/system.gyp:gtk', + ], + }], + ['OS == "android" and gtest_target_type == "shared_library"', { + 'dependencies': [ + '../testing/android/native_test.gyp:native_test_native_code', + ], + }], + ['os_posix == 1 and OS != "mac" and OS != "android"', { + 'conditions': [ + ['linux_use_tcmalloc==1', { + 'dependencies': [ + '../base/allocator/allocator.gyp:allocator', + ], + }], + ], + }] + ], + }, + { 'target_name': 'test_support_ipc', 'type': 'static_library', 'dependencies': [ diff --git a/ipc/ipc_channel_unittest.cc b/ipc/ipc_channel_unittest.cc new file mode 100644 index 0000000..6b63ae0 --- /dev/null +++ b/ipc/ipc_channel_unittest.cc @@ -0,0 +1,336 @@ +// 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 "build/build_config.h" + +#if defined(OS_WIN) +#include +#elif defined(OS_POSIX) +#include +#include +#endif + +#include +#include +#include + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/debug/debug_on_start_win.h" +#include "base/perftimer.h" +#include "base/pickle.h" +#include "base/test/perf_test_suite.h" +#include "base/test/test_suite.h" +#include "base/threading/thread.h" +#include "base/time.h" +#include "ipc/ipc_descriptors.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_message_utils.h" +#include "ipc/ipc_multiprocess_test.h" +#include "ipc/ipc_sender.h" +#include "ipc/ipc_switches.h" +#include "ipc/ipc_test_base.h" +#include "testing/multiprocess_func_list.h" + +const size_t kLongMessageStringNumBytes = 50000; + +class IPCChannelTest : public IPCTestBase { +}; + +TEST_F(IPCChannelTest, BasicMessageTest) { + int v1 = 10; + std::string v2("foobar"); + std::wstring v3(L"hello world"); + + IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); + EXPECT_TRUE(m.WriteInt(v1)); + EXPECT_TRUE(m.WriteString(v2)); + EXPECT_TRUE(m.WriteWString(v3)); + + PickleIterator iter(m); + + int vi; + std::string vs; + std::wstring vw; + + EXPECT_TRUE(m.ReadInt(&iter, &vi)); + EXPECT_EQ(v1, vi); + + EXPECT_TRUE(m.ReadString(&iter, &vs)); + EXPECT_EQ(v2, vs); + + EXPECT_TRUE(m.ReadWString(&iter, &vw)); + EXPECT_EQ(v3, vw); + + // should fail + EXPECT_FALSE(m.ReadInt(&iter, &vi)); + EXPECT_FALSE(m.ReadString(&iter, &vs)); + EXPECT_FALSE(m.ReadWString(&iter, &vw)); +} + +static void Send(IPC::Sender* sender, const char* text) { + static int message_index = 0; + + IPC::Message* message = new IPC::Message(0, + 2, + IPC::Message::PRIORITY_NORMAL); + message->WriteInt(message_index++); + message->WriteString(std::string(text)); + + // Make sure we can handle large messages. + char junk[kLongMessageStringNumBytes]; + memset(junk, 'a', sizeof(junk)-1); + junk[sizeof(junk)-1] = 0; + message->WriteString(std::string(junk)); + + // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text); + sender->Send(message); +} + +class MyChannelListener : public IPC::Listener { + public: + virtual bool OnMessageReceived(const IPC::Message& message) { + PickleIterator iter(message); + + int ignored; + EXPECT_TRUE(iter.ReadInt(&ignored)); + std::string data; + EXPECT_TRUE(iter.ReadString(&data)); + std::string big_string; + EXPECT_TRUE(iter.ReadString(&big_string)); + EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length()); + + + if (--messages_left_ == 0) { + MessageLoop::current()->Quit(); + } else { + Send(sender_, "Foo"); + } + return true; + } + + virtual void OnChannelError() { + // There is a race when closing the channel so the last message may be lost. + EXPECT_LE(messages_left_, 1); + MessageLoop::current()->Quit(); + } + + void Init(IPC::Sender* s) { + sender_ = s; + messages_left_ = 50; + } + + private: + IPC::Sender* sender_; + int messages_left_; +}; + +TEST_F(IPCChannelTest, ChannelTest) { + MyChannelListener channel_listener; + // Setup IPC channel. + IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, + &channel_listener); + ASSERT_TRUE(chan.Connect()); + + channel_listener.Init(&chan); + + base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan); + ASSERT_TRUE(process_handle); + + Send(&chan, "hello from parent"); + + // Run message loop. + MessageLoop::current()->Run(); + + // Close Channel so client gets its OnChannelError() callback fired. + chan.Close(); + + // Cleanup child process. + EXPECT_TRUE(base::WaitForSingleProcess( + process_handle, base::TimeDelta::FromSeconds(5))); + base::CloseProcessHandle(process_handle); +} + +#if defined(OS_WIN) +TEST_F(IPCChannelTest, ChannelTestExistingPipe) { + MyChannelListener channel_listener; + // Setup IPC channel with existing pipe. Specify name in Chrome format. + std::string name("\\\\.\\pipe\\chrome."); + name.append(kTestClientChannel); + const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | + FILE_FLAG_FIRST_PIPE_INSTANCE; + HANDLE pipe = CreateNamedPipeA(name.c_str(), + open_mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, + 1, + 4096, + 4096, + 5000, + NULL); + IPC::Channel chan(IPC::ChannelHandle(pipe), IPC::Channel::MODE_SERVER, + &channel_listener); + // Channel will duplicate the handle. + CloseHandle(pipe); + ASSERT_TRUE(chan.Connect()); + + channel_listener.Init(&chan); + + base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan); + ASSERT_TRUE(process_handle); + + Send(&chan, "hello from parent"); + + // Run message loop. + MessageLoop::current()->Run(); + + // Close Channel so client gets its OnChannelError() callback fired. + chan.Close(); + + // Cleanup child process. + EXPECT_TRUE(base::WaitForSingleProcess( + process_handle, base::TimeDelta::FromSeconds(5))); + base::CloseProcessHandle(process_handle); +} +#endif // defined (OS_WIN) + +TEST_F(IPCChannelTest, ChannelProxyTest) { + MyChannelListener channel_listener; + + // The thread needs to out-live the ChannelProxy. + base::Thread thread("ChannelProxyTestServer"); + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_IO; + thread.StartWithOptions(options); + { + // setup IPC channel proxy + IPC::ChannelProxy chan(kTestClientChannel, IPC::Channel::MODE_SERVER, + &channel_listener, thread.message_loop_proxy()); + + channel_listener.Init(&chan); + +#if defined(OS_WIN) + base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, NULL); +#elif defined(OS_POSIX) + bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDebugChildren); + base::FileHandleMappingVector fds_to_map; + const int ipcfd = chan.GetClientFileDescriptor(); + if (ipcfd > -1) { + fds_to_map.push_back(std::pair(ipcfd, kPrimaryIPCChannel + 3)); + } + + base::ProcessHandle process_handle = MultiProcessTest::SpawnChild( + "RunTestClient", + fds_to_map, + debug_on_start); +#endif // defined(OS_POSIX) + + ASSERT_TRUE(process_handle); + + Send(&chan, "hello from parent"); + + // run message loop + MessageLoop::current()->Run(); + + // cleanup child process + EXPECT_TRUE(base::WaitForSingleProcess( + process_handle, base::TimeDelta::FromSeconds(5))); + base::CloseProcessHandle(process_handle); + } + thread.Stop(); +} + +class ChannelListenerWithOnConnectedSend : public IPC::Listener { + public: + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { + SendNextMessage(); + } + + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { + PickleIterator iter(message); + + int ignored; + EXPECT_TRUE(iter.ReadInt(&ignored)); + std::string data; + EXPECT_TRUE(iter.ReadString(&data)); + std::string big_string; + EXPECT_TRUE(iter.ReadString(&big_string)); + EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length()); + SendNextMessage(); + return true; + } + + virtual void OnChannelError() OVERRIDE { + // There is a race when closing the channel so the last message may be lost. + EXPECT_LE(messages_left_, 1); + MessageLoop::current()->Quit(); + } + + void Init(IPC::Sender* s) { + sender_ = s; + messages_left_ = 50; + } + + private: + void SendNextMessage() { + if (--messages_left_ == 0) { + MessageLoop::current()->Quit(); + } else { + Send(sender_, "Foo"); + } + } + + IPC::Sender* sender_; + int messages_left_; +}; + +#if defined(OS_WIN) +// Acting flakey in Windows. http://crbug.com/129595 +#define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnected +#else +#define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected +#endif +TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) { + // This tests the case of a listener sending back an event in it's + // OnChannelConnected handler. + + ChannelListenerWithOnConnectedSend channel_listener; + // Setup IPC channel. + IPC::Channel channel(kTestClientChannel, IPC::Channel::MODE_SERVER, + &channel_listener); + channel_listener.Init(&channel); + ASSERT_TRUE(channel.Connect()); + + base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &channel); + ASSERT_TRUE(process_handle); + + Send(&channel, "hello from parent"); + + // Run message loop. + MessageLoop::current()->Run(); + + // Close Channel so client gets its OnChannelError() callback fired. + channel.Close(); + + // Cleanup child process. + EXPECT_TRUE(base::WaitForSingleProcess( + process_handle, base::TimeDelta::FromSeconds(5))); + base::CloseProcessHandle(process_handle); +} + +MULTIPROCESS_IPC_TEST_MAIN(RunTestClient) { + MessageLoopForIO main_message_loop; + MyChannelListener channel_listener; + + // setup IPC channel + IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, + &channel_listener); + CHECK(chan.Connect()); + channel_listener.Init(&chan); + Send(&chan, "hello from child"); + // run message loop + MessageLoop::current()->Run(); + return 0; +} diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc index 4c3e9c9..82ac37f 100644 --- a/ipc/ipc_fuzzing_tests.cc +++ b/ipc/ipc_fuzzing_tests.cc @@ -12,7 +12,7 @@ #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_multiprocess_test.h" -#include "ipc/ipc_tests.h" +#include "ipc/ipc_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" @@ -257,7 +257,7 @@ MULTIPROCESS_IPC_TEST_MAIN(RunFuzzServer) { return 0; } -class IPCFuzzingTest : public IPCChannelTest { +class IPCFuzzingTest : public IPCTestBase { }; // This test makes sure that the FuzzerClientListener and FuzzerServerListener diff --git a/ipc/ipc_perftests.cc b/ipc/ipc_perftests.cc new file mode 100644 index 0000000..b290c16 --- /dev/null +++ b/ipc/ipc_perftests.cc @@ -0,0 +1,205 @@ +// 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 "build/build_config.h" + +#if defined(OS_WIN) +#include +#elif defined(OS_POSIX) +#include +#include +#endif + +#include +#include +#include + +#include "ipc/ipc_test_base.h" + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/debug/debug_on_start_win.h" +#include "base/perftimer.h" +#include "base/pickle.h" +#include "base/test/perf_test_suite.h" +#include "base/threading/thread.h" +#include "base/time.h" +#include "ipc/ipc_descriptors.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_message_utils.h" +#include "ipc/ipc_multiprocess_test.h" +#include "ipc/ipc_sender.h" +#include "ipc/ipc_switches.h" +#include "testing/multiprocess_func_list.h" + +// This test times the roundtrip IPC message cycle. It is enabled with a +// special preprocessor define to enable it instead of the standard IPC +// unit tests. This works around some funny termination conditions in the +// regular unit tests. +// +// This test is not automated. To test, you will want to vary the message +// count and message size in TEST to get the numbers you want. +// +// FIXME(brettw): Automate this test and have it run by default. + +class IPCChannelPerfTest : public IPCTestBase { +}; + +// 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: + explicit ChannelReflectorListener(IPC::Channel *channel) : + channel_(channel), + count_messages_(0) { + std::cout << "Reflector up" << std::endl; + } + + ~ChannelReflectorListener() { + std::cout << "Client Messages: " << count_messages_ << std::endl; + std::cout << "Client Latency: " << latency_messages_.InMilliseconds() + << std::endl; + } + + virtual bool OnMessageReceived(const IPC::Message& message) { + count_messages_++; + 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)); + // TODO(vtl): Should we use |HighResNow()| instead of |Now()|? + latency_messages_ += base::TimeTicks::Now() - + base::TimeTicks::FromInternalValue(time_internal); + + // cout << "reflector msg received: " << msgid << endl; + if (payload == "quit") + MessageLoop::current()->Quit(); + + 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_; + int count_messages_; + base::TimeDelta latency_messages_; +}; + +class ChannelPerfListener : public IPC::Listener { + public: + ChannelPerfListener(IPC::Channel* channel, int msg_count, int msg_size) : + count_down_(msg_count), + channel_(channel), + count_messages_(0) { + payload_.resize(msg_size); + for (int i = 0; i < static_cast(payload_.size()); i++) + payload_[i] = 'a'; + std::cout << "perflistener up" << std::endl; + } + + ~ChannelPerfListener() { + std::cout << "Server Messages: " << count_messages_ << std::endl; + std::cout << "Server Latency: " << latency_messages_.InMilliseconds() + << std::endl; + } + + virtual bool OnMessageReceived(const IPC::Message& message) { + count_messages_++; + // Decode the string so this gets counted in the total time. + PickleIterator iter(message); + int64 time_internal; + EXPECT_TRUE(iter.ReadInt64(&time_internal)); + int msgid; + EXPECT_TRUE(iter.ReadInt(&msgid)); + std::string cur; + EXPECT_TRUE(iter.ReadString(&cur)); + latency_messages_ += base::TimeTicks::Now() - + base::TimeTicks::FromInternalValue(time_internal); + + count_down_--; + if (count_down_ == 0) { + IPC::Message* msg = new IPC::Message(0, + 2, + IPC::Message::PRIORITY_NORMAL); + msg->WriteInt64(base::TimeTicks::Now().ToInternalValue()); + msg->WriteInt(count_down_); + msg->WriteString("quit"); + channel_->Send(msg); + + 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_); + channel_->Send(msg); + return true; + } + + private: + int count_down_; + std::string payload_; + IPC::Channel *channel_; + int count_messages_; + base::TimeDelta latency_messages_; +}; + +TEST_F(IPCChannelPerfTest, Performance) { + // setup IPC channel + IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_SERVER, NULL); + ChannelPerfListener perf_listener(&chan, 10000, 100000); + chan.set_listener(&perf_listener); + ASSERT_TRUE(chan.Connect()); + + base::ProcessHandle process_handle = SpawnChild(TEST_REFLECTOR, &chan); + ASSERT_TRUE(process_handle); + + base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); + + PerfTimeLogger logger("IPC_Perf"); + + // 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"); + chan.Send(message); + + // run message loop + MessageLoop::current()->Run(); + + // Clean up child process. + EXPECT_TRUE(base::WaitForSingleProcess( + process_handle, base::TimeDelta::FromSeconds(5))); + base::CloseProcessHandle(process_handle); +} + +// This message loop bounces all messages back to the sender +MULTIPROCESS_IPC_TEST_MAIN(RunReflector) { + MessageLoopForIO main_message_loop; + IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_CLIENT, NULL); + ChannelReflectorListener channel_reflector_listener(&chan); + chan.set_listener(&channel_reflector_listener); + CHECK(chan.Connect()); + + MessageLoop::current()->Run(); + return 0; +} diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc index 6679088..06a4660 100644 --- a/ipc/ipc_send_fds_test.cc +++ b/ipc/ipc_send_fds_test.cc @@ -4,8 +4,6 @@ #include "build/build_config.h" -#include "ipc/ipc_tests.h" - #if defined(OS_MACOSX) extern "C" { #include @@ -20,6 +18,7 @@ extern "C" { #include "ipc/ipc_listener.h" #include "ipc/ipc_message_utils.h" #include "ipc/ipc_multiprocess_test.h" +#include "ipc/ipc_test_base.h" #include "testing/multiprocess_func_list.h" #if defined(OS_POSIX) @@ -132,7 +131,9 @@ int TestDescriptorClient(ino_t expected_inode_num) { } // namespace -// --------------------------------------------------------------------------- +class IPCSendFdsTest : public IPCTestBase { +}; + #if defined(OS_MACOSX) // TODO(port): Make this test cross-platform. MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClientSandboxed) { @@ -165,7 +166,7 @@ MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClientSandboxed) { } // Test that FDs are correctly sent to a sandboxed process. -TEST_F(IPCChannelTest, DescriptorTestSandboxed) { +TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { // Setup IPC channel. MyChannelDescriptorListener listener(-1); @@ -189,7 +190,7 @@ MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClient) { return TestDescriptorClient(st.st_ino); } -TEST_F(IPCChannelTest, DescriptorTest) { +TEST_F(IPCSendFdsTest, DescriptorTest) { // Setup IPC channel. MyChannelDescriptorListener listener(-1); diff --git a/ipc/ipc_test_base.cc b/ipc/ipc_test_base.cc new file mode 100644 index 0000000..2d68a76 --- /dev/null +++ b/ipc/ipc_test_base.cc @@ -0,0 +1,131 @@ +// 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 "build/build_config.h" + +#if defined(OS_WIN) +#include +#elif defined(OS_POSIX) +#include +#include +#endif + +#include +#include +#include + +#include "ipc/ipc_test_base.h" + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/debug/debug_on_start_win.h" +#include "base/perftimer.h" +#include "base/pickle.h" +#include "base/test/perf_test_suite.h" +#include "base/test/test_suite.h" +#include "base/threading/thread.h" +#include "base/time.h" +#include "ipc/ipc_descriptors.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_message_utils.h" +#include "ipc/ipc_multiprocess_test.h" +#include "ipc/ipc_sender.h" +#include "ipc/ipc_switches.h" +#include "testing/multiprocess_func_list.h" + +// Define to enable IPC performance testing instead of the regular unit tests +// #define PERFORMANCE_TEST + +const char kTestClientChannel[] = "T1"; +const char kReflectorChannel[] = "T2"; +const char kFuzzerChannel[] = "F3"; +const char kSyncSocketChannel[] = "S4"; + +void IPCTestBase::SetUp() { + MultiProcessTest::SetUp(); + + // Construct a fresh IO Message loop for the duration of each test. + message_loop_ = new MessageLoopForIO(); +} + +void IPCTestBase::TearDown() { + delete message_loop_; + message_loop_ = NULL; + + MultiProcessTest::TearDown(); +} + +#if defined(OS_WIN) +base::ProcessHandle IPCTestBase::SpawnChild(IPCTestBase::ChildType child_type, + IPC::Channel *channel) { + // kDebugChildren support. + bool debug_on_start = + CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren); + + switch (child_type) { + case TEST_CLIENT: + return MultiProcessTest::SpawnChild("RunTestClient", debug_on_start); + case TEST_REFLECTOR: + return MultiProcessTest::SpawnChild("RunReflector", debug_on_start); + case FUZZER_SERVER: + return MultiProcessTest::SpawnChild("RunFuzzServer", debug_on_start); + case SYNC_SOCKET_SERVER: + return MultiProcessTest::SpawnChild("RunSyncSocketServer", debug_on_start); + default: + return NULL; + } +} +#elif defined(OS_POSIX) +base::ProcessHandle IPCTestBase::SpawnChild(IPCTestBase::ChildType child_type, + IPC::Channel *channel) { + // kDebugChildren support. + bool debug_on_start = + CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren); + + base::FileHandleMappingVector fds_to_map; + const int ipcfd = channel->GetClientFileDescriptor(); + if (ipcfd > -1) { + fds_to_map.push_back(std::pair(ipcfd, kPrimaryIPCChannel + 3)); + } + + base::ProcessHandle ret = base::kNullProcessHandle; + switch (child_type) { + case TEST_CLIENT: + ret = MultiProcessTest::SpawnChild("RunTestClient", + fds_to_map, + debug_on_start); + break; + case TEST_DESCRIPTOR_CLIENT: + ret = MultiProcessTest::SpawnChild("RunTestDescriptorClient", + fds_to_map, + debug_on_start); + break; + case TEST_DESCRIPTOR_CLIENT_SANDBOXED: + ret = MultiProcessTest::SpawnChild("RunTestDescriptorClientSandboxed", + fds_to_map, + debug_on_start); + break; + case TEST_REFLECTOR: + ret = MultiProcessTest::SpawnChild("RunReflector", + fds_to_map, + debug_on_start); + break; + case FUZZER_SERVER: + ret = MultiProcessTest::SpawnChild("RunFuzzServer", + fds_to_map, + debug_on_start); + break; + case SYNC_SOCKET_SERVER: + ret = MultiProcessTest::SpawnChild("RunSyncSocketServer", + fds_to_map, + debug_on_start); + break; + default: + return base::kNullProcessHandle; + break; + } + return ret; +} +#endif // defined(OS_POSIX) diff --git a/ipc/ipc_test_base.h b/ipc/ipc_test_base.h new file mode 100644 index 0000000..08d410c --- /dev/null +++ b/ipc/ipc_test_base.h @@ -0,0 +1,46 @@ +// Copyright (c) 2011 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_TEST_BASE_H_ +#define IPC_IPC_TEST_BASE_H_ + +#include "base/process.h" +#include "base/test/multiprocess_test.h" + +// The different channel names for the child processes. +extern const char kTestClientChannel[]; +extern const char kReflectorChannel[]; +extern const char kFuzzerChannel[]; +extern const char kSyncSocketChannel[]; + +class MessageLoopForIO; +namespace IPC { +class Channel; +} // namespace IPC + +// Base class to facilitate spawning IPC client processes. +class IPCTestBase : public base::MultiProcessTest { + public: + enum ChildType { + TEST_CLIENT, + TEST_DESCRIPTOR_CLIENT, + TEST_DESCRIPTOR_CLIENT_SANDBOXED, + TEST_REFLECTOR, + FUZZER_SERVER, + SYNC_SOCKET_SERVER + }; + + protected: + // Create a new MessageLoopForIO for each test. + virtual void SetUp() OVERRIDE; + virtual void TearDown() OVERRIDE; + + // Spawns a child process of the specified type + base::ProcessHandle SpawnChild(ChildType child_type, IPC::Channel* channel); + + // Created around each test instantiation. + MessageLoopForIO* message_loop_; +}; + +#endif // IPC_IPC_TEST_BASE_H_ diff --git a/ipc/ipc_tests.cc b/ipc/ipc_tests.cc deleted file mode 100644 index 81d6716..0000000 --- a/ipc/ipc_tests.cc +++ /dev/null @@ -1,615 +0,0 @@ -// 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 "build/build_config.h" - -#if defined(OS_WIN) -#include -#elif defined(OS_POSIX) -#include -#include -#endif - -#include -#include -#include - -#include "ipc/ipc_tests.h" - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/debug/debug_on_start_win.h" -#include "base/perftimer.h" -#include "base/pickle.h" -#include "base/test/perf_test_suite.h" -#include "base/test/test_suite.h" -#include "base/threading/thread.h" -#include "base/time.h" -#include "ipc/ipc_descriptors.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_message_utils.h" -#include "ipc/ipc_multiprocess_test.h" -#include "ipc/ipc_sender.h" -#include "ipc/ipc_switches.h" -#include "testing/multiprocess_func_list.h" - -// Define to enable IPC performance testing instead of the regular unit tests -// #define PERFORMANCE_TEST - -const char kTestClientChannel[] = "T1"; -const char kReflectorChannel[] = "T2"; -const char kFuzzerChannel[] = "F3"; -const char kSyncSocketChannel[] = "S4"; - -const size_t kLongMessageStringNumBytes = 50000; - -void IPCChannelTest::SetUp() { - MultiProcessTest::SetUp(); - - // Construct a fresh IO Message loop for the duration of each test. - message_loop_ = new MessageLoopForIO(); -} - -void IPCChannelTest::TearDown() { - delete message_loop_; - message_loop_ = NULL; - - MultiProcessTest::TearDown(); -} - -#if defined(OS_WIN) -base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type, - IPC::Channel *channel) { - // kDebugChildren support. - bool debug_on_start = - CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren); - - switch (child_type) { - case TEST_CLIENT: - return MultiProcessTest::SpawnChild("RunTestClient", debug_on_start); - case TEST_REFLECTOR: - return MultiProcessTest::SpawnChild("RunReflector", debug_on_start); - case FUZZER_SERVER: - return MultiProcessTest::SpawnChild("RunFuzzServer", debug_on_start); - case SYNC_SOCKET_SERVER: - return MultiProcessTest::SpawnChild("RunSyncSocketServer", debug_on_start); - default: - return NULL; - } -} -#elif defined(OS_POSIX) -base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type, - IPC::Channel *channel) { - // kDebugChildren support. - bool debug_on_start = - CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren); - - base::FileHandleMappingVector fds_to_map; - const int ipcfd = channel->GetClientFileDescriptor(); - if (ipcfd > -1) { - fds_to_map.push_back(std::pair(ipcfd, kPrimaryIPCChannel + 3)); - } - - base::ProcessHandle ret = base::kNullProcessHandle; - switch (child_type) { - case TEST_CLIENT: - ret = MultiProcessTest::SpawnChild("RunTestClient", - fds_to_map, - debug_on_start); - break; - case TEST_DESCRIPTOR_CLIENT: - ret = MultiProcessTest::SpawnChild("RunTestDescriptorClient", - fds_to_map, - debug_on_start); - break; - case TEST_DESCRIPTOR_CLIENT_SANDBOXED: - ret = MultiProcessTest::SpawnChild("RunTestDescriptorClientSandboxed", - fds_to_map, - debug_on_start); - break; - case TEST_REFLECTOR: - ret = MultiProcessTest::SpawnChild("RunReflector", - fds_to_map, - debug_on_start); - break; - case FUZZER_SERVER: - ret = MultiProcessTest::SpawnChild("RunFuzzServer", - fds_to_map, - debug_on_start); - break; - case SYNC_SOCKET_SERVER: - ret = MultiProcessTest::SpawnChild("RunSyncSocketServer", - fds_to_map, - debug_on_start); - break; - default: - return base::kNullProcessHandle; - break; - } - return ret; -} -#endif // defined(OS_POSIX) - -#ifndef PERFORMANCE_TEST -TEST_F(IPCChannelTest, BasicMessageTest) { - int v1 = 10; - std::string v2("foobar"); - std::wstring v3(L"hello world"); - - IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); - EXPECT_TRUE(m.WriteInt(v1)); - EXPECT_TRUE(m.WriteString(v2)); - EXPECT_TRUE(m.WriteWString(v3)); - - PickleIterator iter(m); - - int vi; - std::string vs; - std::wstring vw; - - EXPECT_TRUE(m.ReadInt(&iter, &vi)); - EXPECT_EQ(v1, vi); - - EXPECT_TRUE(m.ReadString(&iter, &vs)); - EXPECT_EQ(v2, vs); - - EXPECT_TRUE(m.ReadWString(&iter, &vw)); - EXPECT_EQ(v3, vw); - - // should fail - EXPECT_FALSE(m.ReadInt(&iter, &vi)); - EXPECT_FALSE(m.ReadString(&iter, &vs)); - EXPECT_FALSE(m.ReadWString(&iter, &vw)); -} - -static void Send(IPC::Sender* sender, const char* text) { - static int message_index = 0; - - IPC::Message* message = new IPC::Message(0, - 2, - IPC::Message::PRIORITY_NORMAL); - message->WriteInt(message_index++); - message->WriteString(std::string(text)); - - // Make sure we can handle large messages. - char junk[kLongMessageStringNumBytes]; - memset(junk, 'a', sizeof(junk)-1); - junk[sizeof(junk)-1] = 0; - message->WriteString(std::string(junk)); - - // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text); - sender->Send(message); -} - -class MyChannelListener : public IPC::Listener { - public: - virtual bool OnMessageReceived(const IPC::Message& message) { - PickleIterator iter(message); - - int ignored; - EXPECT_TRUE(iter.ReadInt(&ignored)); - std::string data; - EXPECT_TRUE(iter.ReadString(&data)); - std::string big_string; - EXPECT_TRUE(iter.ReadString(&big_string)); - EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length()); - - - if (--messages_left_ == 0) { - MessageLoop::current()->Quit(); - } else { - Send(sender_, "Foo"); - } - return true; - } - - virtual void OnChannelError() { - // There is a race when closing the channel so the last message may be lost. - EXPECT_LE(messages_left_, 1); - MessageLoop::current()->Quit(); - } - - void Init(IPC::Sender* s) { - sender_ = s; - messages_left_ = 50; - } - - private: - IPC::Sender* sender_; - int messages_left_; -}; - -TEST_F(IPCChannelTest, ChannelTest) { - MyChannelListener channel_listener; - // Setup IPC channel. - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, - &channel_listener); - ASSERT_TRUE(chan.Connect()); - - channel_listener.Init(&chan); - - base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan); - ASSERT_TRUE(process_handle); - - Send(&chan, "hello from parent"); - - // Run message loop. - MessageLoop::current()->Run(); - - // Close Channel so client gets its OnChannelError() callback fired. - chan.Close(); - - // Cleanup child process. - EXPECT_TRUE(base::WaitForSingleProcess( - process_handle, base::TimeDelta::FromSeconds(5))); - base::CloseProcessHandle(process_handle); -} - -#if defined(OS_WIN) -TEST_F(IPCChannelTest, ChannelTestExistingPipe) { - MyChannelListener channel_listener; - // Setup IPC channel with existing pipe. Specify name in Chrome format. - std::string name("\\\\.\\pipe\\chrome."); - name.append(kTestClientChannel); - const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | - FILE_FLAG_FIRST_PIPE_INSTANCE; - HANDLE pipe = CreateNamedPipeA(name.c_str(), - open_mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, - 1, - 4096, - 4096, - 5000, - NULL); - IPC::Channel chan(IPC::ChannelHandle(pipe), IPC::Channel::MODE_SERVER, - &channel_listener); - // Channel will duplicate the handle. - CloseHandle(pipe); - ASSERT_TRUE(chan.Connect()); - - channel_listener.Init(&chan); - - base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan); - ASSERT_TRUE(process_handle); - - Send(&chan, "hello from parent"); - - // Run message loop. - MessageLoop::current()->Run(); - - // Close Channel so client gets its OnChannelError() callback fired. - chan.Close(); - - // Cleanup child process. - EXPECT_TRUE(base::WaitForSingleProcess( - process_handle, base::TimeDelta::FromSeconds(5))); - base::CloseProcessHandle(process_handle); -} -#endif // defined (OS_WIN) - -TEST_F(IPCChannelTest, ChannelProxyTest) { - MyChannelListener channel_listener; - - // The thread needs to out-live the ChannelProxy. - base::Thread thread("ChannelProxyTestServer"); - base::Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; - thread.StartWithOptions(options); - { - // setup IPC channel proxy - IPC::ChannelProxy chan(kTestClientChannel, IPC::Channel::MODE_SERVER, - &channel_listener, thread.message_loop_proxy()); - - channel_listener.Init(&chan); - -#if defined(OS_WIN) - base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, NULL); -#elif defined(OS_POSIX) - bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDebugChildren); - base::FileHandleMappingVector fds_to_map; - const int ipcfd = chan.GetClientFileDescriptor(); - if (ipcfd > -1) { - fds_to_map.push_back(std::pair(ipcfd, kPrimaryIPCChannel + 3)); - } - - base::ProcessHandle process_handle = MultiProcessTest::SpawnChild( - "RunTestClient", - fds_to_map, - debug_on_start); -#endif // defined(OS_POSIX) - - ASSERT_TRUE(process_handle); - - Send(&chan, "hello from parent"); - - // run message loop - MessageLoop::current()->Run(); - - // cleanup child process - EXPECT_TRUE(base::WaitForSingleProcess( - process_handle, base::TimeDelta::FromSeconds(5))); - base::CloseProcessHandle(process_handle); - } - thread.Stop(); -} - -class ChannelListenerWithOnConnectedSend : public IPC::Listener { - public: - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { - SendNextMessage(); - } - - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { - PickleIterator iter(message); - - int ignored; - EXPECT_TRUE(iter.ReadInt(&ignored)); - std::string data; - EXPECT_TRUE(iter.ReadString(&data)); - std::string big_string; - EXPECT_TRUE(iter.ReadString(&big_string)); - EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length()); - SendNextMessage(); - return true; - } - - virtual void OnChannelError() OVERRIDE { - // There is a race when closing the channel so the last message may be lost. - EXPECT_LE(messages_left_, 1); - MessageLoop::current()->Quit(); - } - - void Init(IPC::Sender* s) { - sender_ = s; - messages_left_ = 50; - } - - private: - void SendNextMessage() { - if (--messages_left_ == 0) { - MessageLoop::current()->Quit(); - } else { - Send(sender_, "Foo"); - } - } - - IPC::Sender* sender_; - int messages_left_; -}; - -#if defined(OS_WIN) -// Acting flakey in Windows. http://crbug.com/129595 -#define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnected -#else -#define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected -#endif -TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) { - // This tests the case of a listener sending back an event in it's - // OnChannelConnected handler. - - ChannelListenerWithOnConnectedSend channel_listener; - // Setup IPC channel. - IPC::Channel channel(kTestClientChannel, IPC::Channel::MODE_SERVER, - &channel_listener); - channel_listener.Init(&channel); - ASSERT_TRUE(channel.Connect()); - - base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &channel); - ASSERT_TRUE(process_handle); - - Send(&channel, "hello from parent"); - - // Run message loop. - MessageLoop::current()->Run(); - - // Close Channel so client gets its OnChannelError() callback fired. - channel.Close(); - - // Cleanup child process. - EXPECT_TRUE(base::WaitForSingleProcess( - process_handle, base::TimeDelta::FromSeconds(5))); - base::CloseProcessHandle(process_handle); -} - -MULTIPROCESS_IPC_TEST_MAIN(RunTestClient) { - MessageLoopForIO main_message_loop; - MyChannelListener channel_listener; - - // setup IPC channel - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, - &channel_listener); - CHECK(chan.Connect()); - channel_listener.Init(&chan); - Send(&chan, "hello from child"); - // run message loop - MessageLoop::current()->Run(); - return 0; -} - -#endif // !PERFORMANCE_TEST - -#ifdef PERFORMANCE_TEST - -//----------------------------------------------------------------------------- -// Manually performance test -// -// This test times the roundtrip IPC message cycle. It is enabled with a -// special preprocessor define to enable it instead of the standard IPC -// unit tests. This works around some funny termination conditions in the -// regular unit tests. -// -// This test is not automated. To test, you will want to vary the message -// count and message size in TEST to get the numbers you want. -// -// FIXME(brettw): Automate this test and have it run by default. - -// 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: - explicit ChannelReflectorListener(IPC::Channel *channel) : - channel_(channel), - count_messages_(0) { - std::cout << "Reflector up" << std::endl; - } - - ~ChannelReflectorListener() { - std::cout << "Client Messages: " << count_messages_ << std::endl; - std::cout << "Client Latency: " << latency_messages_.InMilliseconds() - << std::endl; - } - - virtual bool OnMessageReceived(const IPC::Message& message) { - count_messages_++; - 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)); - // TODO(vtl): Should we use |HighResNow()| instead of |Now()|? - latency_messages_ += base::TimeTicks::Now() - - base::TimeTicks::FromInternalValue(time_internal); - - // cout << "reflector msg received: " << msgid << endl; - if (payload == "quit") - MessageLoop::current()->Quit(); - - 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_; - int count_messages_; - base::TimeDelta latency_messages_; -}; - -class ChannelPerfListener : public IPC::Listener { - public: - ChannelPerfListener(IPC::Channel* channel, int msg_count, int msg_size) : - count_down_(msg_count), - channel_(channel), - count_messages_(0) { - payload_.resize(msg_size); - for (int i = 0; i < static_cast(payload_.size()); i++) - payload_[i] = 'a'; - std::cout << "perflistener up" << std::endl; - } - - ~ChannelPerfListener() { - std::cout << "Server Messages: " << count_messages_ << std::endl; - std::cout << "Server Latency: " << latency_messages_.InMilliseconds() - << std::endl; - } - - virtual bool OnMessageReceived(const IPC::Message& message) { - count_messages_++; - // Decode the string so this gets counted in the total time. - PickleIterator iter(message); - int64 time_internal; - EXPECT_TRUE(iter.ReadInt64(&time_internal)); - int msgid; - EXPECT_TRUE(iter.ReadInt(&msgid)); - std::string cur; - EXPECT_TRUE(iter.ReadString(&cur)); - latency_messages_ += base::TimeTicks::Now() - - base::TimeTicks::FromInternalValue(time_internal); - - count_down_--; - if (count_down_ == 0) { - IPC::Message* msg = new IPC::Message(0, - 2, - IPC::Message::PRIORITY_NORMAL); - msg->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - msg->WriteInt(count_down_); - msg->WriteString("quit"); - channel_->Send(msg); - - 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_); - channel_->Send(msg); - return true; - } - - private: - int count_down_; - std::string payload_; - IPC::Channel *channel_; - int count_messages_; - base::TimeDelta latency_messages_; -}; - -TEST_F(IPCChannelTest, Performance) { - // setup IPC channel - IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_SERVER, NULL); - ChannelPerfListener perf_listener(&chan, 10000, 100000); - chan.set_listener(&perf_listener); - ASSERT_TRUE(chan.Connect()); - - base::ProcessHandle process_handle = SpawnChild(TEST_REFLECTOR, &chan); - ASSERT_TRUE(process_handle); - - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); - - PerfTimeLogger logger("IPC_Perf"); - - // 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"); - chan.Send(message); - - // run message loop - MessageLoop::current()->Run(); - - // Clean up child process. - EXPECT_TRUE(base::WaitForSingleProcess( - process_handle, base::TimeDelta::FromSeconds(5))); - base::CloseProcessHandle(process_handle); -} - -// This message loop bounces all messages back to the sender -MULTIPROCESS_IPC_TEST_MAIN(RunReflector) { - MessageLoopForIO main_message_loop; - IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_CLIENT, NULL); - ChannelReflectorListener channel_reflector_listener(&chan); - chan.set_listener(&channel_reflector_listener); - CHECK(chan.Connect()); - - MessageLoop::current()->Run(); - return 0; -} - -#endif // PERFORMANCE_TEST - -int main(int argc, char** argv) { -#ifdef PERFORMANCE_TEST - int retval = base::PerfTestSuite(argc, argv).Run(); -#else - int retval = base::TestSuite(argc, argv).Run(); -#endif - return retval; -} diff --git a/ipc/ipc_tests.h b/ipc/ipc_tests.h deleted file mode 100644 index 76d274c..0000000 --- a/ipc/ipc_tests.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2011 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_TESTS_H_ -#define IPC_IPC_TESTS_H_ - -#include "base/test/multiprocess_test.h" -#include "base/process.h" - -// This unit test uses 3 types of child processes, a regular pipe client, -// a client reflector and a IPC server used for fuzzing tests. -enum ChildType { - TEST_CLIENT, - TEST_DESCRIPTOR_CLIENT, - TEST_DESCRIPTOR_CLIENT_SANDBOXED, - TEST_REFLECTOR, - FUZZER_SERVER, - SYNC_SOCKET_SERVER -}; - -// The different channel names for the child processes. -extern const char kTestClientChannel[]; -extern const char kReflectorChannel[]; -extern const char kFuzzerChannel[]; -extern const char kSyncSocketChannel[]; - -class MessageLoopForIO; -namespace IPC { -class Channel; -} // namespace IPC - -//Base class to facilitate Spawning IPC Client processes. -class IPCChannelTest : public base::MultiProcessTest { - protected: - - // Create a new MessageLoopForIO For each test. - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; - - // Spawns a child process of the specified type - base::ProcessHandle SpawnChild(ChildType child_type, IPC::Channel* channel); - - // Created around each test instantiation. - MessageLoopForIO* message_loop_; -}; - -#endif // IPC_IPC_TESTS_H_ diff --git a/ipc/sync_socket_unittest.cc b/ipc/sync_socket_unittest.cc index 69a2dca..a5cfc6b 100644 --- a/ipc/sync_socket_unittest.cc +++ b/ipc/sync_socket_unittest.cc @@ -14,7 +14,7 @@ #include "base/threading/thread.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_multiprocess_test.h" -#include "ipc/ipc_tests.h" +#include "ipc/ipc_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" @@ -164,7 +164,7 @@ class SyncSocketClientListener : public IPC::Listener { DISALLOW_COPY_AND_ASSIGN(SyncSocketClientListener); }; -class SyncSocketTest : public IPCChannelTest { +class SyncSocketTest : public IPCTestBase { }; TEST_F(SyncSocketTest, SanityTest) { -- cgit v1.1