blob: e846c132bedc211ddea92863e47718753bafa938 [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
amistryd4aa70d2016-06-23 07:52:375#include "ipc/ipc_channel_mojo.h"
[email protected]64860882014-08-04 23:44:176
avi246998d82015-12-22 02:39:047#include <stddef.h>
tfarina10a5c062015-09-04 18:47:578#include <stdint.h>
rockot7c6bf952016-07-14 00:34:119
danakj03de39b22016-04-23 04:21:0910#include <memory>
dchenge48600452015-12-28 02:24:5011#include <utility>
tfarina10a5c062015-09-04 18:47:5712
[email protected]64860882014-08-04 23:44:1713#include "base/base_paths.h"
14#include "base/files/file.h"
amistry20e2b1d62016-06-23 06:12:3515#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2116#include "base/location.h"
[email protected]64860882014-08-04 23:44:1717#include "base/path_service.h"
18#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0419#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2120#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1121#include "base/strings/stringprintf.h"
sammc57ed9f982016-03-10 06:28:3522#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2723#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1724#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1125#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0426#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1727#include "ipc/ipc_message.h"
amistryd4aa70d2016-06-23 07:52:3728#include "ipc/ipc_mojo_handle_attachment.h"
29#include "ipc/ipc_mojo_message_helper.h"
30#include "ipc/ipc_mojo_param_traits.h"
rockot7c6bf952016-07-14 00:34:1131#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1732#include "ipc/ipc_test_base.h"
33#include "ipc/ipc_test_channel_listener.h"
sammc57ed9f982016-03-10 06:28:3534#include "mojo/edk/test/mojo_test_base.h"
35#include "mojo/edk/test/multiprocess_test_helper.h"
36#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1737
38#if defined(OS_POSIX)
39#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4240#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1741#endif
42
sammc57ed9f982016-03-10 06:28:3543#define DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(client_name, test_base) \
44 class client_name##_MainFixture : public test_base { \
45 public: \
46 void Main(); \
47 }; \
48 MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
49 client_name##TestChildMain, \
50 ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \
51 CHECK(!mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token \
52 .empty()); \
53 client_name##_MainFixture test; \
54 test.Init(mojo::edk::CreateChildMessagePipe( \
55 mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token)); \
56 test.Main(); \
57 return (::testing::Test::HasFatalFailure() || \
58 ::testing::Test::HasNonfatalFailure()) \
59 ? 1 \
60 : 0; \
61 } \
62 void client_name##_MainFixture::Main()
63
[email protected]64860882014-08-04 23:44:1764namespace {
65
rockot7c6bf952016-07-14 00:34:1166void SendString(IPC::Sender* sender, const std::string& str) {
67 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
68 message->WriteString(str);
69 ASSERT_TRUE(sender->Send(message));
70}
71
[email protected]64860882014-08-04 23:44:1772class ListenerThatExpectsOK : public IPC::Listener {
73 public:
sammc57ed9f982016-03-10 06:28:3574 ListenerThatExpectsOK() : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1775
dchengfe61fca2014-10-22 02:29:5276 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1777
dchengfe61fca2014-10-22 02:29:5278 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2579 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1780 std::string should_be_ok;
81 EXPECT_TRUE(iter.ReadString(&should_be_ok));
82 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1383 received_ok_ = true;
ki.stfua21ed8c2015-10-12 17:26:0084 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:1785 return true;
86 }
87
dchengfe61fca2014-10-22 02:29:5288 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1389 // The connection should be healthy while the listener is waiting
90 // message. An error can occur after that because the peer
91 // process dies.
92 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1793 }
94
rockot7c6bf952016-07-14 00:34:1195 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:1396
97 private:
98 bool received_ok_;
[email protected]64860882014-08-04 23:44:1799};
100
[email protected]64860882014-08-04 23:44:17101class ChannelClient {
102 public:
sammc57ed9f982016-03-10 06:28:35103 void Init(mojo::ScopedMessagePipeHandle handle) {
104 handle_ = std::move(handle);
tsergeant896012862016-03-10 03:51:33105 }
sammc57ed9f982016-03-10 06:28:35106 void Connect(IPC::Listener* listener) {
107 channel_ = IPC::ChannelMojo::Create(std::move(handle_),
108 IPC::Channel::MODE_CLIENT, listener);
[email protected]64860882014-08-04 23:44:17109 CHECK(channel_->Connect());
110 }
111
rockotcbca72f2015-03-03 16:31:04112 void Close() {
113 channel_->Close();
114
115 base::RunLoop run_loop;
skyostile687bdff2015-05-12 11:29:21116 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
117 run_loop.QuitClosure());
rockotcbca72f2015-03-03 16:31:04118 run_loop.Run();
119 }
120
[email protected]64860882014-08-04 23:44:17121 IPC::ChannelMojo* channel() const { return channel_.get(); }
122
123 private:
[email protected]64860882014-08-04 23:44:17124 base::MessageLoopForIO main_message_loop_;
sammc57ed9f982016-03-10 06:28:35125 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09126 std::unique_ptr<IPC::ChannelMojo> channel_;
[email protected]64860882014-08-04 23:44:17127};
128
sammc57ed9f982016-03-10 06:28:35129class IPCChannelMojoTest : public testing::Test {
rockotcbca72f2015-03-03 16:31:04130 public:
rockot7c6bf952016-07-14 00:34:11131 IPCChannelMojoTest() {}
sammc57ed9f982016-03-10 06:28:35132
133 void TearDown() override { base::RunLoop().RunUntilIdle(); }
134
rockotcbca72f2015-03-03 16:31:04135 void InitWithMojo(const std::string& test_client_name) {
sammc57ed9f982016-03-10 06:28:35136 handle_ = helper_.StartChild(test_client_name);
rockotcbca72f2015-03-03 16:31:04137 }
138
sammc57ed9f982016-03-10 06:28:35139 void CreateChannel(IPC::Listener* listener) {
140 channel_ = IPC::ChannelMojo::Create(std::move(handle_),
141 IPC::Channel::MODE_SERVER, listener);
rockotcbca72f2015-03-03 16:31:04142 }
sammc57ed9f982016-03-10 06:28:35143
144 bool ConnectChannel() { return channel_->Connect(); }
145
146 void DestroyChannel() { channel_.reset(); }
147
148 bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); }
149
150 IPC::Sender* sender() { return channel(); }
151 IPC::Channel* channel() { return channel_.get(); }
152
153 private:
154 base::MessageLoop message_loop_;
sammc57ed9f982016-03-10 06:28:35155 mojo::edk::test::MultiprocessTestHelper helper_;
156 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09157 std::unique_ptr<IPC::Channel> channel_;
rockotcbca72f2015-03-03 16:31:04158};
159
[email protected]64860882014-08-04 23:44:17160class TestChannelListenerWithExtraExpectations
161 : public IPC::TestChannelListener {
162 public:
sammc57ed9f982016-03-10 06:28:35163 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17164
tfarina10a5c062015-09-04 18:47:57165 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17166 IPC::TestChannelListener::OnChannelConnected(peer_pid);
167 EXPECT_TRUE(base::kNullProcessId != peer_pid);
168 is_connected_called_ = true;
169 }
170
171 bool is_connected_called() const { return is_connected_called_; }
172
173 private:
174 bool is_connected_called_;
175};
176
amistry0027a0952016-05-03 00:52:47177TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04178 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17179
180 // Set up IPC channel and start client.
181 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24182 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17183 listener.Init(sender());
184 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17185
sammc57ed9f982016-03-10 06:28:35186 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17187
fdoray8e32586852016-06-22 19:56:16188 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17189
sammc57ed9f982016-03-10 06:28:35190 channel()->Close();
[email protected]64860882014-08-04 23:44:17191
192 EXPECT_TRUE(WaitForClientShutdown());
193 EXPECT_TRUE(listener.is_connected_called());
194 EXPECT_TRUE(listener.HasSentAll());
195
196 DestroyChannel();
197}
198
199// A long running process that connects to us
sammc57ed9f982016-03-10 06:28:35200DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient, ChannelClient) {
[email protected]64860882014-08-04 23:44:17201 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35202 Connect(&listener);
203 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17204
sammc57ed9f982016-03-10 06:28:35205 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16206 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17207 EXPECT_TRUE(listener.is_connected_called());
208 EXPECT_TRUE(listener.HasSentAll());
209
sammc57ed9f982016-03-10 06:28:35210 Close();
[email protected]64860882014-08-04 23:44:17211}
212
morrita0a24cfc92014-09-16 03:20:48213class ListenerExpectingErrors : public IPC::Listener {
214 public:
sammc57ed9f982016-03-10 06:28:35215 ListenerExpectingErrors() : has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48216
tfarina10a5c062015-09-04 18:47:57217 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00218 base::MessageLoop::current()->QuitWhenIdle();
morritabe6c4cc2014-09-24 23:38:44219 }
220
dchengfe61fca2014-10-22 02:29:52221 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48222
dchengfe61fca2014-10-22 02:29:52223 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48224 has_error_ = true;
ki.stfua21ed8c2015-10-12 17:26:00225 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48226 }
227
228 bool has_error() const { return has_error_; }
229
230 private:
231 bool has_error_;
232};
233
morrita0a24cfc92014-09-16 03:20:48234class ListenerThatQuits : public IPC::Listener {
235 public:
sammc57ed9f982016-03-10 06:28:35236 ListenerThatQuits() {}
morrita0a24cfc92014-09-16 03:20:48237
sammc57ed9f982016-03-10 06:28:35238 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48239
tfarina10a5c062015-09-04 18:47:57240 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00241 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48242 }
243};
244
245// A long running process that connects to us.
sammc57ed9f982016-03-10 06:28:35246DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient,
247 ChannelClient) {
morrita0a24cfc92014-09-16 03:20:48248 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35249 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48250
fdoray8e32586852016-06-22 19:56:16251 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48252
sammc57ed9f982016-03-10 06:28:35253 Close();
morrita0a24cfc92014-09-16 03:20:48254}
255
amistry0027a0952016-05-03 00:52:47256TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04257 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48258
259 // Set up IPC channel and start client.
260 ListenerExpectingErrors listener;
261 CreateChannel(&listener);
262 ASSERT_TRUE(ConnectChannel());
263
jamesra03ae492014-10-03 04:26:48264 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44265 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
266 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48267 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44268 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35269 IPC::TestChannelListener::SendOneMessage(sender(),
270 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48271 }
272
fdoray8e32586852016-06-22 19:56:16273 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48274
sammc57ed9f982016-03-10 06:28:35275 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48276
277 EXPECT_TRUE(WaitForClientShutdown());
278 EXPECT_TRUE(listener.has_error());
279
280 DestroyChannel();
281}
282
morrita81b17e02015-02-06 00:58:30283struct TestingMessagePipe {
284 TestingMessagePipe() {
285 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
286 }
287
288 mojo::ScopedMessagePipeHandle self;
289 mojo::ScopedMessagePipeHandle peer;
290};
291
292class HandleSendingHelper {
293 public:
294 static std::string GetSendingFileContent() { return "Hello"; }
295
296 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
297 std::string content = HandleSendingHelper::GetSendingFileContent();
298 EXPECT_EQ(MOJO_RESULT_OK,
299 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
300 static_cast<uint32_t>(content.size()),
301 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50302 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
303 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30304 }
305
306 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
307 IPC::Message* message =
308 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
309 WritePipe(message, pipe);
310 ASSERT_TRUE(sender->Send(message));
311 }
312
313 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25314 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30315 mojo::ScopedMessagePipeHandle pipe;
316 EXPECT_TRUE(
317 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
318 std::string content(GetSendingFileContent().size(), ' ');
319
320 uint32_t num_bytes = static_cast<uint32_t>(content.size());
sammc57ed9f982016-03-10 06:28:35321 ASSERT_EQ(MOJO_RESULT_OK,
322 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
323 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita81b17e02015-02-06 00:58:30324 EXPECT_EQ(MOJO_RESULT_OK,
325 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
326 nullptr, 0));
327 EXPECT_EQ(content, GetSendingFileContent());
328 }
329
330#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35331 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
332 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30333 }
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);
morrita81b17e02015-02-06 00:58:30386 ListenerThatExpectsOK::SendOK(sender_);
387 return true;
388 }
389
amistry6c70caea2016-06-09 03:08:29390 void OnChannelError() override {
391 base::MessageLoop::current()->QuitWhenIdle();
392 }
morrita81b17e02015-02-06 00:58:30393
394 void set_sender(IPC::Sender* sender) { sender_ = sender; }
395
396 private:
397 IPC::Sender* sender_;
398};
399
amistry0027a0952016-05-03 00:52:47400TEST_F(IPCChannelMojoTest, SendMessagePipe) {
rockotcbca72f2015-03-03 16:31:04401 InitWithMojo("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30402
403 ListenerThatExpectsOK listener;
404 CreateChannel(&listener);
405 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30406
407 TestingMessagePipe pipe;
408 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
409
fdoray8e32586852016-06-22 19:56:16410 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35411 channel()->Close();
morrita81b17e02015-02-06 00:58:30412
413 EXPECT_TRUE(WaitForClientShutdown());
414 DestroyChannel();
415}
416
sammc57ed9f982016-03-10 06:28:35417DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient,
418 ChannelClient) {
morrita81b17e02015-02-06 00:58:30419 ListenerThatExpectsMessagePipe listener;
sammc57ed9f982016-03-10 06:28:35420 Connect(&listener);
421 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30422
fdoray8e32586852016-06-22 19:56:16423 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30424
sammc57ed9f982016-03-10 06:28:35425 Close();
morrita81b17e02015-02-06 00:58:30426}
427
morrita438a2ee2015-04-03 05:28:21428void ReadOK(mojo::MessagePipeHandle pipe) {
429 std::string should_be_ok("xx");
430 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
sammc57ed9f982016-03-10 06:28:35431 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE,
432 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita438a2ee2015-04-03 05:28:21433 CHECK_EQ(MOJO_RESULT_OK,
434 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
435 nullptr, 0));
436 EXPECT_EQ(should_be_ok, std::string("OK"));
437}
438
439void WriteOK(mojo::MessagePipeHandle pipe) {
440 std::string ok("OK");
441 CHECK_EQ(MOJO_RESULT_OK,
442 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
443 nullptr, 0, 0));
444}
445
446class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
447 public:
448 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
449 : sender_(NULL), receiving_valid_(receiving_valid) {}
450
451 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
452
453 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25454 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21455 mojo::MessagePipeHandle handle;
456 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
457 &handle));
458 EXPECT_EQ(handle.is_valid(), receiving_valid_);
459 if (receiving_valid_) {
460 ReadOK(handle);
461 MojoClose(handle.value());
462 }
463
morrita438a2ee2015-04-03 05:28:21464 ListenerThatExpectsOK::SendOK(sender_);
465 return true;
466 }
467
amistry6c70caea2016-06-09 03:08:29468 void OnChannelError() override {
469 base::MessageLoop::current()->QuitWhenIdle();
470 }
471
morrita438a2ee2015-04-03 05:28:21472 void set_sender(IPC::Sender* sender) { sender_ = sender; }
473
474 private:
475 IPC::Sender* sender_;
476 bool receiving_valid_;
477};
478
sammc57ed9f982016-03-10 06:28:35479class ParamTraitMessagePipeClient : public ChannelClient {
480 public:
481 void RunTest(bool receiving_valid_handle) {
482 ListenerThatExpectsMessagePipeUsingParamTrait listener(
483 receiving_valid_handle);
484 Connect(&listener);
485 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21486
fdoray8e32586852016-06-22 19:56:16487 base::RunLoop().Run();
morrita438a2ee2015-04-03 05:28:21488
sammc57ed9f982016-03-10 06:28:35489 Close();
490 }
491};
morrita438a2ee2015-04-03 05:28:21492
amistry0027a0952016-05-03 00:52:47493TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21494 InitWithMojo("ParamTraitValidMessagePipeClient");
495
496 ListenerThatExpectsOK listener;
497 CreateChannel(&listener);
498 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21499
500 TestingMessagePipe pipe;
501
danakj03de39b22016-04-23 04:21:09502 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21503 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
504 pipe.peer.release());
505 WriteOK(pipe.self.get());
506
sammc57ed9f982016-03-10 06:28:35507 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16508 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35509 channel()->Close();
morrita438a2ee2015-04-03 05:28:21510
511 EXPECT_TRUE(WaitForClientShutdown());
512 DestroyChannel();
513}
514
sammc57ed9f982016-03-10 06:28:35515DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitValidMessagePipeClient,
516 ParamTraitMessagePipeClient) {
517 RunTest(true);
morrita438a2ee2015-04-03 05:28:21518}
519
amistry0027a0952016-05-03 00:52:47520TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21521 InitWithMojo("ParamTraitInvalidMessagePipeClient");
522
523 ListenerThatExpectsOK listener;
524 CreateChannel(&listener);
525 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21526
527 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09528 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21529 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
530 invalid_handle);
531
sammc57ed9f982016-03-10 06:28:35532 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16533 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35534 channel()->Close();
morrita438a2ee2015-04-03 05:28:21535
536 EXPECT_TRUE(WaitForClientShutdown());
537 DestroyChannel();
538}
539
sammc57ed9f982016-03-10 06:28:35540DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitInvalidMessagePipeClient,
541 ParamTraitMessagePipeClient) {
542 RunTest(false);
morrita438a2ee2015-04-03 05:28:21543}
544
amistry0027a0952016-05-03 00:52:47545TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
morrita17137e62015-06-23 22:29:36546 InitWithMojo("IPCChannelMojoTestSendOkClient");
547
548 ListenerThatExpectsOK listener;
549 CreateChannel(&listener);
550 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36551
fdoray8e32586852016-06-22 19:56:16552 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35553 channel()->Close();
554 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36555
556 EXPECT_TRUE(WaitForClientShutdown());
557 DestroyChannel();
558}
559
560class ListenerSendingOneOk : public IPC::Listener {
561 public:
sammc57ed9f982016-03-10 06:28:35562 ListenerSendingOneOk() {}
morrita17137e62015-06-23 22:29:36563
sammc57ed9f982016-03-10 06:28:35564 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36565
tfarina10a5c062015-09-04 18:47:57566 void OnChannelConnected(int32_t peer_pid) override {
morrita17137e62015-06-23 22:29:36567 ListenerThatExpectsOK::SendOK(sender_);
ki.stfua21ed8c2015-10-12 17:26:00568 base::MessageLoop::current()->QuitWhenIdle();
morrita17137e62015-06-23 22:29:36569 }
570
571 void set_sender(IPC::Sender* sender) { sender_ = sender; }
572
573 private:
574 IPC::Sender* sender_;
575};
576
sammc57ed9f982016-03-10 06:28:35577DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient,
578 ChannelClient) {
morrita17137e62015-06-23 22:29:36579 ListenerSendingOneOk listener;
sammc57ed9f982016-03-10 06:28:35580 Connect(&listener);
581 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36582
fdoray8e32586852016-06-22 19:56:16583 base::RunLoop().Run();
morrita17137e62015-06-23 22:29:36584
sammc57ed9f982016-03-10 06:28:35585 Close();
morrita17137e62015-06-23 22:29:36586}
587
rockot7c6bf952016-07-14 00:34:11588class ListenerWithSimpleAssociatedInterface
589 : public IPC::Listener,
590 public IPC::mojom::SimpleTestDriver {
591 public:
592 static const int kNumMessages;
593
594 ListenerWithSimpleAssociatedInterface() : binding_(this) {}
595
596 ~ListenerWithSimpleAssociatedInterface() override {}
597
598 bool OnMessageReceived(const IPC::Message& message) override {
599 base::PickleIterator iter(message);
600 std::string should_be_expected;
601 EXPECT_TRUE(iter.ReadString(&should_be_expected));
602 EXPECT_EQ(should_be_expected, next_expected_string_);
603 num_messages_received_++;
604 return true;
605 }
606
607 void OnChannelError() override {
608 DCHECK(received_quit_);
609 }
610
611 void RegisterInterfaceFactory(IPC::Channel* channel) {
612 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
613 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest,
614 base::Unretained(this)));
615 }
616
617 private:
618 // IPC::mojom::SimpleTestDriver:
619 void ExpectString(const mojo::String& str) override {
620 next_expected_string_ = str;
621 }
622
623 void RequestQuit(const RequestQuitCallback& callback) override {
624 EXPECT_EQ(kNumMessages, num_messages_received_);
625 received_quit_ = true;
626 callback.Run();
627 base::MessageLoop::current()->QuitWhenIdle();
628 }
629
630 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
631 DCHECK(!binding_.is_bound());
632 binding_.Bind(std::move(request));
633 }
634
635 std::string next_expected_string_;
636 int num_messages_received_ = 0;
637 bool received_quit_ = false;
638
639 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
640};
641
642const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
643
644class ListenerSendingAssociatedMessages : public IPC::Listener {
645 public:
646 ListenerSendingAssociatedMessages() {}
647
648 bool OnMessageReceived(const IPC::Message& message) override { return true; }
649
650 void OnChannelConnected(int32_t peer_pid) override {
651 DCHECK(channel_);
652 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
653 &driver_);
654
655 // Send a bunch of interleaved messages, alternating between the associated
656 // interface and a legacy IPC::Message.
657 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
658 ++i) {
659 std::string str = base::StringPrintf("Hello! %d", i);
660 driver_->ExpectString(str);
661 SendString(channel_, str);
662 }
663 driver_->RequestQuit(base::Bind(&OnQuitAck));
664 }
665
666 void set_channel(IPC::Channel* channel) { channel_ = channel; }
667
668 private:
669 static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); }
670
671 IPC::Channel* channel_ = nullptr;
672 IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
673};
674
675TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
676 InitWithMojo("SimpleAssociatedInterfaceClient");
677
678 ListenerWithSimpleAssociatedInterface listener;
679 CreateChannel(&listener);
680 ASSERT_TRUE(ConnectChannel());
681
682 listener.RegisterInterfaceFactory(channel());
683
684 base::RunLoop().Run();
685 channel()->Close();
686
687 EXPECT_TRUE(WaitForClientShutdown());
688 DestroyChannel();
689}
690
691DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient,
692 ChannelClient) {
693 ListenerSendingAssociatedMessages listener;
694 Connect(&listener);
695 listener.set_channel(channel());
696
697 base::RunLoop().Run();
698
699 Close();
700}
701
[email protected]64860882014-08-04 23:44:17702#if defined(OS_POSIX)
703class ListenerThatExpectsFile : public IPC::Listener {
704 public:
sammc57ed9f982016-03-10 06:28:35705 ListenerThatExpectsFile() : sender_(NULL) {}
[email protected]64860882014-08-04 23:44:17706
dchengfe61fca2014-10-22 02:29:52707 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:17708
dchengfe61fca2014-10-22 02:29:52709 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25710 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30711 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:17712 ListenerThatExpectsOK::SendOK(sender_);
713 return true;
714 }
715
amistry6c70caea2016-06-09 03:08:29716 void OnChannelError() override {
717 base::MessageLoop::current()->QuitWhenIdle();
718 }
[email protected]64860882014-08-04 23:44:17719
[email protected]64860882014-08-04 23:44:17720 void set_sender(IPC::Sender* sender) { sender_ = sender; }
721
722 private:
723 IPC::Sender* sender_;
724};
725
amistry0027a0952016-05-03 00:52:47726TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:04727 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:17728
729 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:24730 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17731 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17732
amistry20e2b1d62016-06-23 06:12:35733 base::ScopedTempDir temp_dir;
734 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
735 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.path()),
[email protected]64860882014-08-04 23:44:17736 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:30737 base::File::FLAG_READ);
738 HandleSendingHelper::WriteFileThenSend(channel(), file);
fdoray8e32586852016-06-22 19:56:16739 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17740
sammc57ed9f982016-03-10 06:28:35741 channel()->Close();
[email protected]64860882014-08-04 23:44:17742
743 EXPECT_TRUE(WaitForClientShutdown());
744 DestroyChannel();
745}
746
sammc57ed9f982016-03-10 06:28:35747DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformHandleClient,
748 ChannelClient) {
[email protected]64860882014-08-04 23:44:17749 ListenerThatExpectsFile listener;
sammc57ed9f982016-03-10 06:28:35750 Connect(&listener);
751 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:17752
fdoray8e32586852016-06-22 19:56:16753 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17754
sammc57ed9f982016-03-10 06:28:35755 Close();
[email protected]64860882014-08-04 23:44:17756}
morrita81b17e02015-02-06 00:58:30757
758class ListenerThatExpectsFileAndPipe : public IPC::Listener {
759 public:
760 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
761
762 ~ListenerThatExpectsFileAndPipe() override {}
763
764 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25765 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30766 HandleSendingHelper::ReadReceivedFile(message, &iter);
767 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:30768 ListenerThatExpectsOK::SendOK(sender_);
769 return true;
770 }
771
amistry6c70caea2016-06-09 03:08:29772 void OnChannelError() override {
773 base::MessageLoop::current()->QuitWhenIdle();
774 }
morrita81b17e02015-02-06 00:58:30775
776 void set_sender(IPC::Sender* sender) { sender_ = sender; }
777
778 private:
779 IPC::Sender* sender_;
780};
781
amistry0027a0952016-05-03 00:52:47782TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:04783 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:30784
785 ListenerThatExpectsOK listener;
786 CreateChannel(&listener);
787 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30788
amistry20e2b1d62016-06-23 06:12:35789 base::ScopedTempDir temp_dir;
790 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
791 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.path()),
morrita81b17e02015-02-06 00:58:30792 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
793 base::File::FLAG_READ);
794 TestingMessagePipe pipe;
795 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
796
fdoray8e32586852016-06-22 19:56:16797 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35798 channel()->Close();
morrita81b17e02015-02-06 00:58:30799
800 EXPECT_TRUE(WaitForClientShutdown());
801 DestroyChannel();
802}
803
sammc57ed9f982016-03-10 06:28:35804DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
805 IPCChannelMojoTestSendPlatformHandleAndPipeClient,
806 ChannelClient) {
morrita81b17e02015-02-06 00:58:30807 ListenerThatExpectsFileAndPipe listener;
sammc57ed9f982016-03-10 06:28:35808 Connect(&listener);
809 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30810
fdoray8e32586852016-06-22 19:56:16811 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30812
sammc57ed9f982016-03-10 06:28:35813 Close();
morrita81b17e02015-02-06 00:58:30814}
815
rockot7c6bf952016-07-14 00:34:11816#endif // defined(OS_POSIX)
[email protected]64860882014-08-04 23:44:17817
morrita0bd20bd2015-02-25 20:11:27818#if defined(OS_LINUX)
819
820const base::ProcessId kMagicChildId = 54321;
821
822class ListenerThatVerifiesPeerPid : public IPC::Listener {
823 public:
tfarina10a5c062015-09-04 18:47:57824 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:27825 EXPECT_EQ(peer_pid, kMagicChildId);
ki.stfua21ed8c2015-10-12 17:26:00826 base::MessageLoop::current()->QuitWhenIdle();
morrita0bd20bd2015-02-25 20:11:27827 }
828
829 bool OnMessageReceived(const IPC::Message& message) override {
830 NOTREACHED();
831 return true;
832 }
833};
834
sammc57ed9f982016-03-10 06:28:35835TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:04836 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:27837
838 ListenerThatVerifiesPeerPid listener;
839 CreateChannel(&listener);
840 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:27841
842 base::MessageLoop::current()->Run();
rockotcbca72f2015-03-03 16:31:04843 channel()->Close();
morrita0bd20bd2015-02-25 20:11:27844
845 EXPECT_TRUE(WaitForClientShutdown());
846 DestroyChannel();
847}
848
sammc57ed9f982016-03-10 06:28:35849DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient,
850 ChannelClient) {
morrita0bd20bd2015-02-25 20:11:27851 IPC::Channel::SetGlobalPid(kMagicChildId);
852 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35853 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:27854
855 base::MessageLoop::current()->Run();
856
sammc57ed9f982016-03-10 06:28:35857 Close();
morrita0bd20bd2015-02-25 20:11:27858}
859
sammc57ed9f982016-03-10 06:28:35860#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:27861
[email protected]64860882014-08-04 23:44:17862} // namespace