summaryrefslogtreecommitdiff
path: root/chromium/ipc/ipc_send_fds_test.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-03-08 10:28:10 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-03-20 13:40:30 +0000
commite733310db58160074f574c429d48f8308c0afe17 (patch)
treef8aef4b7e62a69928dbcf880620eece20f98c6df /chromium/ipc/ipc_send_fds_test.cc
parent2f583e4aec1ae3a86fa047829c96b310dc12ecdf (diff)
downloadqtwebengine-chromium-e733310db58160074f574c429d48f8308c0afe17.tar.gz
BASELINE: Update Chromium to 56.0.2924.122
Change-Id: I4e04de8f47e47e501c46ed934c76a431c6337ced Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ipc/ipc_send_fds_test.cc')
-rw-r--r--chromium/ipc/ipc_send_fds_test.cc237
1 files changed, 29 insertions, 208 deletions
diff --git a/chromium/ipc/ipc_send_fds_test.cc b/chromium/ipc/ipc_send_fds_test.cc
index f92b119a3ca..f648b6411ab 100644
--- a/chromium/ipc/ipc_send_fds_test.cc
+++ b/chromium/ipc/ipc_send_fds_test.cc
@@ -113,15 +113,13 @@ class MyChannelDescriptorListener : public MyChannelDescriptorListenerBase {
unsigned num_fds_received_;
};
-
-class IPCSendFdsTest : public IPCTestBase {
+class IPCSendFdsTest : public IPCChannelMojoTestBase {
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 < kNumMessages; ++i) {
IPC::Message* message =
@@ -151,33 +149,34 @@ TEST_F(IPCSendFdsTest, DescriptorTest) {
RunServer();
}
-int SendFdsClientCommon(const std::string& test_client_name,
- ino_t expected_inode_num) {
- base::MessageLoopForIO main_message_loop;
- MyChannelDescriptorListener listener(expected_inode_num);
+class SendFdsTestClientFixture : public IpcChannelMojoTestClient {
+ protected:
+ void SendFdsClientCommon(const std::string& test_client_name,
+ ino_t expected_inode_num) {
+ MyChannelDescriptorListener listener(expected_inode_num);
- // Set up IPC channel.
- std::unique_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
- IPCTestBase::GetChannelName(test_client_name), &listener,
- main_message_loop.task_runner()));
- CHECK(channel->Connect());
+ // Set up IPC channel.
+ Connect(&listener);
- // Run message loop.
- base::RunLoop().Run();
+ // Run message loop.
+ base::RunLoop().Run();
- // 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());
+ // Verify that the message loop was exited due to getting the correct number
+ // of descriptors, and not because of the channel closing unexpectedly.
+ EXPECT_TRUE(listener.GotExpectedNumberOfDescriptors());
- return 0;
-}
+ Close();
+ }
+};
-MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsClient) {
+DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
+ SendFdsClient,
+ SendFdsTestClientFixture) {
struct stat st;
int fd = open(kDevZeroPath, O_RDONLY);
fstat(fd, &st);
EXPECT_GE(IGNORE_EINTR(close(fd)), 0);
- return SendFdsClientCommon("SendFdsClient", st.st_ino);
+ SendFdsClientCommon("SendFdsClient", st.st_ino);
}
#if defined(OS_MACOSX)
@@ -188,210 +187,32 @@ TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) {
RunServer();
}
-MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsSandboxedClient) {
+DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
+ SendFdsSandboxedClient,
+ SendFdsTestClientFixture) {
struct stat st;
const int fd = open(kDevZeroPath, O_RDONLY);
fstat(fd, &st);
- if (IGNORE_EINTR(close(fd)) < 0)
- return -1;
+ ASSERT_LE(0, IGNORE_EINTR(close(fd)));
// Enable the sandbox.
char* error_buff = NULL;
int error = sandbox::Seatbelt::Init(
sandbox::Seatbelt::kProfilePureComputation, SANDBOX_NAMED, &error_buff);
- bool success = (error == 0 && error_buff == NULL);
- if (!success)
- return -1;
+ ASSERT_EQ(0, error);
+ ASSERT_FALSE(error_buff);
sandbox::Seatbelt::FreeError(error_buff);
// Make sure sandbox is really enabled.
- if (open(kDevZeroPath, O_RDONLY) != -1) {
- LOG(ERROR) << "Sandbox wasn't properly enabled";
- return -1;
- }
+ ASSERT_EQ(-1, open(kDevZeroPath, O_RDONLY))
+ << "Sandbox wasn't properly enabled";
// See if we can receive a file descriptor.
- return SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino);
+ SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino);
}
#endif // defined(OS_MACOSX)
-
-class MyCBListener : public MyChannelDescriptorListenerBase {
- public:
- MyCBListener(base::Callback<void(int)> cb, int fds_to_send)
- : MyChannelDescriptorListenerBase(),
- cb_(cb) {
- }
-
- protected:
- void HandleFD(int fd) override { cb_.Run(fd); }
- private:
- base::Callback<void(int)> cb_;
-};
-
-std::pair<int, int> make_socket_pair() {
- int pipe_fds[2];
- CHECK_EQ(0, HANDLE_EINTR(socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds)));
- return std::pair<int, int>(pipe_fds[0], pipe_fds[1]);
-}
-
-static void null_cb(int unused_fd) {
- NOTREACHED();
-}
-
-class PipeChannelHelper {
- public:
- PipeChannelHelper(base::Thread* in_thread,
- base::Thread* out_thread,
- base::Callback<void(int)> cb,
- int fds_to_send) :
- in_thread_(in_thread),
- out_thread_(out_thread),
- cb_listener_(cb, fds_to_send),
- null_listener_(base::Bind(&null_cb), 0) {
- }
-
- void Init() {
- IPC::ChannelHandle in_handle("IN");
- in = IPC::Channel::CreateServer(
- in_handle, &null_listener_, in_thread_->task_runner());
- IPC::ChannelHandle out_handle(
- "OUT", base::FileDescriptor(in->TakeClientFileDescriptor()));
- out = IPC::Channel::CreateClient(
- out_handle, &cb_listener_, out_thread_->task_runner());
- // PostTask the connect calls to make sure the callbacks happens
- // on the right threads.
- in_thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PipeChannelHelper::Connect, in.get()));
- out_thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PipeChannelHelper::Connect, out.get()));
- }
-
- static void DestroyChannel(std::unique_ptr<IPC::Channel>* c,
- base::WaitableEvent* event) {
- c->reset(0);
- event->Signal();
- }
-
- ~PipeChannelHelper() {
- base::WaitableEvent a(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- base::WaitableEvent b(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- in_thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PipeChannelHelper::DestroyChannel, &in, &a));
- out_thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PipeChannelHelper::DestroyChannel, &out, &b));
- a.Wait();
- b.Wait();
- }
-
- static void Connect(IPC::Channel *channel) {
- EXPECT_TRUE(channel->Connect());
- }
-
- void Send(int fd) {
- CHECK_EQ(base::MessageLoop::current(), in_thread_->message_loop());
-
- 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(in->Send(message));
- }
-
- private:
- std::unique_ptr<IPC::Channel> in, out;
- base::Thread* in_thread_;
- base::Thread* out_thread_;
- MyCBListener cb_listener_;
- MyCBListener null_listener_;
-};
-
-// This test is meant to provoke a kernel bug on OSX, and to prove
-// that the workaround for it is working. It sets up two pipes and three
-// threads, the producer thread creates socketpairs and sends one of the fds
-// over pipe1 to the middleman thread. The middleman thread simply takes the fd
-// sends it over pipe2 to the consumer thread. The consumer thread writes a byte
-// to each fd it receives and then closes the pipe. The producer thread reads
-// the bytes back from each pair of pipes and make sure that everything worked.
-// This feedback mechanism makes sure that not too many file descriptors are
-// in flight at the same time. For more info on the bug, see:
-// http://crbug.com/298276
-class IPCMultiSendingFdsTest : public testing::Test {
- public:
- IPCMultiSendingFdsTest()
- : received_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED) {}
-
- void Producer(PipeChannelHelper* dest,
- base::Thread* t,
- int pipes_to_send) {
- for (int i = 0; i < pipes_to_send; i++) {
- received_.Reset();
- std::pair<int, int> pipe_fds = make_socket_pair();
- t->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PipeChannelHelper::Send,
- base::Unretained(dest), pipe_fds.second));
- char tmp = 'x';
- CHECK_EQ(1, HANDLE_EINTR(write(pipe_fds.first, &tmp, 1)));
- CHECK_EQ(0, IGNORE_EINTR(close(pipe_fds.first)));
- received_.Wait();
- }
- }
-
- void ConsumerHandleFD(int fd) {
- char tmp = 'y';
- CHECK_EQ(1, HANDLE_EINTR(read(fd, &tmp, 1)));
- CHECK_EQ(tmp, 'x');
- CHECK_EQ(0, IGNORE_EINTR(close(fd)));
- received_.Signal();
- }
-
- base::Thread* CreateThread(const char* name) {
- base::Thread* ret = new base::Thread(name);
- base::Thread::Options options;
- options.message_loop_type = base::MessageLoop::TYPE_IO;
- ret->StartWithOptions(options);
- return ret;
- }
-
- void Run() {
- // On my mac, this test fails roughly 35 times per
- // million sends with low load, but much more with high load.
- // Unless the workaround is in place. With 10000 sends, we
- // should see at least a 3% failure rate.
- const int pipes_to_send = 20000;
- std::unique_ptr<base::Thread> producer(CreateThread("producer"));
- std::unique_ptr<base::Thread> middleman(CreateThread("middleman"));
- std::unique_ptr<base::Thread> consumer(CreateThread("consumer"));
- PipeChannelHelper pipe1(
- middleman.get(),
- consumer.get(),
- base::Bind(&IPCMultiSendingFdsTest::ConsumerHandleFD,
- base::Unretained(this)),
- pipes_to_send);
- PipeChannelHelper pipe2(
- producer.get(),
- middleman.get(),
- base::Bind(&PipeChannelHelper::Send, base::Unretained(&pipe1)),
- pipes_to_send);
- pipe1.Init();
- pipe2.Init();
- Producer(&pipe2, producer.get(), pipes_to_send);
- }
-
- private:
- base::WaitableEvent received_;
-};
-
-TEST_F(IPCMultiSendingFdsTest, StressTest) {
- Run();
-}
-
} // namespace
#endif // defined(OS_POSIX)