Index: chrome/common/ipc_tests.cc |
diff --git a/chrome/common/ipc_tests.cc b/chrome/common/ipc_tests.cc |
index 695f0b4d0c19722a601dead50b0a280ed5259bfd..7dd5f0afcc14c22d1112a7bf7bc50ab8bed93458 100644 |
--- a/chrome/common/ipc_tests.cc |
+++ b/chrome/common/ipc_tests.cc |
@@ -20,6 +20,9 @@ |
#include "base/test_suite.h" |
#include "base/thread.h" |
#include "chrome/common/chrome_switches.h" |
+#if defined(OS_POSIX) |
+#include "chrome/common/file_descriptor_posix.h" |
+#endif |
#include "chrome/common/ipc_channel.h" |
#include "chrome/common/ipc_channel_proxy.h" |
#include "chrome/common/ipc_message_utils.h" |
@@ -93,6 +96,12 @@ base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type, |
debug_on_start); |
channel->OnClientConnected(); |
break; |
+ case TEST_DESCRIPTOR_CLIENT: |
+ ret = MultiProcessTest::SpawnChild(L"RunTestDescriptorClient", |
+ fds_to_map, |
+ debug_on_start); |
+ channel->OnClientConnected(); |
+ break; |
case TEST_REFLECTOR: |
ret = MultiProcessTest::SpawnChild(L"RunReflector", |
fds_to_map, |
@@ -217,6 +226,88 @@ TEST_F(IPCChannelTest, ChannelTest) { |
EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000)); |
} |
+#if defined(OS_POSIX) |
+ |
+class MyChannelDescriptorListener : public IPC::Channel::Listener { |
+ public: |
+ virtual void OnMessageReceived(const IPC::Message& message) { |
+ void* iter = NULL; |
+ |
+ FileDescriptor descriptor; |
+ |
+ ASSERT_TRUE( |
+ IPC::ParamTraits<FileDescriptor>::Read(&message, &iter, &descriptor)); |
+ VerifyDescriptor(&descriptor); |
+ MessageLoop::current()->Quit(); |
+ } |
+ |
+ virtual void OnChannelError() { |
+ MessageLoop::current()->Quit(); |
+ } |
+ |
+private: |
+ static void VerifyDescriptor(FileDescriptor* descriptor) { |
+ const int fd = open("/dev/null", O_RDONLY); |
+ struct stat st1, st2; |
+ fstat(fd, &st1); |
+ close(fd); |
+ fstat(descriptor->fd, &st2); |
+ close(descriptor->fd); |
+ ASSERT_EQ(st1.st_ino, st2.st_ino); |
+ } |
+}; |
+ |
+TEST_F(IPCChannelTest, DescriptorTest) { |
+ // Setup IPC channel. |
+ MyChannelDescriptorListener listener; |
+ |
+ IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, |
+ &listener); |
+ chan.Connect(); |
+ |
+ base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT, |
+ &chan); |
+ ASSERT_TRUE(process_handle); |
+ |
+ FileDescriptor descriptor; |
+ const int fd = open("/dev/null", O_RDONLY); |
+ ASSERT_GE(fd, 0); |
+ descriptor.auto_close = true; |
+ descriptor.fd = fd; |
+ |
+ IPC::Message* message = new IPC::Message(0, // routing_id |
+ 3, // message type |
+ IPC::Message::PRIORITY_NORMAL); |
+ IPC::ParamTraits<FileDescriptor>::Write(message, descriptor); |
+ chan.Send(message); |
+ |
+ // 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, 5000)); |
+} |
+ |
+MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) { |
+ MessageLoopForIO main_message_loop; |
+ MyChannelDescriptorListener listener; |
+ |
+ // setup IPC channel |
+ IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, |
+ &listener); |
+ chan.Connect(); |
+ |
+ // run message loop |
+ MessageLoop::current()->Run(); |
+ // return true; |
+ return NULL; |
+} |
+ |
+#endif // defined(OS_POSIX) |
+ |
TEST_F(IPCChannelTest, ChannelProxyTest) { |
// The thread needs to out-live the ChannelProxy. |
base::Thread thread("ChannelProxyTestServer"); |
@@ -277,6 +368,7 @@ MULTIPROCESS_TEST_MAIN(RunTestClient) { |
// return true; |
return NULL; |
} |
+ |
#endif // !PERFORMANCE_TEST |
#ifdef PERFORMANCE_TEST |