diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-25 21:51:35 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-25 21:51:35 +0000 |
commit | 3c78858906d3d0d7f5319d7c993240284b4503b5 (patch) | |
tree | 1abeaac1ec6d16e96c05ef5f534681979d1f4ef6 /ipc/ipc_send_fds_test.cc | |
parent | cdf594b2db94ff9c66d3f552a063706c16015c2b (diff) | |
download | chromium_src-3c78858906d3d0d7f5319d7c993240284b4503b5.zip chromium_src-3c78858906d3d0d7f5319d7c993240284b4503b5.tar.gz chromium_src-3c78858906d3d0d7f5319d7c993240284b4503b5.tar.bz2 |
Refactor (many) IPC tests, notably most of the multiprocess tests.
This factors out common code and, more importantly/usefully, makes test-specific
code more local, and thus easier to add new tests and maintain existing ones. In
particular, this allows you to add a new test "client" (running in another
process) without modifying ipc_test_base.*.
Review URL: https://codereview.chromium.org/12051048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178901 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/ipc_send_fds_test.cc')
-rw-r--r-- | ipc/ipc_send_fds_test.cc | 166 |
1 files changed, 72 insertions, 94 deletions
diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc index 005103c..5699e6d 100644 --- a/ipc/ipc_send_fds_test.cc +++ b/ipc/ipc_send_fds_test.cc @@ -4,6 +4,7 @@ #include "build/build_config.h" +#if defined(OS_POSIX) #if defined(OS_MACOSX) extern "C" { #include <sandbox.h> @@ -11,18 +12,15 @@ extern "C" { #endif #include <fcntl.h> #include <sys/stat.h> +#include <unistd.h> +#include "base/file_descriptor_posix.h" #include "base/message_loop.h" +#include "base/pickle.h" #include "base/posix/eintr_wrapper.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_listener.h" #include "ipc/ipc_message_utils.h" -#include "ipc/ipc_multiprocess_test.h" #include "ipc/ipc_test_base.h" -#if defined(OS_POSIX) -#include "base/file_descriptor_posix.h" - namespace { const unsigned kNumFDsToSend = 20; @@ -33,21 +31,21 @@ static void VerifyAndCloseDescriptor(int fd, ino_t inode_num) { char buf; ssize_t amt_read = read(fd, &buf, 1); ASSERT_EQ(amt_read, 1); - ASSERT_EQ(buf, 0); // /dev/zero always reads NUL bytes. + ASSERT_EQ(buf, 0); // /dev/zero always reads 0 bytes. struct stat st; ASSERT_EQ(fstat(fd, &st), 0); ASSERT_EQ(close(fd), 0); - // We compare iNode numbers to check that the file sent over the wire - // was actually the same physical file as the one we were expecting. + // Compare inode numbers to check that the file sent over the wire is actually + // the one expected. ASSERT_EQ(inode_num, st.st_ino); } class MyChannelDescriptorListener : public IPC::Listener { public: - MyChannelDescriptorListener(ino_t expected_inode_num) + explicit MyChannelDescriptorListener(ino_t expected_inode_num) : expected_inode_num_(expected_inode_num), num_fds_received_(0) {} @@ -57,13 +55,12 @@ class MyChannelDescriptorListener : public IPC::Listener { ++num_fds_received_; base::FileDescriptor descriptor; - IPC::ParamTraits<base::FileDescriptor>::Read( - &message, &iter, &descriptor); + IPC::ParamTraits<base::FileDescriptor>::Read(&message, &iter, &descriptor); VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_); - if (num_fds_received_ == kNumFDsToSend) { + if (num_fds_received_ == kNumFDsToSend) MessageLoop::current()->Quit(); - } + return true; } @@ -71,8 +68,8 @@ class MyChannelDescriptorListener : public IPC::Listener { MessageLoop::current()->Quit(); } - bool GotExpectedNumberOfDescriptors() { - return kNumFDsToSend == num_fds_received_; + bool GotExpectedNumberOfDescriptors() const { + return num_fds_received_ == kNumFDsToSend; } private: @@ -80,126 +77,107 @@ class MyChannelDescriptorListener : public IPC::Listener { unsigned num_fds_received_; }; -void TestDescriptorServer(IPC::Channel& chan, - base::ProcessHandle process_handle) { - ASSERT_TRUE(process_handle); +class IPCSendFdsTest : public IPCTestBase { + protected: + void RunServer() { + // Set up IPC channel and start client. + MyChannelDescriptorListener listener(-1); + CreateChannel(&listener); + ASSERT_TRUE(ConnectChannel()); + ASSERT_TRUE(StartClient()); + + for (unsigned i = 0; i < kNumFDsToSend; ++i) { + const int fd = open(kDevZeroPath, O_RDONLY); + ASSERT_GE(fd, 0); + base::FileDescriptor descriptor(fd, true); + + IPC::Message* message = + new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL); + IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor); + ASSERT_TRUE(sender()->Send(message)); + } - for (unsigned i = 0; i < kNumFDsToSend; ++i) { - base::FileDescriptor descriptor; - const int fd = open(kDevZeroPath, 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<base::FileDescriptor>::Write(message, descriptor); - ASSERT_TRUE(chan.Send(message)); - } + // Run message loop. + MessageLoop::current()->Run(); - // Run message loop. - MessageLoop::current()->Run(); + // Close the channel so the client's OnChannelError() gets fired. + channel()->Close(); - // Close Channel so client gets its OnChannelError() callback fired. - chan.Close(); + EXPECT_TRUE(WaitForClientShutdown()); + DestroyChannel(); + } +}; - // Cleanup child process. - EXPECT_TRUE(base::WaitForSingleProcess( - process_handle, base::TimeDelta::FromSeconds(5))); +TEST_F(IPCSendFdsTest, DescriptorTest) { + Init("SendFdsClient"); + RunServer(); } -int TestDescriptorClient(ino_t expected_inode_num) { +int SendFdsClientCommon(const std::string& test_client_name, + ino_t expected_inode_num) { MessageLoopForIO main_message_loop; MyChannelDescriptorListener listener(expected_inode_num); - // Setup IPC channel. - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, - &listener); - CHECK(chan.Connect()); + // Set up IPC channel. + IPC::Channel channel(IPCTestBase::GetChannelName(test_client_name), + IPC::Channel::MODE_CLIENT, + &listener); + CHECK(channel.Connect()); - // Run message loop so IPC Channel can handle message IO. + // Run message loop. MessageLoop::current()->Run(); - // Verify that the message loop was exited due to getting the correct - // number of descriptors, and not because the channel closing unexpectedly. + // Verify that the message loop was exited due to getting the correct number + // of descriptors, and not because of the channel closing unexpectedly. CHECK(listener.GotExpectedNumberOfDescriptors()); return 0; } -class IPCSendFdsTest : public IPCTestBase { -}; +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsClient) { + struct stat st; + int fd = open(kDevZeroPath, O_RDONLY); + fstat(fd, &st); + EXPECT_GE(HANDLE_EINTR(close(fd)), 0); + return SendFdsClientCommon("SendFdsClient", st.st_ino); +} #if defined(OS_MACOSX) +// Test that FDs are correctly sent to a sandboxed process. // TODO(port): Make this test cross-platform. -MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClientSandboxed) { +TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { + Init("SendFdsSandboxedClient"); + RunServer(); +} + +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsSandboxedClient) { struct stat st; const int fd = open(kDevZeroPath, O_RDONLY); fstat(fd, &st); - if (HANDLE_EINTR(close(fd)) < 0) { + if (HANDLE_EINTR(close(fd)) < 0) return -1; - } - // Enable the Sandbox. + // Enable the sandbox. char* error_buff = NULL; int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED, &error_buff); bool success = (error == 0 && error_buff == NULL); - if (!success) { + if (!success) return -1; - } sandbox_free_error(error_buff); - // Make sure Sandbox is really enabled. + // Make sure sandbox is really enabled. if (open(kDevZeroPath, O_RDONLY) != -1) { LOG(ERROR) << "Sandbox wasn't properly enabled"; return -1; } // See if we can receive a file descriptor. - return TestDescriptorClient(st.st_ino); -} - -// Test that FDs are correctly sent to a sandboxed process. -TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { - // Setup IPC channel. - MyChannelDescriptorListener listener(-1); - - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, - &listener); - ASSERT_TRUE(chan.Connect()); - - base::ProcessHandle process_handle = SpawnChild( - TEST_DESCRIPTOR_CLIENT_SANDBOXED, - &chan); - TestDescriptorServer(chan, process_handle); + return SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino); } #endif // defined(OS_MACOSX) -MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClient) { - struct stat st; - const int fd = open(kDevZeroPath, O_RDONLY); - fstat(fd, &st); - EXPECT_GE(HANDLE_EINTR(close(fd)), 0); - - return TestDescriptorClient(st.st_ino); -} - -TEST_F(IPCSendFdsTest, DescriptorTest) { - // Setup IPC channel. - MyChannelDescriptorListener listener(-1); - - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, - &listener); - ASSERT_TRUE(chan.Connect()); - - base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT, - &chan); - TestDescriptorServer(chan, process_handle); -} - } // namespace #endif // defined(OS_POSIX) |