blob: c82e0119d4177a265ed18bb71a9b66244a9ac987 [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
7#include "base/base_paths.h"
8#include "base/files/file.h"
skyostile687bdff2015-05-12 11:29:219#include "base/location.h"
[email protected]64860882014-08-04 23:44:1710#include "base/path_service.h"
11#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0412#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2113#include "base/single_thread_task_runner.h"
morrita0bd20bd2015-02-25 20:11:2714#include "base/test/test_timeouts.h"
skyostile687bdff2015-05-12 11:29:2115#include "base/thread_task_runner_handle.h"
[email protected]64860882014-08-04 23:44:1716#include "base/threading/thread.h"
17#include "ipc/ipc_message.h"
18#include "ipc/ipc_test_base.h"
19#include "ipc/ipc_test_channel_listener.h"
morrita81b17e02015-02-06 00:58:3020#include "ipc/mojo/ipc_mojo_handle_attachment.h"
21#include "ipc/mojo/ipc_mojo_message_helper.h"
morrita438a2ee2015-04-03 05:28:2122#include "ipc/mojo/ipc_mojo_param_traits.h"
rockotcbca72f2015-03-03 16:31:0423#include "ipc/mojo/scoped_ipc_support.h"
[email protected]64860882014-08-04 23:44:1724
25#if defined(OS_POSIX)
26#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4227#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1728#endif
29
30namespace {
31
32class ListenerThatExpectsOK : public IPC::Listener {
33 public:
[email protected]e5c27752014-08-08 21:45:1334 ListenerThatExpectsOK()
35 : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1736
dchengfe61fca2014-10-22 02:29:5237 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1738
dchengfe61fca2014-10-22 02:29:5239 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2540 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1741 std::string should_be_ok;
42 EXPECT_TRUE(iter.ReadString(&should_be_ok));
43 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1344 received_ok_ = true;
[email protected]64860882014-08-04 23:44:1745 base::MessageLoop::current()->Quit();
46 return true;
47 }
48
dchengfe61fca2014-10-22 02:29:5249 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1350 // The connection should be healthy while the listener is waiting
51 // message. An error can occur after that because the peer
52 // process dies.
53 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1754 }
55
56 static void SendOK(IPC::Sender* sender) {
57 IPC::Message* message = new IPC::Message(
58 0, 2, IPC::Message::PRIORITY_NORMAL);
59 message->WriteString(std::string("OK"));
60 ASSERT_TRUE(sender->Send(message));
61 }
[email protected]e5c27752014-08-08 21:45:1362
63 private:
64 bool received_ok_;
[email protected]64860882014-08-04 23:44:1765};
66
[email protected]64860882014-08-04 23:44:1767class ChannelClient {
68 public:
69 explicit ChannelClient(IPC::Listener* listener, const char* name) {
leon.hand20a6c4c2015-06-19 02:25:4870 channel_ = IPC::ChannelMojo::Create(
71 main_message_loop_.task_runner(), IPCTestBase::GetChannelName(name),
72 IPC::Channel::MODE_CLIENT, listener, nullptr);
[email protected]64860882014-08-04 23:44:1773 }
74
75 void Connect() {
76 CHECK(channel_->Connect());
77 }
78
rockotcbca72f2015-03-03 16:31:0479 void Close() {
80 channel_->Close();
81
82 base::RunLoop run_loop;
skyostile687bdff2015-05-12 11:29:2183 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
84 run_loop.QuitClosure());
rockotcbca72f2015-03-03 16:31:0485 run_loop.Run();
86 }
87
[email protected]64860882014-08-04 23:44:1788 IPC::ChannelMojo* channel() const { return channel_.get(); }
89
90 private:
[email protected]64860882014-08-04 23:44:1791 base::MessageLoopForIO main_message_loop_;
morrita54f6f80c2014-09-23 21:16:0092 scoped_ptr<IPC::ChannelMojo> channel_;
[email protected]64860882014-08-04 23:44:1793};
94
rockotcbca72f2015-03-03 16:31:0495class IPCChannelMojoTestBase : public IPCTestBase {
96 public:
97 void InitWithMojo(const std::string& test_client_name) {
98 Init(test_client_name);
rockotcbca72f2015-03-03 16:31:0499 }
100
101 void TearDown() override {
102 // Make sure Mojo IPC support is properly shutdown on the I/O loop before
103 // TearDown continues.
rockotcbca72f2015-03-03 16:31:04104 base::RunLoop run_loop;
105 task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
106 run_loop.Run();
107
108 IPCTestBase::TearDown();
109 }
rockotcbca72f2015-03-03 16:31:04110};
111
112class IPCChannelMojoTest : public IPCChannelMojoTestBase {
[email protected]64860882014-08-04 23:44:17113 protected:
dchengfe61fca2014-10-22 02:29:52114 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita373af03b2014-09-09 19:35:24115 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39116 base::SequencedTaskRunner* runner) override {
leon.hand20a6c4c2015-06-19 02:25:48117 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle,
118 nullptr);
[email protected]64860882014-08-04 23:44:17119 }
morrita54f6f80c2014-09-23 21:16:00120
dchengfe61fca2014-10-22 02:29:52121 bool DidStartClient() override {
morrita54f6f80c2014-09-23 21:16:00122 bool ok = IPCTestBase::DidStartClient();
123 DCHECK(ok);
morrita54f6f80c2014-09-23 21:16:00124 return ok;
125 }
[email protected]64860882014-08-04 23:44:17126};
127
128
[email protected]64860882014-08-04 23:44:17129class TestChannelListenerWithExtraExpectations
130 : public IPC::TestChannelListener {
131 public:
132 TestChannelListenerWithExtraExpectations()
133 : is_connected_called_(false) {
134 }
135
dchengfe61fca2014-10-22 02:29:52136 void OnChannelConnected(int32 peer_pid) override {
[email protected]64860882014-08-04 23:44:17137 IPC::TestChannelListener::OnChannelConnected(peer_pid);
138 EXPECT_TRUE(base::kNullProcessId != peer_pid);
139 is_connected_called_ = true;
140 }
141
142 bool is_connected_called() const { return is_connected_called_; }
143
144 private:
145 bool is_connected_called_;
146};
147
msw8f7f53902015-06-19 16:26:47148// Times out on Android; see http://crbug.com/502290
149#if defined(OS_ANDROID)
150#define MAYBE_ConnectedFromClient DISABLED_ConnectedFromClient
151#else
152#define MAYBE_ConnectedFromClient ConnectedFromClient
153#endif
154TEST_F(IPCChannelMojoTest, MAYBE_ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04155 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17156
157 // Set up IPC channel and start client.
158 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24159 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17160 listener.Init(sender());
161 ASSERT_TRUE(ConnectChannel());
162 ASSERT_TRUE(StartClient());
163
164 IPC::TestChannelListener::SendOneMessage(
165 sender(), "hello from parent");
166
167 base::MessageLoop::current()->Run();
168 EXPECT_TRUE(base::kNullProcessId != this->channel()->GetPeerPID());
169
170 this->channel()->Close();
171
172 EXPECT_TRUE(WaitForClientShutdown());
173 EXPECT_TRUE(listener.is_connected_called());
174 EXPECT_TRUE(listener.HasSentAll());
175
176 DestroyChannel();
177}
178
179// A long running process that connects to us
180MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestClient) {
181 TestChannelListenerWithExtraExpectations listener;
182 ChannelClient client(&listener, "IPCChannelMojoTestClient");
183 client.Connect();
184 listener.Init(client.channel());
185
186 IPC::TestChannelListener::SendOneMessage(
187 client.channel(), "hello from child");
188 base::MessageLoop::current()->Run();
189 EXPECT_TRUE(listener.is_connected_called());
190 EXPECT_TRUE(listener.HasSentAll());
191
rockotcbca72f2015-03-03 16:31:04192 client.Close();
193
[email protected]64860882014-08-04 23:44:17194 return 0;
195}
196
morrita0a24cfc92014-09-16 03:20:48197class ListenerExpectingErrors : public IPC::Listener {
198 public:
199 ListenerExpectingErrors()
200 : has_error_(false) {
201 }
202
dchengfe61fca2014-10-22 02:29:52203 void OnChannelConnected(int32 peer_pid) override {
morritabe6c4cc2014-09-24 23:38:44204 base::MessageLoop::current()->Quit();
205 }
206
dchengfe61fca2014-10-22 02:29:52207 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48208
dchengfe61fca2014-10-22 02:29:52209 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48210 has_error_ = true;
211 base::MessageLoop::current()->Quit();
212 }
213
214 bool has_error() const { return has_error_; }
215
216 private:
217 bool has_error_;
218};
219
220
rockotcbca72f2015-03-03 16:31:04221class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase {
morrita0a24cfc92014-09-16 03:20:48222 protected:
dchengfe61fca2014-10-22 02:29:52223 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita0a24cfc92014-09-16 03:20:48224 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39225 base::SequencedTaskRunner* runner) override {
leon.hand20a6c4c2015-06-19 02:25:48226 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle,
227 nullptr);
morrita0a24cfc92014-09-16 03:20:48228 }
morrita54f6f80c2014-09-23 21:16:00229
dchengfe61fca2014-10-22 02:29:52230 bool DidStartClient() override {
morrita54f6f80c2014-09-23 21:16:00231 bool ok = IPCTestBase::DidStartClient();
232 DCHECK(ok);
morrita54f6f80c2014-09-23 21:16:00233 return ok;
234 }
morrita0a24cfc92014-09-16 03:20:48235};
236
237class ListenerThatQuits : public IPC::Listener {
238 public:
239 ListenerThatQuits() {
240 }
241
dchengfe61fca2014-10-22 02:29:52242 bool OnMessageReceived(const IPC::Message& message) override {
dchengf3076af2014-10-21 18:02:42243 return true;
244 }
morrita0a24cfc92014-09-16 03:20:48245
dchengfe61fca2014-10-22 02:29:52246 void OnChannelConnected(int32 peer_pid) override {
morrita0a24cfc92014-09-16 03:20:48247 base::MessageLoop::current()->Quit();
248 }
249};
250
251// A long running process that connects to us.
252MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) {
253 ListenerThatQuits listener;
254 ChannelClient client(&listener, "IPCChannelMojoErraticTestClient");
255 client.Connect();
256
257 base::MessageLoop::current()->Run();
258
rockotcbca72f2015-03-03 16:31:04259 client.Close();
260
morrita0a24cfc92014-09-16 03:20:48261 return 0;
262}
263
msw8f7f53902015-06-19 16:26:47264// Times out on Android; see http://crbug.com/502290
265#if defined(OS_ANDROID)
266#define MAYBE_SendFailWithPendingMessages DISABLED_SendFailWithPendingMessages
267#else
268#define MAYBE_SendFailWithPendingMessages SendFailWithPendingMessages
269#endif
270TEST_F(IPCChannelMojoErrorTest, MAYBE_SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04271 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48272
273 // Set up IPC channel and start client.
274 ListenerExpectingErrors listener;
275 CreateChannel(&listener);
276 ASSERT_TRUE(ConnectChannel());
277
jamesra03ae492014-10-03 04:26:48278 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44279 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
280 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48281 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44282 for (size_t i = 0; i < 10; ++i) {
morrita0a24cfc92014-09-16 03:20:48283 IPC::TestChannelListener::SendOneMessage(
morritabe6c4cc2014-09-24 23:38:44284 sender(), overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48285 }
286
287 ASSERT_TRUE(StartClient());
288 base::MessageLoop::current()->Run();
289
290 this->channel()->Close();
291
292 EXPECT_TRUE(WaitForClientShutdown());
293 EXPECT_TRUE(listener.has_error());
294
295 DestroyChannel();
296}
297
morrita81b17e02015-02-06 00:58:30298struct TestingMessagePipe {
299 TestingMessagePipe() {
300 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
301 }
302
303 mojo::ScopedMessagePipeHandle self;
304 mojo::ScopedMessagePipeHandle peer;
305};
306
307class HandleSendingHelper {
308 public:
309 static std::string GetSendingFileContent() { return "Hello"; }
310
311 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
312 std::string content = HandleSendingHelper::GetSendingFileContent();
313 EXPECT_EQ(MOJO_RESULT_OK,
314 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
315 static_cast<uint32_t>(content.size()),
316 nullptr, 0, 0));
317 EXPECT_TRUE(
318 IPC::MojoMessageHelper::WriteMessagePipeTo(message, pipe->peer.Pass()));
319 }
320
321 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
322 IPC::Message* message =
323 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
324 WritePipe(message, pipe);
325 ASSERT_TRUE(sender->Send(message));
326 }
327
328 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25329 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30330 mojo::ScopedMessagePipeHandle pipe;
331 EXPECT_TRUE(
332 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
333 std::string content(GetSendingFileContent().size(), ' ');
334
335 uint32_t num_bytes = static_cast<uint32_t>(content.size());
336 EXPECT_EQ(MOJO_RESULT_OK,
337 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
338 nullptr, 0));
339 EXPECT_EQ(content, GetSendingFileContent());
340 }
341
342#if defined(OS_POSIX)
343 static base::FilePath GetSendingFilePath() {
344 base::FilePath path;
345 bool ok = PathService::Get(base::DIR_CACHE, &path);
346 EXPECT_TRUE(ok);
347 return path.Append("ListenerThatExpectsFile.txt");
348 }
349
350 static void WriteFile(IPC::Message* message, base::File& file) {
351 std::string content = GetSendingFileContent();
352 file.WriteAtCurrentPos(content.data(), content.size());
353 file.Flush();
354 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
355 base::ScopedFD(file.TakePlatformFile())));
356 }
357
358 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
359 IPC::Message* message =
360 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
361 WriteFile(message, file);
362 ASSERT_TRUE(sender->Send(message));
363 }
364
365 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
366 base::File& file,
367 TestingMessagePipe* pipe) {
368 IPC::Message* message =
369 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
370 WriteFile(message, file);
371 WritePipe(message, pipe);
372 ASSERT_TRUE(sender->Send(message));
373 }
374
375 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25376 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30377 base::ScopedFD fd;
378 scoped_refptr<IPC::MessageAttachment> attachment;
379 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
380 base::File file(attachment->TakePlatformFile());
381 std::string content(GetSendingFileContent().size(), ' ');
382 file.Read(0, &content[0], content.size());
383 EXPECT_EQ(content, GetSendingFileContent());
384 }
385#endif
386};
387
388class ListenerThatExpectsMessagePipe : public IPC::Listener {
389 public:
390 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
391
392 ~ListenerThatExpectsMessagePipe() override {}
393
394 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25395 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30396 HandleSendingHelper::ReadReceivedPipe(message, &iter);
397 base::MessageLoop::current()->Quit();
398 ListenerThatExpectsOK::SendOK(sender_);
399 return true;
400 }
401
402 void OnChannelError() override { NOTREACHED(); }
403
404 void set_sender(IPC::Sender* sender) { sender_ = sender; }
405
406 private:
407 IPC::Sender* sender_;
408};
409
msw8f7f53902015-06-19 16:26:47410// Times out on Android; see http://crbug.com/502290
411#if defined(OS_ANDROID)
412#define MAYBE_SendMessagePipe DISABLED_SendMessagePipe
413#else
414#define MAYBE_SendMessagePipe SendMessagePipe
415#endif
416TEST_F(IPCChannelMojoTest, MAYBE_SendMessagePipe) {
rockotcbca72f2015-03-03 16:31:04417 InitWithMojo("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30418
419 ListenerThatExpectsOK listener;
420 CreateChannel(&listener);
421 ASSERT_TRUE(ConnectChannel());
422 ASSERT_TRUE(StartClient());
423
424 TestingMessagePipe pipe;
425 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
426
427 base::MessageLoop::current()->Run();
428 this->channel()->Close();
429
430 EXPECT_TRUE(WaitForClientShutdown());
431 DestroyChannel();
432}
433
434MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendMessagePipeClient) {
435 ListenerThatExpectsMessagePipe listener;
morritae73c0b42015-03-05 02:55:19436 ChannelClient client(&listener, "IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30437 client.Connect();
438 listener.set_sender(client.channel());
439
440 base::MessageLoop::current()->Run();
441
rockotcbca72f2015-03-03 16:31:04442 client.Close();
443
morrita81b17e02015-02-06 00:58:30444 return 0;
445}
446
morrita438a2ee2015-04-03 05:28:21447void ReadOK(mojo::MessagePipeHandle pipe) {
448 std::string should_be_ok("xx");
449 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
450 CHECK_EQ(MOJO_RESULT_OK,
451 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
452 nullptr, 0));
453 EXPECT_EQ(should_be_ok, std::string("OK"));
454}
455
456void WriteOK(mojo::MessagePipeHandle pipe) {
457 std::string ok("OK");
458 CHECK_EQ(MOJO_RESULT_OK,
459 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
460 nullptr, 0, 0));
461}
462
463class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
464 public:
465 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
466 : sender_(NULL), receiving_valid_(receiving_valid) {}
467
468 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
469
470 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25471 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21472 mojo::MessagePipeHandle handle;
473 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
474 &handle));
475 EXPECT_EQ(handle.is_valid(), receiving_valid_);
476 if (receiving_valid_) {
477 ReadOK(handle);
478 MojoClose(handle.value());
479 }
480
481 base::MessageLoop::current()->Quit();
482 ListenerThatExpectsOK::SendOK(sender_);
483 return true;
484 }
485
486 void OnChannelError() override { NOTREACHED(); }
487 void set_sender(IPC::Sender* sender) { sender_ = sender; }
488
489 private:
490 IPC::Sender* sender_;
491 bool receiving_valid_;
492};
493
494void ParamTraitMessagePipeClient(bool receiving_valid_handle,
495 const char* channel_name) {
496 ListenerThatExpectsMessagePipeUsingParamTrait listener(
497 receiving_valid_handle);
498 ChannelClient client(&listener, channel_name);
499 client.Connect();
500 listener.set_sender(client.channel());
501
502 base::MessageLoop::current()->Run();
503
504 client.Close();
505}
506
msw8f7f53902015-06-19 16:26:47507// Times out on Android; see http://crbug.com/502290
508#if defined(OS_ANDROID)
509#define MAYBE_ParamTraitValidMessagePipe DISABLED_ParamTraitValidMessagePipe
510#else
511#define MAYBE_ParamTraitValidMessagePipe ParamTraitValidMessagePipe
512#endif
513TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitValidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21514 InitWithMojo("ParamTraitValidMessagePipeClient");
515
516 ListenerThatExpectsOK listener;
517 CreateChannel(&listener);
518 ASSERT_TRUE(ConnectChannel());
519 ASSERT_TRUE(StartClient());
520
521 TestingMessagePipe pipe;
522
523 scoped_ptr<IPC::Message> message(new IPC::Message());
524 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
525 pipe.peer.release());
526 WriteOK(pipe.self.get());
527
528 this->channel()->Send(message.release());
529 base::MessageLoop::current()->Run();
530 this->channel()->Close();
531
532 EXPECT_TRUE(WaitForClientShutdown());
533 DestroyChannel();
534}
535
536MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitValidMessagePipeClient) {
537 ParamTraitMessagePipeClient(true, "ParamTraitValidMessagePipeClient");
538 return 0;
539}
540
msw8f7f53902015-06-19 16:26:47541// Times out on Android; see http://crbug.com/502290
542#if defined(OS_ANDROID)
543#define MAYBE_ParamTraitInvalidMessagePipe DISABLED_ParamTraitInvalidMessagePipe
544#else
545#define MAYBE_ParamTraitInvalidMessagePipe ParamTraitInvalidMessagePipe
546#endif
547TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitInvalidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21548 InitWithMojo("ParamTraitInvalidMessagePipeClient");
549
550 ListenerThatExpectsOK listener;
551 CreateChannel(&listener);
552 ASSERT_TRUE(ConnectChannel());
553 ASSERT_TRUE(StartClient());
554
555 mojo::MessagePipeHandle invalid_handle;
556 scoped_ptr<IPC::Message> message(new IPC::Message());
557 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
558 invalid_handle);
559
560 this->channel()->Send(message.release());
561 base::MessageLoop::current()->Run();
562 this->channel()->Close();
563
564 EXPECT_TRUE(WaitForClientShutdown());
565 DestroyChannel();
566}
567
568MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitInvalidMessagePipeClient) {
569 ParamTraitMessagePipeClient(false, "ParamTraitInvalidMessagePipeClient");
570 return 0;
571}
572
morrita17137e62015-06-23 22:29:36573TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
574 InitWithMojo("IPCChannelMojoTestSendOkClient");
575
576 ListenerThatExpectsOK listener;
577 CreateChannel(&listener);
578 ASSERT_TRUE(ConnectChannel());
579 ASSERT_TRUE(StartClient());
580
581 base::MessageLoop::current()->Run();
582 this->channel()->Close();
583 ASSERT_FALSE(this->channel()->Send(new IPC::Message()));
584
585 EXPECT_TRUE(WaitForClientShutdown());
586 DestroyChannel();
587}
588
589class ListenerSendingOneOk : public IPC::Listener {
590 public:
591 ListenerSendingOneOk() {
592 }
593
594 bool OnMessageReceived(const IPC::Message& message) override {
595 return true;
596 }
597
598 void OnChannelConnected(int32 peer_pid) override {
599 ListenerThatExpectsOK::SendOK(sender_);
600 base::MessageLoop::current()->Quit();
601 }
602
603 void set_sender(IPC::Sender* sender) { sender_ = sender; }
604
605 private:
606 IPC::Sender* sender_;
607};
608
609MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendOkClient) {
610 ListenerSendingOneOk listener;
611 ChannelClient client(&listener, "IPCChannelMojoTestSendOkClient");
612 client.Connect();
613 listener.set_sender(client.channel());
614
615 base::MessageLoop::current()->Run();
616
617 client.Close();
618
619 return 0;
620}
621
morrita25803672014-10-15 18:50:19622#if defined(OS_WIN)
rockotcbca72f2015-03-03 16:31:04623class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase {
morrita25803672014-10-15 18:50:19624 protected:
nickd60f7172015-04-23 16:42:48625 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita25803672014-10-15 18:50:19626 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39627 base::SequencedTaskRunner* runner) override {
leon.hand20a6c4c2015-06-19 02:25:48628 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle,
629 nullptr);
morrita25803672014-10-15 18:50:19630 }
631
nickd60f7172015-04-23 16:42:48632 bool DidStartClient() override {
morrita25803672014-10-15 18:50:19633 IPCTestBase::DidStartClient();
leon.hand20a6c4c2015-06-19 02:25:48634 // const base::ProcessHandle client = client_process().Handle();
morrita25803672014-10-15 18:50:19635 // Forces GetFileHandleForProcess() fail. It happens occasionally
636 // in production, so we should exercise it somehow.
morritae73c0b42015-03-05 02:55:19637 // TODO(morrita): figure out how to safely test this. See crbug.com/464109.
rvargas07b589c2015-01-12 22:23:23638 // ::CloseHandle(client);
morrita25803672014-10-15 18:50:19639 return true;
640 }
morrita25803672014-10-15 18:50:19641};
642
643TEST_F(IPCChannelMojoDeadHandleTest, InvalidClientHandle) {
644 // Any client type is fine as it is going to be killed anyway.
rockotcbca72f2015-03-03 16:31:04645 InitWithMojo("IPCChannelMojoTestDoNothingClient");
morrita25803672014-10-15 18:50:19646
647 // Set up IPC channel and start client.
648 ListenerExpectingErrors listener;
649 CreateChannel(&listener);
650 ASSERT_TRUE(ConnectChannel());
651
652 ASSERT_TRUE(StartClient());
653 base::MessageLoop::current()->Run();
654
655 this->channel()->Close();
656
morritae73c0b42015-03-05 02:55:19657 // TODO(morrita): We need CloseHandle() call in DidStartClient(),
658 // which has been disabled since crrev.com/843113003, to
659 // make this fail. See crbug.com/464109.
660 // EXPECT_FALSE(WaitForClientShutdown());
661 WaitForClientShutdown();
morrita25803672014-10-15 18:50:19662 EXPECT_TRUE(listener.has_error());
663
664 DestroyChannel();
665}
666
667MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestDoNothingClient) {
668 ListenerThatQuits listener;
669 ChannelClient client(&listener, "IPCChannelMojoTestDoNothingClient");
670 client.Connect();
671
672 // Quits without running the message loop as this client won't
673 // receive any messages from the server.
674
675 return 0;
676}
677#endif
morrita0a24cfc92014-09-16 03:20:48678
[email protected]64860882014-08-04 23:44:17679#if defined(OS_POSIX)
680class ListenerThatExpectsFile : public IPC::Listener {
681 public:
682 ListenerThatExpectsFile()
683 : sender_(NULL) {}
684
dchengfe61fca2014-10-22 02:29:52685 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:17686
dchengfe61fca2014-10-22 02:29:52687 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25688 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30689 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:17690 base::MessageLoop::current()->Quit();
691 ListenerThatExpectsOK::SendOK(sender_);
692 return true;
693 }
694
dchengfe61fca2014-10-22 02:29:52695 void OnChannelError() override {
dchengf3076af2014-10-21 18:02:42696 NOTREACHED();
697 }
[email protected]64860882014-08-04 23:44:17698
[email protected]64860882014-08-04 23:44:17699 void set_sender(IPC::Sender* sender) { sender_ = sender; }
700
701 private:
702 IPC::Sender* sender_;
703};
704
msw8f7f53902015-06-19 16:26:47705// Times out on Android; see http://crbug.com/502290
706#if defined(OS_ANDROID)
707#define MAYBE_SendPlatformHandle DISABLED_SendPlatformHandle
708#else
709#define MAYBE_SendPlatformHandle SendPlatformHandle
710#endif
711TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:04712 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:17713
714 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:24715 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17716 ASSERT_TRUE(ConnectChannel());
717 ASSERT_TRUE(StartClient());
718
morrita81b17e02015-02-06 00:58:30719 base::File file(HandleSendingHelper::GetSendingFilePath(),
[email protected]64860882014-08-04 23:44:17720 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:30721 base::File::FLAG_READ);
722 HandleSendingHelper::WriteFileThenSend(channel(), file);
[email protected]64860882014-08-04 23:44:17723 base::MessageLoop::current()->Run();
724
725 this->channel()->Close();
726
727 EXPECT_TRUE(WaitForClientShutdown());
728 DestroyChannel();
729}
730
731MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) {
732 ListenerThatExpectsFile listener;
733 ChannelClient client(
734 &listener, "IPCChannelMojoTestSendPlatformHandleClient");
735 client.Connect();
736 listener.set_sender(client.channel());
737
738 base::MessageLoop::current()->Run();
739
rockotcbca72f2015-03-03 16:31:04740 client.Close();
741
[email protected]64860882014-08-04 23:44:17742 return 0;
743}
morrita81b17e02015-02-06 00:58:30744
745class ListenerThatExpectsFileAndPipe : public IPC::Listener {
746 public:
747 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
748
749 ~ListenerThatExpectsFileAndPipe() override {}
750
751 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25752 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30753 HandleSendingHelper::ReadReceivedFile(message, &iter);
754 HandleSendingHelper::ReadReceivedPipe(message, &iter);
755 base::MessageLoop::current()->Quit();
756 ListenerThatExpectsOK::SendOK(sender_);
757 return true;
758 }
759
760 void OnChannelError() override { NOTREACHED(); }
761
762 void set_sender(IPC::Sender* sender) { sender_ = sender; }
763
764 private:
765 IPC::Sender* sender_;
766};
767
msw8f7f53902015-06-19 16:26:47768// Times out on Android; see http://crbug.com/502290
769#if defined(OS_ANDROID)
770#define MAYBE_SendPlatformHandleAndPipe DISABLED_SendPlatformHandleAndPipe
771#else
772#define MAYBE_SendPlatformHandleAndPipe SendPlatformHandleAndPipe
773#endif
774TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:04775 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:30776
777 ListenerThatExpectsOK listener;
778 CreateChannel(&listener);
779 ASSERT_TRUE(ConnectChannel());
780 ASSERT_TRUE(StartClient());
781
782 base::File file(HandleSendingHelper::GetSendingFilePath(),
783 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
784 base::File::FLAG_READ);
785 TestingMessagePipe pipe;
786 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
787
788 base::MessageLoop::current()->Run();
789 this->channel()->Close();
790
791 EXPECT_TRUE(WaitForClientShutdown());
792 DestroyChannel();
793}
794
795MULTIPROCESS_IPC_TEST_CLIENT_MAIN(
796 IPCChannelMojoTestSendPlatformHandleAndPipeClient) {
797 ListenerThatExpectsFileAndPipe listener;
798 ChannelClient client(&listener,
799 "IPCChannelMojoTestSendPlatformHandleAndPipeClient");
800 client.Connect();
801 listener.set_sender(client.channel());
802
803 base::MessageLoop::current()->Run();
804
rockotcbca72f2015-03-03 16:31:04805 client.Close();
806
morrita81b17e02015-02-06 00:58:30807 return 0;
808}
809
[email protected]64860882014-08-04 23:44:17810#endif
811
morrita0bd20bd2015-02-25 20:11:27812#if defined(OS_LINUX)
813
814const base::ProcessId kMagicChildId = 54321;
815
816class ListenerThatVerifiesPeerPid : public IPC::Listener {
817 public:
818 void OnChannelConnected(int32 peer_pid) override {
819 EXPECT_EQ(peer_pid, kMagicChildId);
820 base::MessageLoop::current()->Quit();
821 }
822
823 bool OnMessageReceived(const IPC::Message& message) override {
824 NOTREACHED();
825 return true;
826 }
827};
828
829TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:04830 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:27831
832 ListenerThatVerifiesPeerPid listener;
833 CreateChannel(&listener);
834 ASSERT_TRUE(ConnectChannel());
835 ASSERT_TRUE(StartClient());
836
837 base::MessageLoop::current()->Run();
rockotcbca72f2015-03-03 16:31:04838 channel()->Close();
morrita0bd20bd2015-02-25 20:11:27839
840 EXPECT_TRUE(WaitForClientShutdown());
841 DestroyChannel();
842}
843
844MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestVerifyGlobalPidClient) {
845 IPC::Channel::SetGlobalPid(kMagicChildId);
846 ListenerThatQuits listener;
847 ChannelClient client(&listener,
848 "IPCChannelMojoTestVerifyGlobalPidClient");
849 client.Connect();
850
851 base::MessageLoop::current()->Run();
852
rockotcbca72f2015-03-03 16:31:04853 client.Close();
854
morrita0bd20bd2015-02-25 20:11:27855 return 0;
856}
857
858#endif // OS_LINUX
859
[email protected]64860882014-08-04 23:44:17860} // namespace