blob: aecb0c62f5c6ac253ff70a7a680e9b0529521d6c [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"
amistry20e2b1d62016-06-23 06:12:3514#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2115#include "base/location.h"
[email protected]64860882014-08-04 23:44:1716#include "base/path_service.h"
17#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0418#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2119#include "base/single_thread_task_runner.h"
sammc57ed9f982016-03-10 06:28:3520#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2721#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1722#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1123#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0424#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1725#include "ipc/ipc_message.h"
26#include "ipc/ipc_test_base.h"
27#include "ipc/ipc_test_channel_listener.h"
sammc57ed9f982016-03-10 06:28:3528#include "ipc/mojo/ipc_channel_mojo.h"
morrita81b17e02015-02-06 00:58:3029#include "ipc/mojo/ipc_mojo_handle_attachment.h"
30#include "ipc/mojo/ipc_mojo_message_helper.h"
morrita438a2ee2015-04-03 05:28:2131#include "ipc/mojo/ipc_mojo_param_traits.h"
sammc57ed9f982016-03-10 06:28:3532#include "mojo/edk/test/mojo_test_base.h"
33#include "mojo/edk/test/multiprocess_test_helper.h"
34#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1735
36#if defined(OS_POSIX)
37#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4238#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1739#endif
40
sammc57ed9f982016-03-10 06:28:3541#define DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(client_name, test_base) \
42 class client_name##_MainFixture : public test_base { \
43 public: \
44 void Main(); \
45 }; \
46 MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
47 client_name##TestChildMain, \
48 ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \
49 CHECK(!mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token \
50 .empty()); \
51 client_name##_MainFixture test; \
52 test.Init(mojo::edk::CreateChildMessagePipe( \
53 mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token)); \
54 test.Main(); \
55 return (::testing::Test::HasFatalFailure() || \
56 ::testing::Test::HasNonfatalFailure()) \
57 ? 1 \
58 : 0; \
59 } \
60 void client_name##_MainFixture::Main()
61
[email protected]64860882014-08-04 23:44:1762namespace {
63
64class ListenerThatExpectsOK : public IPC::Listener {
65 public:
sammc57ed9f982016-03-10 06:28:3566 ListenerThatExpectsOK() : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1767
dchengfe61fca2014-10-22 02:29:5268 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1769
dchengfe61fca2014-10-22 02:29:5270 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2571 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1772 std::string should_be_ok;
73 EXPECT_TRUE(iter.ReadString(&should_be_ok));
74 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1375 received_ok_ = true;
ki.stfua21ed8c2015-10-12 17:26:0076 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:1777 return true;
78 }
79
dchengfe61fca2014-10-22 02:29:5280 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1381 // The connection should be healthy while the listener is waiting
82 // message. An error can occur after that because the peer
83 // process dies.
84 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1785 }
86
87 static void SendOK(IPC::Sender* sender) {
sammc57ed9f982016-03-10 06:28:3588 IPC::Message* message =
89 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
[email protected]64860882014-08-04 23:44:1790 message->WriteString(std::string("OK"));
91 ASSERT_TRUE(sender->Send(message));
92 }
[email protected]e5c27752014-08-08 21:45:1393
94 private:
95 bool received_ok_;
[email protected]64860882014-08-04 23:44:1796};
97
[email protected]64860882014-08-04 23:44:1798class ChannelClient {
99 public:
sammc57ed9f982016-03-10 06:28:35100 void Init(mojo::ScopedMessagePipeHandle handle) {
101 handle_ = std::move(handle);
tsergeant896012862016-03-10 03:51:33102 }
sammc57ed9f982016-03-10 06:28:35103 void Connect(IPC::Listener* listener) {
104 channel_ = IPC::ChannelMojo::Create(std::move(handle_),
105 IPC::Channel::MODE_CLIENT, listener);
[email protected]64860882014-08-04 23:44:17106 CHECK(channel_->Connect());
107 }
108
rockotcbca72f2015-03-03 16:31:04109 void Close() {
110 channel_->Close();
111
112 base::RunLoop run_loop;
skyostile687bdff2015-05-12 11:29:21113 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
114 run_loop.QuitClosure());
rockotcbca72f2015-03-03 16:31:04115 run_loop.Run();
116 }
117
[email protected]64860882014-08-04 23:44:17118 IPC::ChannelMojo* channel() const { return channel_.get(); }
119
120 private:
[email protected]64860882014-08-04 23:44:17121 base::MessageLoopForIO main_message_loop_;
sammc57ed9f982016-03-10 06:28:35122 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09123 std::unique_ptr<IPC::ChannelMojo> channel_;
[email protected]64860882014-08-04 23:44:17124};
125
sammc57ed9f982016-03-10 06:28:35126class IPCChannelMojoTest : public testing::Test {
rockotcbca72f2015-03-03 16:31:04127 public:
sammc57ed9f982016-03-10 06:28:35128 IPCChannelMojoTest() : io_thread_(base::TestIOThread::Mode::kAutoStart) {}
129
130 void TearDown() override { base::RunLoop().RunUntilIdle(); }
131
rockotcbca72f2015-03-03 16:31:04132 void InitWithMojo(const std::string& test_client_name) {
sammc57ed9f982016-03-10 06:28:35133 handle_ = helper_.StartChild(test_client_name);
rockotcbca72f2015-03-03 16:31:04134 }
135
sammc57ed9f982016-03-10 06:28:35136 void CreateChannel(IPC::Listener* listener) {
137 channel_ = IPC::ChannelMojo::Create(std::move(handle_),
138 IPC::Channel::MODE_SERVER, listener);
rockotcbca72f2015-03-03 16:31:04139 }
sammc57ed9f982016-03-10 06:28:35140
141 bool ConnectChannel() { return channel_->Connect(); }
142
143 void DestroyChannel() { channel_.reset(); }
144
145 bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); }
146
147 IPC::Sender* sender() { return channel(); }
148 IPC::Channel* channel() { return channel_.get(); }
149
150 private:
151 base::MessageLoop message_loop_;
152 base::TestIOThread io_thread_;
153 mojo::edk::test::MultiprocessTestHelper helper_;
154 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09155 std::unique_ptr<IPC::Channel> channel_;
rockotcbca72f2015-03-03 16:31:04156};
157
[email protected]64860882014-08-04 23:44:17158class TestChannelListenerWithExtraExpectations
159 : public IPC::TestChannelListener {
160 public:
sammc57ed9f982016-03-10 06:28:35161 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17162
tfarina10a5c062015-09-04 18:47:57163 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17164 IPC::TestChannelListener::OnChannelConnected(peer_pid);
165 EXPECT_TRUE(base::kNullProcessId != peer_pid);
166 is_connected_called_ = true;
167 }
168
169 bool is_connected_called() const { return is_connected_called_; }
170
171 private:
172 bool is_connected_called_;
173};
174
amistry0027a0952016-05-03 00:52:47175TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04176 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17177
178 // Set up IPC channel and start client.
179 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24180 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17181 listener.Init(sender());
182 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17183
sammc57ed9f982016-03-10 06:28:35184 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17185
fdoray8e32586852016-06-22 19:56:16186 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17187
sammc57ed9f982016-03-10 06:28:35188 channel()->Close();
[email protected]64860882014-08-04 23:44:17189
190 EXPECT_TRUE(WaitForClientShutdown());
191 EXPECT_TRUE(listener.is_connected_called());
192 EXPECT_TRUE(listener.HasSentAll());
193
194 DestroyChannel();
195}
196
197// A long running process that connects to us
sammc57ed9f982016-03-10 06:28:35198DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient, ChannelClient) {
[email protected]64860882014-08-04 23:44:17199 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35200 Connect(&listener);
201 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17202
sammc57ed9f982016-03-10 06:28:35203 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16204 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17205 EXPECT_TRUE(listener.is_connected_called());
206 EXPECT_TRUE(listener.HasSentAll());
207
sammc57ed9f982016-03-10 06:28:35208 Close();
[email protected]64860882014-08-04 23:44:17209}
210
morrita0a24cfc92014-09-16 03:20:48211class ListenerExpectingErrors : public IPC::Listener {
212 public:
sammc57ed9f982016-03-10 06:28:35213 ListenerExpectingErrors() : has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48214
tfarina10a5c062015-09-04 18:47:57215 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00216 base::MessageLoop::current()->QuitWhenIdle();
morritabe6c4cc2014-09-24 23:38:44217 }
218
dchengfe61fca2014-10-22 02:29:52219 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48220
dchengfe61fca2014-10-22 02:29:52221 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48222 has_error_ = true;
ki.stfua21ed8c2015-10-12 17:26:00223 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48224 }
225
226 bool has_error() const { return has_error_; }
227
228 private:
229 bool has_error_;
230};
231
morrita0a24cfc92014-09-16 03:20:48232class ListenerThatQuits : public IPC::Listener {
233 public:
sammc57ed9f982016-03-10 06:28:35234 ListenerThatQuits() {}
morrita0a24cfc92014-09-16 03:20:48235
sammc57ed9f982016-03-10 06:28:35236 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48237
tfarina10a5c062015-09-04 18:47:57238 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00239 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48240 }
241};
242
243// A long running process that connects to us.
sammc57ed9f982016-03-10 06:28:35244DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient,
245 ChannelClient) {
morrita0a24cfc92014-09-16 03:20:48246 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35247 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48248
fdoray8e32586852016-06-22 19:56:16249 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48250
sammc57ed9f982016-03-10 06:28:35251 Close();
morrita0a24cfc92014-09-16 03:20:48252}
253
amistry0027a0952016-05-03 00:52:47254TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04255 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48256
257 // Set up IPC channel and start client.
258 ListenerExpectingErrors listener;
259 CreateChannel(&listener);
260 ASSERT_TRUE(ConnectChannel());
261
jamesra03ae492014-10-03 04:26:48262 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44263 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
264 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48265 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44266 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35267 IPC::TestChannelListener::SendOneMessage(sender(),
268 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48269 }
270
fdoray8e32586852016-06-22 19:56:16271 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48272
sammc57ed9f982016-03-10 06:28:35273 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48274
275 EXPECT_TRUE(WaitForClientShutdown());
276 EXPECT_TRUE(listener.has_error());
277
278 DestroyChannel();
279}
280
morrita81b17e02015-02-06 00:58:30281struct TestingMessagePipe {
282 TestingMessagePipe() {
283 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
284 }
285
286 mojo::ScopedMessagePipeHandle self;
287 mojo::ScopedMessagePipeHandle peer;
288};
289
290class HandleSendingHelper {
291 public:
292 static std::string GetSendingFileContent() { return "Hello"; }
293
294 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
295 std::string content = HandleSendingHelper::GetSendingFileContent();
296 EXPECT_EQ(MOJO_RESULT_OK,
297 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
298 static_cast<uint32_t>(content.size()),
299 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50300 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
301 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30302 }
303
304 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
305 IPC::Message* message =
306 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
307 WritePipe(message, pipe);
308 ASSERT_TRUE(sender->Send(message));
309 }
310
311 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25312 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30313 mojo::ScopedMessagePipeHandle pipe;
314 EXPECT_TRUE(
315 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
316 std::string content(GetSendingFileContent().size(), ' ');
317
318 uint32_t num_bytes = static_cast<uint32_t>(content.size());
sammc57ed9f982016-03-10 06:28:35319 ASSERT_EQ(MOJO_RESULT_OK,
320 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
321 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita81b17e02015-02-06 00:58:30322 EXPECT_EQ(MOJO_RESULT_OK,
323 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
324 nullptr, 0));
325 EXPECT_EQ(content, GetSendingFileContent());
326 }
327
328#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35329 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
330 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30331 }
332
333 static void WriteFile(IPC::Message* message, base::File& file) {
334 std::string content = GetSendingFileContent();
335 file.WriteAtCurrentPos(content.data(), content.size());
336 file.Flush();
337 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
338 base::ScopedFD(file.TakePlatformFile())));
339 }
340
341 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
342 IPC::Message* message =
343 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
344 WriteFile(message, file);
345 ASSERT_TRUE(sender->Send(message));
346 }
347
348 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
349 base::File& file,
350 TestingMessagePipe* pipe) {
351 IPC::Message* message =
352 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
353 WriteFile(message, file);
354 WritePipe(message, pipe);
355 ASSERT_TRUE(sender->Send(message));
356 }
357
358 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25359 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30360 base::ScopedFD fd;
rockot502c94f2016-02-03 20:20:16361 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30362 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
amistry980a61b2016-06-09 02:51:20363 EXPECT_EQ(IPC::MessageAttachment::TYPE_PLATFORM_FILE,
364 static_cast<IPC::MessageAttachment*>(attachment.get())
365 ->GetType());
rockot502c94f2016-02-03 20:20:16366 base::File file(static_cast<IPC::MessageAttachment*>(attachment.get())
367 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30368 std::string content(GetSendingFileContent().size(), ' ');
369 file.Read(0, &content[0], content.size());
370 EXPECT_EQ(content, GetSendingFileContent());
371 }
372#endif
373};
374
375class ListenerThatExpectsMessagePipe : public IPC::Listener {
376 public:
377 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
378
379 ~ListenerThatExpectsMessagePipe() override {}
380
381 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25382 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30383 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:30384 ListenerThatExpectsOK::SendOK(sender_);
385 return true;
386 }
387
amistry6c70caea2016-06-09 03:08:29388 void OnChannelError() override {
389 base::MessageLoop::current()->QuitWhenIdle();
390 }
morrita81b17e02015-02-06 00:58:30391
392 void set_sender(IPC::Sender* sender) { sender_ = sender; }
393
394 private:
395 IPC::Sender* sender_;
396};
397
amistry0027a0952016-05-03 00:52:47398TEST_F(IPCChannelMojoTest, SendMessagePipe) {
rockotcbca72f2015-03-03 16:31:04399 InitWithMojo("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30400
401 ListenerThatExpectsOK listener;
402 CreateChannel(&listener);
403 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30404
405 TestingMessagePipe pipe;
406 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
407
fdoray8e32586852016-06-22 19:56:16408 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35409 channel()->Close();
morrita81b17e02015-02-06 00:58:30410
411 EXPECT_TRUE(WaitForClientShutdown());
412 DestroyChannel();
413}
414
sammc57ed9f982016-03-10 06:28:35415DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient,
416 ChannelClient) {
morrita81b17e02015-02-06 00:58:30417 ListenerThatExpectsMessagePipe listener;
sammc57ed9f982016-03-10 06:28:35418 Connect(&listener);
419 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30420
fdoray8e32586852016-06-22 19:56:16421 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30422
sammc57ed9f982016-03-10 06:28:35423 Close();
morrita81b17e02015-02-06 00:58:30424}
425
morrita438a2ee2015-04-03 05:28:21426void ReadOK(mojo::MessagePipeHandle pipe) {
427 std::string should_be_ok("xx");
428 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
sammc57ed9f982016-03-10 06:28:35429 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE,
430 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita438a2ee2015-04-03 05:28:21431 CHECK_EQ(MOJO_RESULT_OK,
432 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
433 nullptr, 0));
434 EXPECT_EQ(should_be_ok, std::string("OK"));
435}
436
437void WriteOK(mojo::MessagePipeHandle pipe) {
438 std::string ok("OK");
439 CHECK_EQ(MOJO_RESULT_OK,
440 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
441 nullptr, 0, 0));
442}
443
444class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
445 public:
446 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
447 : sender_(NULL), receiving_valid_(receiving_valid) {}
448
449 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
450
451 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25452 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21453 mojo::MessagePipeHandle handle;
454 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
455 &handle));
456 EXPECT_EQ(handle.is_valid(), receiving_valid_);
457 if (receiving_valid_) {
458 ReadOK(handle);
459 MojoClose(handle.value());
460 }
461
morrita438a2ee2015-04-03 05:28:21462 ListenerThatExpectsOK::SendOK(sender_);
463 return true;
464 }
465
amistry6c70caea2016-06-09 03:08:29466 void OnChannelError() override {
467 base::MessageLoop::current()->QuitWhenIdle();
468 }
469
morrita438a2ee2015-04-03 05:28:21470 void set_sender(IPC::Sender* sender) { sender_ = sender; }
471
472 private:
473 IPC::Sender* sender_;
474 bool receiving_valid_;
475};
476
sammc57ed9f982016-03-10 06:28:35477class ParamTraitMessagePipeClient : public ChannelClient {
478 public:
479 void RunTest(bool receiving_valid_handle) {
480 ListenerThatExpectsMessagePipeUsingParamTrait listener(
481 receiving_valid_handle);
482 Connect(&listener);
483 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21484
fdoray8e32586852016-06-22 19:56:16485 base::RunLoop().Run();
morrita438a2ee2015-04-03 05:28:21486
sammc57ed9f982016-03-10 06:28:35487 Close();
488 }
489};
morrita438a2ee2015-04-03 05:28:21490
amistry0027a0952016-05-03 00:52:47491TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21492 InitWithMojo("ParamTraitValidMessagePipeClient");
493
494 ListenerThatExpectsOK listener;
495 CreateChannel(&listener);
496 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21497
498 TestingMessagePipe pipe;
499
danakj03de39b22016-04-23 04:21:09500 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21501 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
502 pipe.peer.release());
503 WriteOK(pipe.self.get());
504
sammc57ed9f982016-03-10 06:28:35505 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16506 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35507 channel()->Close();
morrita438a2ee2015-04-03 05:28:21508
509 EXPECT_TRUE(WaitForClientShutdown());
510 DestroyChannel();
511}
512
sammc57ed9f982016-03-10 06:28:35513DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitValidMessagePipeClient,
514 ParamTraitMessagePipeClient) {
515 RunTest(true);
morrita438a2ee2015-04-03 05:28:21516}
517
amistry0027a0952016-05-03 00:52:47518TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21519 InitWithMojo("ParamTraitInvalidMessagePipeClient");
520
521 ListenerThatExpectsOK listener;
522 CreateChannel(&listener);
523 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21524
525 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09526 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21527 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
528 invalid_handle);
529
sammc57ed9f982016-03-10 06:28:35530 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16531 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35532 channel()->Close();
morrita438a2ee2015-04-03 05:28:21533
534 EXPECT_TRUE(WaitForClientShutdown());
535 DestroyChannel();
536}
537
sammc57ed9f982016-03-10 06:28:35538DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitInvalidMessagePipeClient,
539 ParamTraitMessagePipeClient) {
540 RunTest(false);
morrita438a2ee2015-04-03 05:28:21541}
542
amistry0027a0952016-05-03 00:52:47543TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
morrita17137e62015-06-23 22:29:36544 InitWithMojo("IPCChannelMojoTestSendOkClient");
545
546 ListenerThatExpectsOK listener;
547 CreateChannel(&listener);
548 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36549
fdoray8e32586852016-06-22 19:56:16550 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35551 channel()->Close();
552 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36553
554 EXPECT_TRUE(WaitForClientShutdown());
555 DestroyChannel();
556}
557
558class ListenerSendingOneOk : public IPC::Listener {
559 public:
sammc57ed9f982016-03-10 06:28:35560 ListenerSendingOneOk() {}
morrita17137e62015-06-23 22:29:36561
sammc57ed9f982016-03-10 06:28:35562 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36563
tfarina10a5c062015-09-04 18:47:57564 void OnChannelConnected(int32_t peer_pid) override {
morrita17137e62015-06-23 22:29:36565 ListenerThatExpectsOK::SendOK(sender_);
ki.stfua21ed8c2015-10-12 17:26:00566 base::MessageLoop::current()->QuitWhenIdle();
morrita17137e62015-06-23 22:29:36567 }
568
569 void set_sender(IPC::Sender* sender) { sender_ = sender; }
570
571 private:
572 IPC::Sender* sender_;
573};
574
sammc57ed9f982016-03-10 06:28:35575DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient,
576 ChannelClient) {
morrita17137e62015-06-23 22:29:36577 ListenerSendingOneOk listener;
sammc57ed9f982016-03-10 06:28:35578 Connect(&listener);
579 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36580
fdoray8e32586852016-06-22 19:56:16581 base::RunLoop().Run();
morrita17137e62015-06-23 22:29:36582
sammc57ed9f982016-03-10 06:28:35583 Close();
morrita17137e62015-06-23 22:29:36584}
585
[email protected]64860882014-08-04 23:44:17586#if defined(OS_POSIX)
587class ListenerThatExpectsFile : public IPC::Listener {
588 public:
sammc57ed9f982016-03-10 06:28:35589 ListenerThatExpectsFile() : sender_(NULL) {}
[email protected]64860882014-08-04 23:44:17590
dchengfe61fca2014-10-22 02:29:52591 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:17592
dchengfe61fca2014-10-22 02:29:52593 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25594 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30595 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:17596 ListenerThatExpectsOK::SendOK(sender_);
597 return true;
598 }
599
amistry6c70caea2016-06-09 03:08:29600 void OnChannelError() override {
601 base::MessageLoop::current()->QuitWhenIdle();
602 }
[email protected]64860882014-08-04 23:44:17603
[email protected]64860882014-08-04 23:44:17604 void set_sender(IPC::Sender* sender) { sender_ = sender; }
605
606 private:
607 IPC::Sender* sender_;
608};
609
amistry0027a0952016-05-03 00:52:47610TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:04611 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:17612
613 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:24614 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17615 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17616
amistry20e2b1d62016-06-23 06:12:35617 base::ScopedTempDir temp_dir;
618 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
619 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.path()),
[email protected]64860882014-08-04 23:44:17620 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:30621 base::File::FLAG_READ);
622 HandleSendingHelper::WriteFileThenSend(channel(), file);
fdoray8e32586852016-06-22 19:56:16623 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17624
sammc57ed9f982016-03-10 06:28:35625 channel()->Close();
[email protected]64860882014-08-04 23:44:17626
627 EXPECT_TRUE(WaitForClientShutdown());
628 DestroyChannel();
629}
630
sammc57ed9f982016-03-10 06:28:35631DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformHandleClient,
632 ChannelClient) {
[email protected]64860882014-08-04 23:44:17633 ListenerThatExpectsFile listener;
sammc57ed9f982016-03-10 06:28:35634 Connect(&listener);
635 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:17636
fdoray8e32586852016-06-22 19:56:16637 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17638
sammc57ed9f982016-03-10 06:28:35639 Close();
[email protected]64860882014-08-04 23:44:17640}
morrita81b17e02015-02-06 00:58:30641
642class ListenerThatExpectsFileAndPipe : public IPC::Listener {
643 public:
644 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
645
646 ~ListenerThatExpectsFileAndPipe() override {}
647
648 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25649 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30650 HandleSendingHelper::ReadReceivedFile(message, &iter);
651 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:30652 ListenerThatExpectsOK::SendOK(sender_);
653 return true;
654 }
655
amistry6c70caea2016-06-09 03:08:29656 void OnChannelError() override {
657 base::MessageLoop::current()->QuitWhenIdle();
658 }
morrita81b17e02015-02-06 00:58:30659
660 void set_sender(IPC::Sender* sender) { sender_ = sender; }
661
662 private:
663 IPC::Sender* sender_;
664};
665
amistry0027a0952016-05-03 00:52:47666TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:04667 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:30668
669 ListenerThatExpectsOK listener;
670 CreateChannel(&listener);
671 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30672
amistry20e2b1d62016-06-23 06:12:35673 base::ScopedTempDir temp_dir;
674 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
675 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.path()),
morrita81b17e02015-02-06 00:58:30676 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
677 base::File::FLAG_READ);
678 TestingMessagePipe pipe;
679 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
680
fdoray8e32586852016-06-22 19:56:16681 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35682 channel()->Close();
morrita81b17e02015-02-06 00:58:30683
684 EXPECT_TRUE(WaitForClientShutdown());
685 DestroyChannel();
686}
687
sammc57ed9f982016-03-10 06:28:35688DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
689 IPCChannelMojoTestSendPlatformHandleAndPipeClient,
690 ChannelClient) {
morrita81b17e02015-02-06 00:58:30691 ListenerThatExpectsFileAndPipe listener;
sammc57ed9f982016-03-10 06:28:35692 Connect(&listener);
693 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30694
fdoray8e32586852016-06-22 19:56:16695 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30696
sammc57ed9f982016-03-10 06:28:35697 Close();
morrita81b17e02015-02-06 00:58:30698}
699
[email protected]64860882014-08-04 23:44:17700#endif
701
morrita0bd20bd2015-02-25 20:11:27702#if defined(OS_LINUX)
703
704const base::ProcessId kMagicChildId = 54321;
705
706class ListenerThatVerifiesPeerPid : public IPC::Listener {
707 public:
tfarina10a5c062015-09-04 18:47:57708 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:27709 EXPECT_EQ(peer_pid, kMagicChildId);
ki.stfua21ed8c2015-10-12 17:26:00710 base::MessageLoop::current()->QuitWhenIdle();
morrita0bd20bd2015-02-25 20:11:27711 }
712
713 bool OnMessageReceived(const IPC::Message& message) override {
714 NOTREACHED();
715 return true;
716 }
717};
718
sammc57ed9f982016-03-10 06:28:35719TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:04720 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:27721
722 ListenerThatVerifiesPeerPid listener;
723 CreateChannel(&listener);
724 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:27725
726 base::MessageLoop::current()->Run();
rockotcbca72f2015-03-03 16:31:04727 channel()->Close();
morrita0bd20bd2015-02-25 20:11:27728
729 EXPECT_TRUE(WaitForClientShutdown());
730 DestroyChannel();
731}
732
sammc57ed9f982016-03-10 06:28:35733DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient,
734 ChannelClient) {
morrita0bd20bd2015-02-25 20:11:27735 IPC::Channel::SetGlobalPid(kMagicChildId);
736 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35737 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:27738
739 base::MessageLoop::current()->Run();
740
sammc57ed9f982016-03-10 06:28:35741 Close();
morrita0bd20bd2015-02-25 20:11:27742}
743
sammc57ed9f982016-03-10 06:28:35744#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:27745
[email protected]64860882014-08-04 23:44:17746} // namespace