blob: cb5c459233b6145fd5a9f894e364f869be40c958 [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
148TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04149 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17150
151 // Set up IPC channel and start client.
152 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24153 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17154 listener.Init(sender());
155 ASSERT_TRUE(ConnectChannel());
156 ASSERT_TRUE(StartClient());
157
158 IPC::TestChannelListener::SendOneMessage(
159 sender(), "hello from parent");
160
161 base::MessageLoop::current()->Run();
162 EXPECT_TRUE(base::kNullProcessId != this->channel()->GetPeerPID());
163
164 this->channel()->Close();
165
166 EXPECT_TRUE(WaitForClientShutdown());
167 EXPECT_TRUE(listener.is_connected_called());
168 EXPECT_TRUE(listener.HasSentAll());
169
170 DestroyChannel();
171}
172
173// A long running process that connects to us
174MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestClient) {
175 TestChannelListenerWithExtraExpectations listener;
176 ChannelClient client(&listener, "IPCChannelMojoTestClient");
177 client.Connect();
178 listener.Init(client.channel());
179
180 IPC::TestChannelListener::SendOneMessage(
181 client.channel(), "hello from child");
182 base::MessageLoop::current()->Run();
183 EXPECT_TRUE(listener.is_connected_called());
184 EXPECT_TRUE(listener.HasSentAll());
185
rockotcbca72f2015-03-03 16:31:04186 client.Close();
187
[email protected]64860882014-08-04 23:44:17188 return 0;
189}
190
morrita0a24cfc92014-09-16 03:20:48191class ListenerExpectingErrors : public IPC::Listener {
192 public:
193 ListenerExpectingErrors()
194 : has_error_(false) {
195 }
196
dchengfe61fca2014-10-22 02:29:52197 void OnChannelConnected(int32 peer_pid) override {
morritabe6c4cc2014-09-24 23:38:44198 base::MessageLoop::current()->Quit();
199 }
200
dchengfe61fca2014-10-22 02:29:52201 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48202
dchengfe61fca2014-10-22 02:29:52203 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48204 has_error_ = true;
205 base::MessageLoop::current()->Quit();
206 }
207
208 bool has_error() const { return has_error_; }
209
210 private:
211 bool has_error_;
212};
213
214
rockotcbca72f2015-03-03 16:31:04215class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase {
morrita0a24cfc92014-09-16 03:20:48216 protected:
dchengfe61fca2014-10-22 02:29:52217 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita0a24cfc92014-09-16 03:20:48218 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39219 base::SequencedTaskRunner* runner) override {
leon.hand20a6c4c2015-06-19 02:25:48220 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle,
221 nullptr);
morrita0a24cfc92014-09-16 03:20:48222 }
morrita54f6f80c2014-09-23 21:16:00223
dchengfe61fca2014-10-22 02:29:52224 bool DidStartClient() override {
morrita54f6f80c2014-09-23 21:16:00225 bool ok = IPCTestBase::DidStartClient();
226 DCHECK(ok);
morrita54f6f80c2014-09-23 21:16:00227 return ok;
228 }
morrita0a24cfc92014-09-16 03:20:48229};
230
231class ListenerThatQuits : public IPC::Listener {
232 public:
233 ListenerThatQuits() {
234 }
235
dchengfe61fca2014-10-22 02:29:52236 bool OnMessageReceived(const IPC::Message& message) override {
dchengf3076af2014-10-21 18:02:42237 return true;
238 }
morrita0a24cfc92014-09-16 03:20:48239
dchengfe61fca2014-10-22 02:29:52240 void OnChannelConnected(int32 peer_pid) override {
morrita0a24cfc92014-09-16 03:20:48241 base::MessageLoop::current()->Quit();
242 }
243};
244
245// A long running process that connects to us.
246MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) {
247 ListenerThatQuits listener;
248 ChannelClient client(&listener, "IPCChannelMojoErraticTestClient");
249 client.Connect();
250
251 base::MessageLoop::current()->Run();
252
rockotcbca72f2015-03-03 16:31:04253 client.Close();
254
morrita0a24cfc92014-09-16 03:20:48255 return 0;
256}
257
morritabe6c4cc2014-09-24 23:38:44258TEST_F(IPCChannelMojoErrorTest, SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04259 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48260
261 // Set up IPC channel and start client.
262 ListenerExpectingErrors listener;
263 CreateChannel(&listener);
264 ASSERT_TRUE(ConnectChannel());
265
jamesra03ae492014-10-03 04:26:48266 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44267 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
268 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48269 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44270 for (size_t i = 0; i < 10; ++i) {
morrita0a24cfc92014-09-16 03:20:48271 IPC::TestChannelListener::SendOneMessage(
morritabe6c4cc2014-09-24 23:38:44272 sender(), overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48273 }
274
275 ASSERT_TRUE(StartClient());
276 base::MessageLoop::current()->Run();
277
278 this->channel()->Close();
279
280 EXPECT_TRUE(WaitForClientShutdown());
281 EXPECT_TRUE(listener.has_error());
282
283 DestroyChannel();
284}
285
morrita81b17e02015-02-06 00:58:30286struct TestingMessagePipe {
287 TestingMessagePipe() {
288 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
289 }
290
291 mojo::ScopedMessagePipeHandle self;
292 mojo::ScopedMessagePipeHandle peer;
293};
294
295class HandleSendingHelper {
296 public:
297 static std::string GetSendingFileContent() { return "Hello"; }
298
299 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
300 std::string content = HandleSendingHelper::GetSendingFileContent();
301 EXPECT_EQ(MOJO_RESULT_OK,
302 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
303 static_cast<uint32_t>(content.size()),
304 nullptr, 0, 0));
305 EXPECT_TRUE(
306 IPC::MojoMessageHelper::WriteMessagePipeTo(message, pipe->peer.Pass()));
307 }
308
309 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
310 IPC::Message* message =
311 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
312 WritePipe(message, pipe);
313 ASSERT_TRUE(sender->Send(message));
314 }
315
316 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25317 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30318 mojo::ScopedMessagePipeHandle pipe;
319 EXPECT_TRUE(
320 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
321 std::string content(GetSendingFileContent().size(), ' ');
322
323 uint32_t num_bytes = static_cast<uint32_t>(content.size());
324 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)
331 static base::FilePath GetSendingFilePath() {
332 base::FilePath path;
333 bool ok = PathService::Get(base::DIR_CACHE, &path);
334 EXPECT_TRUE(ok);
335 return path.Append("ListenerThatExpectsFile.txt");
336 }
337
338 static void WriteFile(IPC::Message* message, base::File& file) {
339 std::string content = GetSendingFileContent();
340 file.WriteAtCurrentPos(content.data(), content.size());
341 file.Flush();
342 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
343 base::ScopedFD(file.TakePlatformFile())));
344 }
345
346 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
347 IPC::Message* message =
348 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
349 WriteFile(message, file);
350 ASSERT_TRUE(sender->Send(message));
351 }
352
353 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
354 base::File& file,
355 TestingMessagePipe* pipe) {
356 IPC::Message* message =
357 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
358 WriteFile(message, file);
359 WritePipe(message, pipe);
360 ASSERT_TRUE(sender->Send(message));
361 }
362
363 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25364 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30365 base::ScopedFD fd;
366 scoped_refptr<IPC::MessageAttachment> attachment;
367 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
368 base::File file(attachment->TakePlatformFile());
369 std::string content(GetSendingFileContent().size(), ' ');
370 file.Read(0, &content[0], content.size());
371 EXPECT_EQ(content, GetSendingFileContent());
372 }
373#endif
374};
375
376class ListenerThatExpectsMessagePipe : public IPC::Listener {
377 public:
378 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
379
380 ~ListenerThatExpectsMessagePipe() override {}
381
382 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25383 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30384 HandleSendingHelper::ReadReceivedPipe(message, &iter);
385 base::MessageLoop::current()->Quit();
386 ListenerThatExpectsOK::SendOK(sender_);
387 return true;
388 }
389
390 void OnChannelError() override { NOTREACHED(); }
391
392 void set_sender(IPC::Sender* sender) { sender_ = sender; }
393
394 private:
395 IPC::Sender* sender_;
396};
397
398TEST_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());
404 ASSERT_TRUE(StartClient());
405
406 TestingMessagePipe pipe;
407 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
408
409 base::MessageLoop::current()->Run();
410 this->channel()->Close();
411
412 EXPECT_TRUE(WaitForClientShutdown());
413 DestroyChannel();
414}
415
416MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendMessagePipeClient) {
417 ListenerThatExpectsMessagePipe listener;
morritae73c0b42015-03-05 02:55:19418 ChannelClient client(&listener, "IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30419 client.Connect();
420 listener.set_sender(client.channel());
421
422 base::MessageLoop::current()->Run();
423
rockotcbca72f2015-03-03 16:31:04424 client.Close();
425
morrita81b17e02015-02-06 00:58:30426 return 0;
427}
428
morrita438a2ee2015-04-03 05:28:21429void ReadOK(mojo::MessagePipeHandle pipe) {
430 std::string should_be_ok("xx");
431 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
432 CHECK_EQ(MOJO_RESULT_OK,
433 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
434 nullptr, 0));
435 EXPECT_EQ(should_be_ok, std::string("OK"));
436}
437
438void WriteOK(mojo::MessagePipeHandle pipe) {
439 std::string ok("OK");
440 CHECK_EQ(MOJO_RESULT_OK,
441 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
442 nullptr, 0, 0));
443}
444
445class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
446 public:
447 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
448 : sender_(NULL), receiving_valid_(receiving_valid) {}
449
450 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
451
452 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25453 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21454 mojo::MessagePipeHandle handle;
455 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
456 &handle));
457 EXPECT_EQ(handle.is_valid(), receiving_valid_);
458 if (receiving_valid_) {
459 ReadOK(handle);
460 MojoClose(handle.value());
461 }
462
463 base::MessageLoop::current()->Quit();
464 ListenerThatExpectsOK::SendOK(sender_);
465 return true;
466 }
467
468 void OnChannelError() override { NOTREACHED(); }
469 void set_sender(IPC::Sender* sender) { sender_ = sender; }
470
471 private:
472 IPC::Sender* sender_;
473 bool receiving_valid_;
474};
475
476void ParamTraitMessagePipeClient(bool receiving_valid_handle,
477 const char* channel_name) {
478 ListenerThatExpectsMessagePipeUsingParamTrait listener(
479 receiving_valid_handle);
480 ChannelClient client(&listener, channel_name);
481 client.Connect();
482 listener.set_sender(client.channel());
483
484 base::MessageLoop::current()->Run();
485
486 client.Close();
487}
488
489TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
490 InitWithMojo("ParamTraitValidMessagePipeClient");
491
492 ListenerThatExpectsOK listener;
493 CreateChannel(&listener);
494 ASSERT_TRUE(ConnectChannel());
495 ASSERT_TRUE(StartClient());
496
497 TestingMessagePipe pipe;
498
499 scoped_ptr<IPC::Message> message(new IPC::Message());
500 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
501 pipe.peer.release());
502 WriteOK(pipe.self.get());
503
504 this->channel()->Send(message.release());
505 base::MessageLoop::current()->Run();
506 this->channel()->Close();
507
508 EXPECT_TRUE(WaitForClientShutdown());
509 DestroyChannel();
510}
511
512MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitValidMessagePipeClient) {
513 ParamTraitMessagePipeClient(true, "ParamTraitValidMessagePipeClient");
514 return 0;
515}
516
517TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
518 InitWithMojo("ParamTraitInvalidMessagePipeClient");
519
520 ListenerThatExpectsOK listener;
521 CreateChannel(&listener);
522 ASSERT_TRUE(ConnectChannel());
523 ASSERT_TRUE(StartClient());
524
525 mojo::MessagePipeHandle invalid_handle;
526 scoped_ptr<IPC::Message> message(new IPC::Message());
527 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
528 invalid_handle);
529
530 this->channel()->Send(message.release());
531 base::MessageLoop::current()->Run();
532 this->channel()->Close();
533
534 EXPECT_TRUE(WaitForClientShutdown());
535 DestroyChannel();
536}
537
538MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitInvalidMessagePipeClient) {
539 ParamTraitMessagePipeClient(false, "ParamTraitInvalidMessagePipeClient");
540 return 0;
541}
542
morrita25803672014-10-15 18:50:19543#if defined(OS_WIN)
rockotcbca72f2015-03-03 16:31:04544class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase {
morrita25803672014-10-15 18:50:19545 protected:
nickd60f7172015-04-23 16:42:48546 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita25803672014-10-15 18:50:19547 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39548 base::SequencedTaskRunner* runner) override {
leon.hand20a6c4c2015-06-19 02:25:48549 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle,
550 nullptr);
morrita25803672014-10-15 18:50:19551 }
552
nickd60f7172015-04-23 16:42:48553 bool DidStartClient() override {
morrita25803672014-10-15 18:50:19554 IPCTestBase::DidStartClient();
leon.hand20a6c4c2015-06-19 02:25:48555 // const base::ProcessHandle client = client_process().Handle();
morrita25803672014-10-15 18:50:19556 // Forces GetFileHandleForProcess() fail. It happens occasionally
557 // in production, so we should exercise it somehow.
morritae73c0b42015-03-05 02:55:19558 // TODO(morrita): figure out how to safely test this. See crbug.com/464109.
rvargas07b589c2015-01-12 22:23:23559 // ::CloseHandle(client);
morrita25803672014-10-15 18:50:19560 return true;
561 }
morrita25803672014-10-15 18:50:19562};
563
564TEST_F(IPCChannelMojoDeadHandleTest, InvalidClientHandle) {
565 // Any client type is fine as it is going to be killed anyway.
rockotcbca72f2015-03-03 16:31:04566 InitWithMojo("IPCChannelMojoTestDoNothingClient");
morrita25803672014-10-15 18:50:19567
568 // Set up IPC channel and start client.
569 ListenerExpectingErrors listener;
570 CreateChannel(&listener);
571 ASSERT_TRUE(ConnectChannel());
572
573 ASSERT_TRUE(StartClient());
574 base::MessageLoop::current()->Run();
575
576 this->channel()->Close();
577
morritae73c0b42015-03-05 02:55:19578 // TODO(morrita): We need CloseHandle() call in DidStartClient(),
579 // which has been disabled since crrev.com/843113003, to
580 // make this fail. See crbug.com/464109.
581 // EXPECT_FALSE(WaitForClientShutdown());
582 WaitForClientShutdown();
morrita25803672014-10-15 18:50:19583 EXPECT_TRUE(listener.has_error());
584
585 DestroyChannel();
586}
587
588MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestDoNothingClient) {
589 ListenerThatQuits listener;
590 ChannelClient client(&listener, "IPCChannelMojoTestDoNothingClient");
591 client.Connect();
592
593 // Quits without running the message loop as this client won't
594 // receive any messages from the server.
595
596 return 0;
597}
598#endif
morrita0a24cfc92014-09-16 03:20:48599
[email protected]64860882014-08-04 23:44:17600#if defined(OS_POSIX)
601class ListenerThatExpectsFile : public IPC::Listener {
602 public:
603 ListenerThatExpectsFile()
604 : sender_(NULL) {}
605
dchengfe61fca2014-10-22 02:29:52606 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:17607
dchengfe61fca2014-10-22 02:29:52608 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25609 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30610 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:17611 base::MessageLoop::current()->Quit();
612 ListenerThatExpectsOK::SendOK(sender_);
613 return true;
614 }
615
dchengfe61fca2014-10-22 02:29:52616 void OnChannelError() override {
dchengf3076af2014-10-21 18:02:42617 NOTREACHED();
618 }
[email protected]64860882014-08-04 23:44:17619
[email protected]64860882014-08-04 23:44:17620 void set_sender(IPC::Sender* sender) { sender_ = sender; }
621
622 private:
623 IPC::Sender* sender_;
624};
625
626
627TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:04628 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:17629
630 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:24631 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17632 ASSERT_TRUE(ConnectChannel());
633 ASSERT_TRUE(StartClient());
634
morrita81b17e02015-02-06 00:58:30635 base::File file(HandleSendingHelper::GetSendingFilePath(),
[email protected]64860882014-08-04 23:44:17636 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:30637 base::File::FLAG_READ);
638 HandleSendingHelper::WriteFileThenSend(channel(), file);
[email protected]64860882014-08-04 23:44:17639 base::MessageLoop::current()->Run();
640
641 this->channel()->Close();
642
643 EXPECT_TRUE(WaitForClientShutdown());
644 DestroyChannel();
645}
646
647MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) {
648 ListenerThatExpectsFile listener;
649 ChannelClient client(
650 &listener, "IPCChannelMojoTestSendPlatformHandleClient");
651 client.Connect();
652 listener.set_sender(client.channel());
653
654 base::MessageLoop::current()->Run();
655
rockotcbca72f2015-03-03 16:31:04656 client.Close();
657
[email protected]64860882014-08-04 23:44:17658 return 0;
659}
morrita81b17e02015-02-06 00:58:30660
661class ListenerThatExpectsFileAndPipe : public IPC::Listener {
662 public:
663 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
664
665 ~ListenerThatExpectsFileAndPipe() override {}
666
667 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25668 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30669 HandleSendingHelper::ReadReceivedFile(message, &iter);
670 HandleSendingHelper::ReadReceivedPipe(message, &iter);
671 base::MessageLoop::current()->Quit();
672 ListenerThatExpectsOK::SendOK(sender_);
673 return true;
674 }
675
676 void OnChannelError() override { NOTREACHED(); }
677
678 void set_sender(IPC::Sender* sender) { sender_ = sender; }
679
680 private:
681 IPC::Sender* sender_;
682};
683
684TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:04685 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:30686
687 ListenerThatExpectsOK listener;
688 CreateChannel(&listener);
689 ASSERT_TRUE(ConnectChannel());
690 ASSERT_TRUE(StartClient());
691
692 base::File file(HandleSendingHelper::GetSendingFilePath(),
693 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
694 base::File::FLAG_READ);
695 TestingMessagePipe pipe;
696 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
697
698 base::MessageLoop::current()->Run();
699 this->channel()->Close();
700
701 EXPECT_TRUE(WaitForClientShutdown());
702 DestroyChannel();
703}
704
705MULTIPROCESS_IPC_TEST_CLIENT_MAIN(
706 IPCChannelMojoTestSendPlatformHandleAndPipeClient) {
707 ListenerThatExpectsFileAndPipe listener;
708 ChannelClient client(&listener,
709 "IPCChannelMojoTestSendPlatformHandleAndPipeClient");
710 client.Connect();
711 listener.set_sender(client.channel());
712
713 base::MessageLoop::current()->Run();
714
rockotcbca72f2015-03-03 16:31:04715 client.Close();
716
morrita81b17e02015-02-06 00:58:30717 return 0;
718}
719
[email protected]64860882014-08-04 23:44:17720#endif
721
morrita0bd20bd2015-02-25 20:11:27722#if defined(OS_LINUX)
723
724const base::ProcessId kMagicChildId = 54321;
725
726class ListenerThatVerifiesPeerPid : public IPC::Listener {
727 public:
728 void OnChannelConnected(int32 peer_pid) override {
729 EXPECT_EQ(peer_pid, kMagicChildId);
730 base::MessageLoop::current()->Quit();
731 }
732
733 bool OnMessageReceived(const IPC::Message& message) override {
734 NOTREACHED();
735 return true;
736 }
737};
738
739TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:04740 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:27741
742 ListenerThatVerifiesPeerPid listener;
743 CreateChannel(&listener);
744 ASSERT_TRUE(ConnectChannel());
745 ASSERT_TRUE(StartClient());
746
747 base::MessageLoop::current()->Run();
rockotcbca72f2015-03-03 16:31:04748 channel()->Close();
morrita0bd20bd2015-02-25 20:11:27749
750 EXPECT_TRUE(WaitForClientShutdown());
751 DestroyChannel();
752}
753
754MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestVerifyGlobalPidClient) {
755 IPC::Channel::SetGlobalPid(kMagicChildId);
756 ListenerThatQuits listener;
757 ChannelClient client(&listener,
758 "IPCChannelMojoTestVerifyGlobalPidClient");
759 client.Connect();
760
761 base::MessageLoop::current()->Run();
762
rockotcbca72f2015-03-03 16:31:04763 client.Close();
764
morrita0bd20bd2015-02-25 20:11:27765 return 0;
766}
767
768#endif // OS_LINUX
769
[email protected]64860882014-08-04 23:44:17770} // namespace