blob: 40525591eca953fadc32069d331dcc2924cc380b [file] [log] [blame]
[email protected]64860882014-08-04 23:44:171// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ipc/mojo/ipc_channel_mojo.h"
6
avi246998d82015-12-22 02:39:047#include <stddef.h>
tfarina10a5c062015-09-04 18:47:578#include <stdint.h>
danakj03de39b22016-04-23 04:21:099#include <memory>
dchenge48600452015-12-28 02:24:5010#include <utility>
tfarina10a5c062015-09-04 18:47:5711
[email protected]64860882014-08-04 23:44:1712#include "base/base_paths.h"
13#include "base/files/file.h"
skyostile687bdff2015-05-12 11:29:2114#include "base/location.h"
[email protected]64860882014-08-04 23:44:1715#include "base/path_service.h"
16#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0417#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2118#include "base/single_thread_task_runner.h"
sammc57ed9f982016-03-10 06:28:3519#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2720#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1721#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1122#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0423#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1724#include "ipc/ipc_message.h"
25#include "ipc/ipc_test_base.h"
26#include "ipc/ipc_test_channel_listener.h"
sammc57ed9f982016-03-10 06:28:3527#include "ipc/mojo/ipc_channel_mojo.h"
morrita81b17e02015-02-06 00:58:3028#include "ipc/mojo/ipc_mojo_handle_attachment.h"
29#include "ipc/mojo/ipc_mojo_message_helper.h"
morrita438a2ee2015-04-03 05:28:2130#include "ipc/mojo/ipc_mojo_param_traits.h"
sammc57ed9f982016-03-10 06:28:3531#include "mojo/edk/test/mojo_test_base.h"
32#include "mojo/edk/test/multiprocess_test_helper.h"
33#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1734
35#if defined(OS_POSIX)
36#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4237#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1738#endif
39
sammc57ed9f982016-03-10 06:28:3540#define DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(client_name, test_base) \
41 class client_name##_MainFixture : public test_base { \
42 public: \
43 void Main(); \
44 }; \
45 MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
46 client_name##TestChildMain, \
47 ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \
48 CHECK(!mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token \
49 .empty()); \
50 client_name##_MainFixture test; \
51 test.Init(mojo::edk::CreateChildMessagePipe( \
52 mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token)); \
53 test.Main(); \
54 return (::testing::Test::HasFatalFailure() || \
55 ::testing::Test::HasNonfatalFailure()) \
56 ? 1 \
57 : 0; \
58 } \
59 void client_name##_MainFixture::Main()
60
[email protected]64860882014-08-04 23:44:1761namespace {
62
63class ListenerThatExpectsOK : public IPC::Listener {
64 public:
sammc57ed9f982016-03-10 06:28:3565 ListenerThatExpectsOK() : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1766
dchengfe61fca2014-10-22 02:29:5267 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1768
dchengfe61fca2014-10-22 02:29:5269 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2570 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1771 std::string should_be_ok;
72 EXPECT_TRUE(iter.ReadString(&should_be_ok));
73 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1374 received_ok_ = true;
ki.stfua21ed8c2015-10-12 17:26:0075 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:1776 return true;
77 }
78
dchengfe61fca2014-10-22 02:29:5279 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1380 // The connection should be healthy while the listener is waiting
81 // message. An error can occur after that because the peer
82 // process dies.
83 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1784 }
85
86 static void SendOK(IPC::Sender* sender) {
sammc57ed9f982016-03-10 06:28:3587 IPC::Message* message =
88 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
[email protected]64860882014-08-04 23:44:1789 message->WriteString(std::string("OK"));
90 ASSERT_TRUE(sender->Send(message));
91 }
[email protected]e5c27752014-08-08 21:45:1392
93 private:
94 bool received_ok_;
[email protected]64860882014-08-04 23:44:1795};
96
[email protected]64860882014-08-04 23:44:1797class ChannelClient {
98 public:
sammc57ed9f982016-03-10 06:28:3599 void Init(mojo::ScopedMessagePipeHandle handle) {
100 handle_ = std::move(handle);
tsergeant896012862016-03-10 03:51:33101 }
sammc57ed9f982016-03-10 06:28:35102 void Connect(IPC::Listener* listener) {
103 channel_ = IPC::ChannelMojo::Create(std::move(handle_),
104 IPC::Channel::MODE_CLIENT, listener);
[email protected]64860882014-08-04 23:44:17105 CHECK(channel_->Connect());
106 }
107
rockotcbca72f2015-03-03 16:31:04108 void Close() {
109 channel_->Close();
110
111 base::RunLoop run_loop;
skyostile687bdff2015-05-12 11:29:21112 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
113 run_loop.QuitClosure());
rockotcbca72f2015-03-03 16:31:04114 run_loop.Run();
115 }
116
[email protected]64860882014-08-04 23:44:17117 IPC::ChannelMojo* channel() const { return channel_.get(); }
118
119 private:
[email protected]64860882014-08-04 23:44:17120 base::MessageLoopForIO main_message_loop_;
sammc57ed9f982016-03-10 06:28:35121 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09122 std::unique_ptr<IPC::ChannelMojo> channel_;
[email protected]64860882014-08-04 23:44:17123};
124
sammc57ed9f982016-03-10 06:28:35125class IPCChannelMojoTest : public testing::Test {
rockotcbca72f2015-03-03 16:31:04126 public:
sammc57ed9f982016-03-10 06:28:35127 IPCChannelMojoTest() : io_thread_(base::TestIOThread::Mode::kAutoStart) {}
128
129 void TearDown() override { base::RunLoop().RunUntilIdle(); }
130
rockotcbca72f2015-03-03 16:31:04131 void InitWithMojo(const std::string& test_client_name) {
sammc57ed9f982016-03-10 06:28:35132 handle_ = helper_.StartChild(test_client_name);
rockotcbca72f2015-03-03 16:31:04133 }
134
sammc57ed9f982016-03-10 06:28:35135 void CreateChannel(IPC::Listener* listener) {
136 channel_ = IPC::ChannelMojo::Create(std::move(handle_),
137 IPC::Channel::MODE_SERVER, listener);
rockotcbca72f2015-03-03 16:31:04138 }
sammc57ed9f982016-03-10 06:28:35139
140 bool ConnectChannel() { return channel_->Connect(); }
141
142 void DestroyChannel() { channel_.reset(); }
143
144 bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); }
145
146 IPC::Sender* sender() { return channel(); }
147 IPC::Channel* channel() { return channel_.get(); }
148
149 private:
150 base::MessageLoop message_loop_;
151 base::TestIOThread io_thread_;
152 mojo::edk::test::MultiprocessTestHelper helper_;
153 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09154 std::unique_ptr<IPC::Channel> channel_;
rockotcbca72f2015-03-03 16:31:04155};
156
[email protected]64860882014-08-04 23:44:17157class TestChannelListenerWithExtraExpectations
158 : public IPC::TestChannelListener {
159 public:
sammc57ed9f982016-03-10 06:28:35160 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17161
tfarina10a5c062015-09-04 18:47:57162 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17163 IPC::TestChannelListener::OnChannelConnected(peer_pid);
164 EXPECT_TRUE(base::kNullProcessId != peer_pid);
165 is_connected_called_ = true;
166 }
167
168 bool is_connected_called() const { return is_connected_called_; }
169
170 private:
171 bool is_connected_called_;
172};
173
amistry0027a0952016-05-03 00:52:47174TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04175 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17176
177 // Set up IPC channel and start client.
178 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24179 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17180 listener.Init(sender());
181 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17182
sammc57ed9f982016-03-10 06:28:35183 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17184
185 base::MessageLoop::current()->Run();
[email protected]64860882014-08-04 23:44:17186
sammc57ed9f982016-03-10 06:28:35187 channel()->Close();
[email protected]64860882014-08-04 23:44:17188
189 EXPECT_TRUE(WaitForClientShutdown());
190 EXPECT_TRUE(listener.is_connected_called());
191 EXPECT_TRUE(listener.HasSentAll());
192
193 DestroyChannel();
194}
195
196// A long running process that connects to us
sammc57ed9f982016-03-10 06:28:35197DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient, ChannelClient) {
[email protected]64860882014-08-04 23:44:17198 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35199 Connect(&listener);
200 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17201
sammc57ed9f982016-03-10 06:28:35202 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
[email protected]64860882014-08-04 23:44:17203 base::MessageLoop::current()->Run();
204 EXPECT_TRUE(listener.is_connected_called());
205 EXPECT_TRUE(listener.HasSentAll());
206
sammc57ed9f982016-03-10 06:28:35207 Close();
[email protected]64860882014-08-04 23:44:17208}
209
morrita0a24cfc92014-09-16 03:20:48210class ListenerExpectingErrors : public IPC::Listener {
211 public:
sammc57ed9f982016-03-10 06:28:35212 ListenerExpectingErrors() : has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48213
tfarina10a5c062015-09-04 18:47:57214 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00215 base::MessageLoop::current()->QuitWhenIdle();
morritabe6c4cc2014-09-24 23:38:44216 }
217
dchengfe61fca2014-10-22 02:29:52218 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48219
dchengfe61fca2014-10-22 02:29:52220 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48221 has_error_ = true;
ki.stfua21ed8c2015-10-12 17:26:00222 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48223 }
224
225 bool has_error() const { return has_error_; }
226
227 private:
228 bool has_error_;
229};
230
morrita0a24cfc92014-09-16 03:20:48231class ListenerThatQuits : public IPC::Listener {
232 public:
sammc57ed9f982016-03-10 06:28:35233 ListenerThatQuits() {}
morrita0a24cfc92014-09-16 03:20:48234
sammc57ed9f982016-03-10 06:28:35235 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48236
tfarina10a5c062015-09-04 18:47:57237 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00238 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48239 }
240};
241
242// A long running process that connects to us.
sammc57ed9f982016-03-10 06:28:35243DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient,
244 ChannelClient) {
morrita0a24cfc92014-09-16 03:20:48245 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35246 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48247
248 base::MessageLoop::current()->Run();
249
sammc57ed9f982016-03-10 06:28:35250 Close();
morrita0a24cfc92014-09-16 03:20:48251}
252
amistry0027a0952016-05-03 00:52:47253TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04254 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48255
256 // Set up IPC channel and start client.
257 ListenerExpectingErrors listener;
258 CreateChannel(&listener);
259 ASSERT_TRUE(ConnectChannel());
260
jamesra03ae492014-10-03 04:26:48261 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44262 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
263 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48264 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44265 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35266 IPC::TestChannelListener::SendOneMessage(sender(),
267 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48268 }
269
morrita0a24cfc92014-09-16 03:20:48270 base::MessageLoop::current()->Run();
271
sammc57ed9f982016-03-10 06:28:35272 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48273
274 EXPECT_TRUE(WaitForClientShutdown());
275 EXPECT_TRUE(listener.has_error());
276
277 DestroyChannel();
278}
279
morrita81b17e02015-02-06 00:58:30280struct TestingMessagePipe {
281 TestingMessagePipe() {
282 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
283 }
284
285 mojo::ScopedMessagePipeHandle self;
286 mojo::ScopedMessagePipeHandle peer;
287};
288
289class HandleSendingHelper {
290 public:
291 static std::string GetSendingFileContent() { return "Hello"; }
292
293 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
294 std::string content = HandleSendingHelper::GetSendingFileContent();
295 EXPECT_EQ(MOJO_RESULT_OK,
296 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
297 static_cast<uint32_t>(content.size()),
298 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50299 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
300 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30301 }
302
303 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
304 IPC::Message* message =
305 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
306 WritePipe(message, pipe);
307 ASSERT_TRUE(sender->Send(message));
308 }
309
310 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25311 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30312 mojo::ScopedMessagePipeHandle pipe;
313 EXPECT_TRUE(
314 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
315 std::string content(GetSendingFileContent().size(), ' ');
316
317 uint32_t num_bytes = static_cast<uint32_t>(content.size());
sammc57ed9f982016-03-10 06:28:35318 ASSERT_EQ(MOJO_RESULT_OK,
319 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
320 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita81b17e02015-02-06 00:58:30321 EXPECT_EQ(MOJO_RESULT_OK,
322 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
323 nullptr, 0));
324 EXPECT_EQ(content, GetSendingFileContent());
325 }
326
327#if defined(OS_POSIX)
328 static base::FilePath GetSendingFilePath() {
329 base::FilePath path;
330 bool ok = PathService::Get(base::DIR_CACHE, &path);
331 EXPECT_TRUE(ok);
332 return path.Append("ListenerThatExpectsFile.txt");
333 }
334
335 static void WriteFile(IPC::Message* message, base::File& file) {
336 std::string content = GetSendingFileContent();
337 file.WriteAtCurrentPos(content.data(), content.size());
338 file.Flush();
339 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
340 base::ScopedFD(file.TakePlatformFile())));
341 }
342
343 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
344 IPC::Message* message =
345 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
346 WriteFile(message, file);
347 ASSERT_TRUE(sender->Send(message));
348 }
349
350 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
351 base::File& file,
352 TestingMessagePipe* pipe) {
353 IPC::Message* message =
354 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
355 WriteFile(message, file);
356 WritePipe(message, pipe);
357 ASSERT_TRUE(sender->Send(message));
358 }
359
360 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25361 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30362 base::ScopedFD fd;
rockot502c94f2016-02-03 20:20:16363 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30364 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
amistry980a61b2016-06-09 02:51:20365 EXPECT_EQ(IPC::MessageAttachment::TYPE_PLATFORM_FILE,
366 static_cast<IPC::MessageAttachment*>(attachment.get())
367 ->GetType());
rockot502c94f2016-02-03 20:20:16368 base::File file(static_cast<IPC::MessageAttachment*>(attachment.get())
369 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30370 std::string content(GetSendingFileContent().size(), ' ');
371 file.Read(0, &content[0], content.size());
372 EXPECT_EQ(content, GetSendingFileContent());
373 }
374#endif
375};
376
377class ListenerThatExpectsMessagePipe : public IPC::Listener {
378 public:
379 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
380
381 ~ListenerThatExpectsMessagePipe() override {}
382
383 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25384 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30385 HandleSendingHelper::ReadReceivedPipe(message, &iter);
ki.stfua21ed8c2015-10-12 17:26:00386 base::MessageLoop::current()->QuitWhenIdle();
morrita81b17e02015-02-06 00:58:30387 ListenerThatExpectsOK::SendOK(sender_);
388 return true;
389 }
390
391 void OnChannelError() override { NOTREACHED(); }
392
393 void set_sender(IPC::Sender* sender) { sender_ = sender; }
394
395 private:
396 IPC::Sender* sender_;
397};
398
amistry0027a0952016-05-03 00:52:47399TEST_F(IPCChannelMojoTest, SendMessagePipe) {
rockotcbca72f2015-03-03 16:31:04400 InitWithMojo("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30401
402 ListenerThatExpectsOK listener;
403 CreateChannel(&listener);
404 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30405
406 TestingMessagePipe pipe;
407 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
408
409 base::MessageLoop::current()->Run();
sammc57ed9f982016-03-10 06:28:35410 channel()->Close();
morrita81b17e02015-02-06 00:58:30411
412 EXPECT_TRUE(WaitForClientShutdown());
413 DestroyChannel();
414}
415
sammc57ed9f982016-03-10 06:28:35416DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient,
417 ChannelClient) {
morrita81b17e02015-02-06 00:58:30418 ListenerThatExpectsMessagePipe listener;
sammc57ed9f982016-03-10 06:28:35419 Connect(&listener);
420 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30421
422 base::MessageLoop::current()->Run();
423
sammc57ed9f982016-03-10 06:28:35424 Close();
morrita81b17e02015-02-06 00:58:30425}
426
morrita438a2ee2015-04-03 05:28:21427void ReadOK(mojo::MessagePipeHandle pipe) {
428 std::string should_be_ok("xx");
429 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
sammc57ed9f982016-03-10 06:28:35430 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE,
431 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita438a2ee2015-04-03 05:28:21432 CHECK_EQ(MOJO_RESULT_OK,
433 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
434 nullptr, 0));
435 EXPECT_EQ(should_be_ok, std::string("OK"));
436}
437
438void WriteOK(mojo::MessagePipeHandle pipe) {
439 std::string ok("OK");
440 CHECK_EQ(MOJO_RESULT_OK,
441 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
442 nullptr, 0, 0));
443}
444
445class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
446 public:
447 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
448 : sender_(NULL), receiving_valid_(receiving_valid) {}
449
450 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
451
452 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25453 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21454 mojo::MessagePipeHandle handle;
455 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
456 &handle));
457 EXPECT_EQ(handle.is_valid(), receiving_valid_);
458 if (receiving_valid_) {
459 ReadOK(handle);
460 MojoClose(handle.value());
461 }
462
ki.stfua21ed8c2015-10-12 17:26:00463 base::MessageLoop::current()->QuitWhenIdle();
morrita438a2ee2015-04-03 05:28:21464 ListenerThatExpectsOK::SendOK(sender_);
465 return true;
466 }
467
468 void OnChannelError() override { NOTREACHED(); }
469 void set_sender(IPC::Sender* sender) { sender_ = sender; }
470
471 private:
472 IPC::Sender* sender_;
473 bool receiving_valid_;
474};
475
sammc57ed9f982016-03-10 06:28:35476class ParamTraitMessagePipeClient : public ChannelClient {
477 public:
478 void RunTest(bool receiving_valid_handle) {
479 ListenerThatExpectsMessagePipeUsingParamTrait listener(
480 receiving_valid_handle);
481 Connect(&listener);
482 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21483
sammc57ed9f982016-03-10 06:28:35484 base::MessageLoop::current()->Run();
morrita438a2ee2015-04-03 05:28:21485
sammc57ed9f982016-03-10 06:28:35486 Close();
487 }
488};
morrita438a2ee2015-04-03 05:28:21489
amistry0027a0952016-05-03 00:52:47490TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21491 InitWithMojo("ParamTraitValidMessagePipeClient");
492
493 ListenerThatExpectsOK listener;
494 CreateChannel(&listener);
495 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21496
497 TestingMessagePipe pipe;
498
danakj03de39b22016-04-23 04:21:09499 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21500 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
501 pipe.peer.release());
502 WriteOK(pipe.self.get());
503
sammc57ed9f982016-03-10 06:28:35504 channel()->Send(message.release());
morrita438a2ee2015-04-03 05:28:21505 base::MessageLoop::current()->Run();
sammc57ed9f982016-03-10 06:28:35506 channel()->Close();
morrita438a2ee2015-04-03 05:28:21507
508 EXPECT_TRUE(WaitForClientShutdown());
509 DestroyChannel();
510}
511
sammc57ed9f982016-03-10 06:28:35512DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitValidMessagePipeClient,
513 ParamTraitMessagePipeClient) {
514 RunTest(true);
morrita438a2ee2015-04-03 05:28:21515}
516
amistry0027a0952016-05-03 00:52:47517TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21518 InitWithMojo("ParamTraitInvalidMessagePipeClient");
519
520 ListenerThatExpectsOK listener;
521 CreateChannel(&listener);
522 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21523
524 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09525 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21526 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
527 invalid_handle);
528
sammc57ed9f982016-03-10 06:28:35529 channel()->Send(message.release());
morrita438a2ee2015-04-03 05:28:21530 base::MessageLoop::current()->Run();
sammc57ed9f982016-03-10 06:28:35531 channel()->Close();
morrita438a2ee2015-04-03 05:28:21532
533 EXPECT_TRUE(WaitForClientShutdown());
534 DestroyChannel();
535}
536
sammc57ed9f982016-03-10 06:28:35537DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitInvalidMessagePipeClient,
538 ParamTraitMessagePipeClient) {
539 RunTest(false);
morrita438a2ee2015-04-03 05:28:21540}
541
amistry0027a0952016-05-03 00:52:47542TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
morrita17137e62015-06-23 22:29:36543 InitWithMojo("IPCChannelMojoTestSendOkClient");
544
545 ListenerThatExpectsOK listener;
546 CreateChannel(&listener);
547 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36548
549 base::MessageLoop::current()->Run();
sammc57ed9f982016-03-10 06:28:35550 channel()->Close();
551 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36552
553 EXPECT_TRUE(WaitForClientShutdown());
554 DestroyChannel();
555}
556
557class ListenerSendingOneOk : public IPC::Listener {
558 public:
sammc57ed9f982016-03-10 06:28:35559 ListenerSendingOneOk() {}
morrita17137e62015-06-23 22:29:36560
sammc57ed9f982016-03-10 06:28:35561 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36562
tfarina10a5c062015-09-04 18:47:57563 void OnChannelConnected(int32_t peer_pid) override {
morrita17137e62015-06-23 22:29:36564 ListenerThatExpectsOK::SendOK(sender_);
ki.stfua21ed8c2015-10-12 17:26:00565 base::MessageLoop::current()->QuitWhenIdle();
morrita17137e62015-06-23 22:29:36566 }
567
568 void set_sender(IPC::Sender* sender) { sender_ = sender; }
569
570 private:
571 IPC::Sender* sender_;
572};
573
sammc57ed9f982016-03-10 06:28:35574DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient,
575 ChannelClient) {
morrita17137e62015-06-23 22:29:36576 ListenerSendingOneOk listener;
sammc57ed9f982016-03-10 06:28:35577 Connect(&listener);
578 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36579
580 base::MessageLoop::current()->Run();
581
sammc57ed9f982016-03-10 06:28:35582 Close();
morrita17137e62015-06-23 22:29:36583}
584
[email protected]64860882014-08-04 23:44:17585#if defined(OS_POSIX)
586class ListenerThatExpectsFile : public IPC::Listener {
587 public:
sammc57ed9f982016-03-10 06:28:35588 ListenerThatExpectsFile() : sender_(NULL) {}
[email protected]64860882014-08-04 23:44:17589
dchengfe61fca2014-10-22 02:29:52590 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:17591
dchengfe61fca2014-10-22 02:29:52592 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25593 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30594 HandleSendingHelper::ReadReceivedFile(message, &iter);
ki.stfua21ed8c2015-10-12 17:26:00595 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:17596 ListenerThatExpectsOK::SendOK(sender_);
597 return true;
598 }
599
sammc57ed9f982016-03-10 06:28:35600 void OnChannelError() override { NOTREACHED(); }
[email protected]64860882014-08-04 23:44:17601
[email protected]64860882014-08-04 23:44:17602 void set_sender(IPC::Sender* sender) { sender_ = sender; }
603
604 private:
605 IPC::Sender* sender_;
606};
607
amistry0027a0952016-05-03 00:52:47608TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:04609 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:17610
611 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:24612 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17613 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17614
morrita81b17e02015-02-06 00:58:30615 base::File file(HandleSendingHelper::GetSendingFilePath(),
[email protected]64860882014-08-04 23:44:17616 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:30617 base::File::FLAG_READ);
618 HandleSendingHelper::WriteFileThenSend(channel(), file);
[email protected]64860882014-08-04 23:44:17619 base::MessageLoop::current()->Run();
620
sammc57ed9f982016-03-10 06:28:35621 channel()->Close();
[email protected]64860882014-08-04 23:44:17622
623 EXPECT_TRUE(WaitForClientShutdown());
624 DestroyChannel();
625}
626
sammc57ed9f982016-03-10 06:28:35627DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformHandleClient,
628 ChannelClient) {
[email protected]64860882014-08-04 23:44:17629 ListenerThatExpectsFile listener;
sammc57ed9f982016-03-10 06:28:35630 Connect(&listener);
631 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:17632
633 base::MessageLoop::current()->Run();
634
sammc57ed9f982016-03-10 06:28:35635 Close();
[email protected]64860882014-08-04 23:44:17636}
morrita81b17e02015-02-06 00:58:30637
638class ListenerThatExpectsFileAndPipe : public IPC::Listener {
639 public:
640 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
641
642 ~ListenerThatExpectsFileAndPipe() override {}
643
644 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25645 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30646 HandleSendingHelper::ReadReceivedFile(message, &iter);
647 HandleSendingHelper::ReadReceivedPipe(message, &iter);
ki.stfua21ed8c2015-10-12 17:26:00648 base::MessageLoop::current()->QuitWhenIdle();
morrita81b17e02015-02-06 00:58:30649 ListenerThatExpectsOK::SendOK(sender_);
650 return true;
651 }
652
653 void OnChannelError() override { NOTREACHED(); }
654
655 void set_sender(IPC::Sender* sender) { sender_ = sender; }
656
657 private:
658 IPC::Sender* sender_;
659};
660
amistry0027a0952016-05-03 00:52:47661TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:04662 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:30663
664 ListenerThatExpectsOK listener;
665 CreateChannel(&listener);
666 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30667
668 base::File file(HandleSendingHelper::GetSendingFilePath(),
669 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
670 base::File::FLAG_READ);
671 TestingMessagePipe pipe;
672 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
673
674 base::MessageLoop::current()->Run();
sammc57ed9f982016-03-10 06:28:35675 channel()->Close();
morrita81b17e02015-02-06 00:58:30676
677 EXPECT_TRUE(WaitForClientShutdown());
678 DestroyChannel();
679}
680
sammc57ed9f982016-03-10 06:28:35681DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
682 IPCChannelMojoTestSendPlatformHandleAndPipeClient,
683 ChannelClient) {
morrita81b17e02015-02-06 00:58:30684 ListenerThatExpectsFileAndPipe listener;
sammc57ed9f982016-03-10 06:28:35685 Connect(&listener);
686 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30687
688 base::MessageLoop::current()->Run();
689
sammc57ed9f982016-03-10 06:28:35690 Close();
morrita81b17e02015-02-06 00:58:30691}
692
[email protected]64860882014-08-04 23:44:17693#endif
694
morrita0bd20bd2015-02-25 20:11:27695#if defined(OS_LINUX)
696
697const base::ProcessId kMagicChildId = 54321;
698
699class ListenerThatVerifiesPeerPid : public IPC::Listener {
700 public:
tfarina10a5c062015-09-04 18:47:57701 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:27702 EXPECT_EQ(peer_pid, kMagicChildId);
ki.stfua21ed8c2015-10-12 17:26:00703 base::MessageLoop::current()->QuitWhenIdle();
morrita0bd20bd2015-02-25 20:11:27704 }
705
706 bool OnMessageReceived(const IPC::Message& message) override {
707 NOTREACHED();
708 return true;
709 }
710};
711
sammc57ed9f982016-03-10 06:28:35712TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:04713 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:27714
715 ListenerThatVerifiesPeerPid listener;
716 CreateChannel(&listener);
717 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:27718
719 base::MessageLoop::current()->Run();
rockotcbca72f2015-03-03 16:31:04720 channel()->Close();
morrita0bd20bd2015-02-25 20:11:27721
722 EXPECT_TRUE(WaitForClientShutdown());
723 DestroyChannel();
724}
725
sammc57ed9f982016-03-10 06:28:35726DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient,
727 ChannelClient) {
morrita0bd20bd2015-02-25 20:11:27728 IPC::Channel::SetGlobalPid(kMagicChildId);
729 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35730 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:27731
732 base::MessageLoop::current()->Run();
733
sammc57ed9f982016-03-10 06:28:35734 Close();
morrita0bd20bd2015-02-25 20:11:27735}
736
sammc57ed9f982016-03-10 06:28:35737#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:27738
[email protected]64860882014-08-04 23:44:17739} // namespace