blob: 356d3b3acd110ab1835f89ca9849cd0ccdc8c4fa [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"
9#include "base/message_loop/message_loop.h"
10#include "base/path_service.h"
11#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0412#include "base/run_loop.h"
morrita0bd20bd2015-02-25 20:11:2713#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1714#include "base/threading/thread.h"
15#include "ipc/ipc_message.h"
16#include "ipc/ipc_test_base.h"
17#include "ipc/ipc_test_channel_listener.h"
morrita54f6f80c2014-09-23 21:16:0018#include "ipc/mojo/ipc_channel_mojo_host.h"
morrita81b17e02015-02-06 00:58:3019#include "ipc/mojo/ipc_mojo_handle_attachment.h"
20#include "ipc/mojo/ipc_mojo_message_helper.h"
morrita438a2ee2015-04-03 05:28:2121#include "ipc/mojo/ipc_mojo_param_traits.h"
rockotcbca72f2015-03-03 16:31:0422#include "ipc/mojo/scoped_ipc_support.h"
[email protected]64860882014-08-04 23:44:1723
24#if defined(OS_POSIX)
25#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4226#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1727#endif
28
29namespace {
30
31class ListenerThatExpectsOK : public IPC::Listener {
32 public:
[email protected]e5c27752014-08-08 21:45:1333 ListenerThatExpectsOK()
34 : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1735
dchengfe61fca2014-10-22 02:29:5236 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1737
dchengfe61fca2014-10-22 02:29:5238 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]64860882014-08-04 23:44:1739 PickleIterator iter(message);
40 std::string should_be_ok;
41 EXPECT_TRUE(iter.ReadString(&should_be_ok));
42 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1343 received_ok_ = true;
[email protected]64860882014-08-04 23:44:1744 base::MessageLoop::current()->Quit();
45 return true;
46 }
47
dchengfe61fca2014-10-22 02:29:5248 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1349 // The connection should be healthy while the listener is waiting
50 // message. An error can occur after that because the peer
51 // process dies.
52 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1753 }
54
55 static void SendOK(IPC::Sender* sender) {
56 IPC::Message* message = new IPC::Message(
57 0, 2, IPC::Message::PRIORITY_NORMAL);
58 message->WriteString(std::string("OK"));
59 ASSERT_TRUE(sender->Send(message));
60 }
[email protected]e5c27752014-08-08 21:45:1361
62 private:
63 bool received_ok_;
[email protected]64860882014-08-04 23:44:1764};
65
[email protected]64860882014-08-04 23:44:1766class ChannelClient {
67 public:
68 explicit ChannelClient(IPC::Listener* listener, const char* name) {
rockotcbca72f2015-03-03 16:31:0469 ipc_support_.reset(
70 new IPC::ScopedIPCSupport(main_message_loop_.task_runner()));
morrita54f6f80c2014-09-23 21:16:0071 channel_ = IPC::ChannelMojo::Create(NULL,
72 IPCTestBase::GetChannelName(name),
73 IPC::Channel::MODE_CLIENT,
74 listener);
[email protected]64860882014-08-04 23:44:1775 }
76
77 void Connect() {
78 CHECK(channel_->Connect());
79 }
80
rockotcbca72f2015-03-03 16:31:0481 void Close() {
82 channel_->Close();
83
84 base::RunLoop run_loop;
85 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure());
86 run_loop.Run();
87 }
88
[email protected]64860882014-08-04 23:44:1789 IPC::ChannelMojo* channel() const { return channel_.get(); }
90
91 private:
[email protected]64860882014-08-04 23:44:1792 base::MessageLoopForIO main_message_loop_;
rockotcbca72f2015-03-03 16:31:0493 scoped_ptr<IPC::ScopedIPCSupport> ipc_support_;
morrita54f6f80c2014-09-23 21:16:0094 scoped_ptr<IPC::ChannelMojo> channel_;
[email protected]64860882014-08-04 23:44:1795};
96
rockotcbca72f2015-03-03 16:31:0497class IPCChannelMojoTestBase : public IPCTestBase {
98 public:
99 void InitWithMojo(const std::string& test_client_name) {
100 Init(test_client_name);
101 ipc_support_.reset(new IPC::ScopedIPCSupport(task_runner()));
102 }
103
104 void TearDown() override {
105 // Make sure Mojo IPC support is properly shutdown on the I/O loop before
106 // TearDown continues.
107 ipc_support_.reset();
108 base::RunLoop run_loop;
109 task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
110 run_loop.Run();
111
112 IPCTestBase::TearDown();
113 }
114
115 private:
116 scoped_ptr<IPC::ScopedIPCSupport> ipc_support_;
117};
118
119class IPCChannelMojoTest : public IPCChannelMojoTestBase {
[email protected]64860882014-08-04 23:44:17120 protected:
dchengfe61fca2014-10-22 02:29:52121 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita373af03b2014-09-09 19:35:24122 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39123 base::SequencedTaskRunner* runner) override {
morrita54f6f80c2014-09-23 21:16:00124 host_.reset(new IPC::ChannelMojoHost(task_runner()));
morritae9453ea2014-09-26 03:20:48125 return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(),
126 handle);
[email protected]64860882014-08-04 23:44:17127 }
morrita54f6f80c2014-09-23 21:16:00128
dchengfe61fca2014-10-22 02:29:52129 bool DidStartClient() override {
morrita54f6f80c2014-09-23 21:16:00130 bool ok = IPCTestBase::DidStartClient();
131 DCHECK(ok);
rvargas07b589c2015-01-12 22:23:23132 host_->OnClientLaunched(client_process().Handle());
morrita54f6f80c2014-09-23 21:16:00133 return ok;
134 }
135
136 private:
137 scoped_ptr<IPC::ChannelMojoHost> host_;
[email protected]64860882014-08-04 23:44:17138};
139
140
[email protected]64860882014-08-04 23:44:17141class TestChannelListenerWithExtraExpectations
142 : public IPC::TestChannelListener {
143 public:
144 TestChannelListenerWithExtraExpectations()
145 : is_connected_called_(false) {
146 }
147
dchengfe61fca2014-10-22 02:29:52148 void OnChannelConnected(int32 peer_pid) override {
[email protected]64860882014-08-04 23:44:17149 IPC::TestChannelListener::OnChannelConnected(peer_pid);
150 EXPECT_TRUE(base::kNullProcessId != peer_pid);
151 is_connected_called_ = true;
152 }
153
154 bool is_connected_called() const { return is_connected_called_; }
155
156 private:
157 bool is_connected_called_;
158};
159
160TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04161 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17162
163 // Set up IPC channel and start client.
164 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24165 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17166 listener.Init(sender());
167 ASSERT_TRUE(ConnectChannel());
168 ASSERT_TRUE(StartClient());
169
170 IPC::TestChannelListener::SendOneMessage(
171 sender(), "hello from parent");
172
173 base::MessageLoop::current()->Run();
174 EXPECT_TRUE(base::kNullProcessId != this->channel()->GetPeerPID());
175
176 this->channel()->Close();
177
178 EXPECT_TRUE(WaitForClientShutdown());
179 EXPECT_TRUE(listener.is_connected_called());
180 EXPECT_TRUE(listener.HasSentAll());
181
182 DestroyChannel();
183}
184
185// A long running process that connects to us
186MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestClient) {
187 TestChannelListenerWithExtraExpectations listener;
188 ChannelClient client(&listener, "IPCChannelMojoTestClient");
189 client.Connect();
190 listener.Init(client.channel());
191
192 IPC::TestChannelListener::SendOneMessage(
193 client.channel(), "hello from child");
194 base::MessageLoop::current()->Run();
195 EXPECT_TRUE(listener.is_connected_called());
196 EXPECT_TRUE(listener.HasSentAll());
197
rockotcbca72f2015-03-03 16:31:04198 client.Close();
199
[email protected]64860882014-08-04 23:44:17200 return 0;
201}
202
morrita0a24cfc92014-09-16 03:20:48203class ListenerExpectingErrors : public IPC::Listener {
204 public:
205 ListenerExpectingErrors()
206 : has_error_(false) {
207 }
208
dchengfe61fca2014-10-22 02:29:52209 void OnChannelConnected(int32 peer_pid) override {
morritabe6c4cc2014-09-24 23:38:44210 base::MessageLoop::current()->Quit();
211 }
212
dchengfe61fca2014-10-22 02:29:52213 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48214
dchengfe61fca2014-10-22 02:29:52215 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48216 has_error_ = true;
217 base::MessageLoop::current()->Quit();
218 }
219
220 bool has_error() const { return has_error_; }
221
222 private:
223 bool has_error_;
224};
225
226
rockotcbca72f2015-03-03 16:31:04227class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase {
morrita0a24cfc92014-09-16 03:20:48228 protected:
dchengfe61fca2014-10-22 02:29:52229 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
morrita0a24cfc92014-09-16 03:20:48230 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39231 base::SequencedTaskRunner* runner) override {
morrita54f6f80c2014-09-23 21:16:00232 host_.reset(new IPC::ChannelMojoHost(task_runner()));
morritae9453ea2014-09-26 03:20:48233 return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(),
234 handle);
morrita0a24cfc92014-09-16 03:20:48235 }
morrita54f6f80c2014-09-23 21:16:00236
dchengfe61fca2014-10-22 02:29:52237 bool DidStartClient() override {
morrita54f6f80c2014-09-23 21:16:00238 bool ok = IPCTestBase::DidStartClient();
239 DCHECK(ok);
rvargas07b589c2015-01-12 22:23:23240 host_->OnClientLaunched(client_process().Handle());
morrita54f6f80c2014-09-23 21:16:00241 return ok;
242 }
243
244 private:
245 scoped_ptr<IPC::ChannelMojoHost> host_;
morrita0a24cfc92014-09-16 03:20:48246};
247
248class ListenerThatQuits : public IPC::Listener {
249 public:
250 ListenerThatQuits() {
251 }
252
dchengfe61fca2014-10-22 02:29:52253 bool OnMessageReceived(const IPC::Message& message) override {
dchengf3076af2014-10-21 18:02:42254 return true;
255 }
morrita0a24cfc92014-09-16 03:20:48256
dchengfe61fca2014-10-22 02:29:52257 void OnChannelConnected(int32 peer_pid) override {
morrita0a24cfc92014-09-16 03:20:48258 base::MessageLoop::current()->Quit();
259 }
260};
261
262// A long running process that connects to us.
263MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) {
264 ListenerThatQuits listener;
265 ChannelClient client(&listener, "IPCChannelMojoErraticTestClient");
266 client.Connect();
267
268 base::MessageLoop::current()->Run();
269
rockotcbca72f2015-03-03 16:31:04270 client.Close();
271
morrita0a24cfc92014-09-16 03:20:48272 return 0;
273}
274
morritabe6c4cc2014-09-24 23:38:44275TEST_F(IPCChannelMojoErrorTest, SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04276 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48277
278 // Set up IPC channel and start client.
279 ListenerExpectingErrors listener;
280 CreateChannel(&listener);
281 ASSERT_TRUE(ConnectChannel());
282
jamesra03ae492014-10-03 04:26:48283 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44284 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
285 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48286 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44287 for (size_t i = 0; i < 10; ++i) {
morrita0a24cfc92014-09-16 03:20:48288 IPC::TestChannelListener::SendOneMessage(
morritabe6c4cc2014-09-24 23:38:44289 sender(), overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48290 }
291
292 ASSERT_TRUE(StartClient());
293 base::MessageLoop::current()->Run();
294
295 this->channel()->Close();
296
297 EXPECT_TRUE(WaitForClientShutdown());
298 EXPECT_TRUE(listener.has_error());
299
300 DestroyChannel();
301}
302
morrita81b17e02015-02-06 00:58:30303struct TestingMessagePipe {
304 TestingMessagePipe() {
305 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
306 }
307
308 mojo::ScopedMessagePipeHandle self;
309 mojo::ScopedMessagePipeHandle peer;
310};
311
312class HandleSendingHelper {
313 public:
314 static std::string GetSendingFileContent() { return "Hello"; }
315
316 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
317 std::string content = HandleSendingHelper::GetSendingFileContent();
318 EXPECT_EQ(MOJO_RESULT_OK,
319 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
320 static_cast<uint32_t>(content.size()),
321 nullptr, 0, 0));
322 EXPECT_TRUE(
323 IPC::MojoMessageHelper::WriteMessagePipeTo(message, pipe->peer.Pass()));
324 }
325
326 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
327 IPC::Message* message =
328 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
329 WritePipe(message, pipe);
330 ASSERT_TRUE(sender->Send(message));
331 }
332
333 static void ReadReceivedPipe(const IPC::Message& message,
334 PickleIterator* iter) {
335 mojo::ScopedMessagePipeHandle pipe;
336 EXPECT_TRUE(
337 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
338 std::string content(GetSendingFileContent().size(), ' ');
339
340 uint32_t num_bytes = static_cast<uint32_t>(content.size());
341 EXPECT_EQ(MOJO_RESULT_OK,
342 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
343 nullptr, 0));
344 EXPECT_EQ(content, GetSendingFileContent());
345 }
346
347#if defined(OS_POSIX)
348 static base::FilePath GetSendingFilePath() {
349 base::FilePath path;
350 bool ok = PathService::Get(base::DIR_CACHE, &path);
351 EXPECT_TRUE(ok);
352 return path.Append("ListenerThatExpectsFile.txt");
353 }
354
355 static void WriteFile(IPC::Message* message, base::File& file) {
356 std::string content = GetSendingFileContent();
357 file.WriteAtCurrentPos(content.data(), content.size());
358 file.Flush();
359 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
360 base::ScopedFD(file.TakePlatformFile())));
361 }
362
363 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
364 IPC::Message* message =
365 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
366 WriteFile(message, file);
367 ASSERT_TRUE(sender->Send(message));
368 }
369
370 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
371 base::File& file,
372 TestingMessagePipe* pipe) {
373 IPC::Message* message =
374 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
375 WriteFile(message, file);
376 WritePipe(message, pipe);
377 ASSERT_TRUE(sender->Send(message));
378 }
379
380 static void ReadReceivedFile(const IPC::Message& message,
381 PickleIterator* iter) {
382 base::ScopedFD fd;
383 scoped_refptr<IPC::MessageAttachment> attachment;
384 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
385 base::File file(attachment->TakePlatformFile());
386 std::string content(GetSendingFileContent().size(), ' ');
387 file.Read(0, &content[0], content.size());
388 EXPECT_EQ(content, GetSendingFileContent());
389 }
390#endif
391};
392
393class ListenerThatExpectsMessagePipe : public IPC::Listener {
394 public:
395 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
396
397 ~ListenerThatExpectsMessagePipe() override {}
398
399 bool OnMessageReceived(const IPC::Message& message) override {
400 PickleIterator iter(message);
401 HandleSendingHelper::ReadReceivedPipe(message, &iter);
402 base::MessageLoop::current()->Quit();
403 ListenerThatExpectsOK::SendOK(sender_);
404 return true;
405 }
406
407 void OnChannelError() override { NOTREACHED(); }
408
409 void set_sender(IPC::Sender* sender) { sender_ = sender; }
410
411 private:
412 IPC::Sender* sender_;
413};
414
415TEST_F(IPCChannelMojoTest, SendMessagePipe) {
rockotcbca72f2015-03-03 16:31:04416 InitWithMojo("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30417
418 ListenerThatExpectsOK listener;
419 CreateChannel(&listener);
420 ASSERT_TRUE(ConnectChannel());
421 ASSERT_TRUE(StartClient());
422
423 TestingMessagePipe pipe;
424 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
425
426 base::MessageLoop::current()->Run();
427 this->channel()->Close();
428
429 EXPECT_TRUE(WaitForClientShutdown());
430 DestroyChannel();
431}
432
433MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendMessagePipeClient) {
434 ListenerThatExpectsMessagePipe listener;
morritae73c0b42015-03-05 02:55:19435 ChannelClient client(&listener, "IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30436 client.Connect();
437 listener.set_sender(client.channel());
438
439 base::MessageLoop::current()->Run();
440
rockotcbca72f2015-03-03 16:31:04441 client.Close();
442
morrita81b17e02015-02-06 00:58:30443 return 0;
444}
445
morrita438a2ee2015-04-03 05:28:21446void ReadOK(mojo::MessagePipeHandle pipe) {
447 std::string should_be_ok("xx");
448 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
449 CHECK_EQ(MOJO_RESULT_OK,
450 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
451 nullptr, 0));
452 EXPECT_EQ(should_be_ok, std::string("OK"));
453}
454
455void WriteOK(mojo::MessagePipeHandle pipe) {
456 std::string ok("OK");
457 CHECK_EQ(MOJO_RESULT_OK,
458 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
459 nullptr, 0, 0));
460}
461
462class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
463 public:
464 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
465 : sender_(NULL), receiving_valid_(receiving_valid) {}
466
467 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
468
469 bool OnMessageReceived(const IPC::Message& message) override {
470 PickleIterator iter(message);
471 mojo::MessagePipeHandle handle;
472 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
473 &handle));
474 EXPECT_EQ(handle.is_valid(), receiving_valid_);
475 if (receiving_valid_) {
476 ReadOK(handle);
477 MojoClose(handle.value());
478 }
479
480 base::MessageLoop::current()->Quit();
481 ListenerThatExpectsOK::SendOK(sender_);
482 return true;
483 }
484
485 void OnChannelError() override { NOTREACHED(); }
486 void set_sender(IPC::Sender* sender) { sender_ = sender; }
487
488 private:
489 IPC::Sender* sender_;
490 bool receiving_valid_;
491};
492
493void ParamTraitMessagePipeClient(bool receiving_valid_handle,
494 const char* channel_name) {
495 ListenerThatExpectsMessagePipeUsingParamTrait listener(
496 receiving_valid_handle);
497 ChannelClient client(&listener, channel_name);
498 client.Connect();
499 listener.set_sender(client.channel());
500
501 base::MessageLoop::current()->Run();
502
503 client.Close();
504}
505
506TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
507 InitWithMojo("ParamTraitValidMessagePipeClient");
508
509 ListenerThatExpectsOK listener;
510 CreateChannel(&listener);
511 ASSERT_TRUE(ConnectChannel());
512 ASSERT_TRUE(StartClient());
513
514 TestingMessagePipe pipe;
515
516 scoped_ptr<IPC::Message> message(new IPC::Message());
517 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
518 pipe.peer.release());
519 WriteOK(pipe.self.get());
520
521 this->channel()->Send(message.release());
522 base::MessageLoop::current()->Run();
523 this->channel()->Close();
524
525 EXPECT_TRUE(WaitForClientShutdown());
526 DestroyChannel();
527}
528
529MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitValidMessagePipeClient) {
530 ParamTraitMessagePipeClient(true, "ParamTraitValidMessagePipeClient");
531 return 0;
532}
533
534TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
535 InitWithMojo("ParamTraitInvalidMessagePipeClient");
536
537 ListenerThatExpectsOK listener;
538 CreateChannel(&listener);
539 ASSERT_TRUE(ConnectChannel());
540 ASSERT_TRUE(StartClient());
541
542 mojo::MessagePipeHandle invalid_handle;
543 scoped_ptr<IPC::Message> message(new IPC::Message());
544 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
545 invalid_handle);
546
547 this->channel()->Send(message.release());
548 base::MessageLoop::current()->Run();
549 this->channel()->Close();
550
551 EXPECT_TRUE(WaitForClientShutdown());
552 DestroyChannel();
553}
554
555MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitInvalidMessagePipeClient) {
556 ParamTraitMessagePipeClient(false, "ParamTraitInvalidMessagePipeClient");
557 return 0;
558}
559
morrita25803672014-10-15 18:50:19560#if defined(OS_WIN)
rockotcbca72f2015-03-03 16:31:04561class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase {
morrita25803672014-10-15 18:50:19562 protected:
563 virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
564 const IPC::ChannelHandle& handle,
morritac4db5472015-03-13 20:44:39565 base::SequencedTaskRunner* runner) override {
morrita25803672014-10-15 18:50:19566 host_.reset(new IPC::ChannelMojoHost(task_runner()));
567 return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(),
568 handle);
569 }
570
571 virtual bool DidStartClient() override {
572 IPCTestBase::DidStartClient();
rvargas07b589c2015-01-12 22:23:23573 const base::ProcessHandle client = client_process().Handle();
morrita25803672014-10-15 18:50:19574 // Forces GetFileHandleForProcess() fail. It happens occasionally
575 // in production, so we should exercise it somehow.
morritae73c0b42015-03-05 02:55:19576 // TODO(morrita): figure out how to safely test this. See crbug.com/464109.
rvargas07b589c2015-01-12 22:23:23577 // ::CloseHandle(client);
morrita25803672014-10-15 18:50:19578 host_->OnClientLaunched(client);
579 return true;
580 }
581
582 private:
583 scoped_ptr<IPC::ChannelMojoHost> host_;
584};
585
586TEST_F(IPCChannelMojoDeadHandleTest, InvalidClientHandle) {
587 // Any client type is fine as it is going to be killed anyway.
rockotcbca72f2015-03-03 16:31:04588 InitWithMojo("IPCChannelMojoTestDoNothingClient");
morrita25803672014-10-15 18:50:19589
590 // Set up IPC channel and start client.
591 ListenerExpectingErrors listener;
592 CreateChannel(&listener);
593 ASSERT_TRUE(ConnectChannel());
594
595 ASSERT_TRUE(StartClient());
596 base::MessageLoop::current()->Run();
597
598 this->channel()->Close();
599
morritae73c0b42015-03-05 02:55:19600 // TODO(morrita): We need CloseHandle() call in DidStartClient(),
601 // which has been disabled since crrev.com/843113003, to
602 // make this fail. See crbug.com/464109.
603 // EXPECT_FALSE(WaitForClientShutdown());
604 WaitForClientShutdown();
morrita25803672014-10-15 18:50:19605 EXPECT_TRUE(listener.has_error());
606
607 DestroyChannel();
608}
609
610MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestDoNothingClient) {
611 ListenerThatQuits listener;
612 ChannelClient client(&listener, "IPCChannelMojoTestDoNothingClient");
613 client.Connect();
614
615 // Quits without running the message loop as this client won't
616 // receive any messages from the server.
617
618 return 0;
619}
620#endif
morrita0a24cfc92014-09-16 03:20:48621
[email protected]64860882014-08-04 23:44:17622#if defined(OS_POSIX)
623class ListenerThatExpectsFile : public IPC::Listener {
624 public:
625 ListenerThatExpectsFile()
626 : sender_(NULL) {}
627
dchengfe61fca2014-10-22 02:29:52628 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:17629
dchengfe61fca2014-10-22 02:29:52630 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]64860882014-08-04 23:44:17631 PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30632 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:17633 base::MessageLoop::current()->Quit();
634 ListenerThatExpectsOK::SendOK(sender_);
635 return true;
636 }
637
dchengfe61fca2014-10-22 02:29:52638 void OnChannelError() override {
dchengf3076af2014-10-21 18:02:42639 NOTREACHED();
640 }
[email protected]64860882014-08-04 23:44:17641
[email protected]64860882014-08-04 23:44:17642 void set_sender(IPC::Sender* sender) { sender_ = sender; }
643
644 private:
645 IPC::Sender* sender_;
646};
647
648
649TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:04650 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:17651
652 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:24653 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17654 ASSERT_TRUE(ConnectChannel());
655 ASSERT_TRUE(StartClient());
656
morrita81b17e02015-02-06 00:58:30657 base::File file(HandleSendingHelper::GetSendingFilePath(),
[email protected]64860882014-08-04 23:44:17658 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:30659 base::File::FLAG_READ);
660 HandleSendingHelper::WriteFileThenSend(channel(), file);
[email protected]64860882014-08-04 23:44:17661 base::MessageLoop::current()->Run();
662
663 this->channel()->Close();
664
665 EXPECT_TRUE(WaitForClientShutdown());
666 DestroyChannel();
667}
668
669MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) {
670 ListenerThatExpectsFile listener;
671 ChannelClient client(
672 &listener, "IPCChannelMojoTestSendPlatformHandleClient");
673 client.Connect();
674 listener.set_sender(client.channel());
675
676 base::MessageLoop::current()->Run();
677
rockotcbca72f2015-03-03 16:31:04678 client.Close();
679
[email protected]64860882014-08-04 23:44:17680 return 0;
681}
morrita81b17e02015-02-06 00:58:30682
683class ListenerThatExpectsFileAndPipe : public IPC::Listener {
684 public:
685 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
686
687 ~ListenerThatExpectsFileAndPipe() override {}
688
689 bool OnMessageReceived(const IPC::Message& message) override {
690 PickleIterator iter(message);
691 HandleSendingHelper::ReadReceivedFile(message, &iter);
692 HandleSendingHelper::ReadReceivedPipe(message, &iter);
693 base::MessageLoop::current()->Quit();
694 ListenerThatExpectsOK::SendOK(sender_);
695 return true;
696 }
697
698 void OnChannelError() override { NOTREACHED(); }
699
700 void set_sender(IPC::Sender* sender) { sender_ = sender; }
701
702 private:
703 IPC::Sender* sender_;
704};
705
706TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:04707 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:30708
709 ListenerThatExpectsOK listener;
710 CreateChannel(&listener);
711 ASSERT_TRUE(ConnectChannel());
712 ASSERT_TRUE(StartClient());
713
714 base::File file(HandleSendingHelper::GetSendingFilePath(),
715 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
716 base::File::FLAG_READ);
717 TestingMessagePipe pipe;
718 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
719
720 base::MessageLoop::current()->Run();
721 this->channel()->Close();
722
723 EXPECT_TRUE(WaitForClientShutdown());
724 DestroyChannel();
725}
726
727MULTIPROCESS_IPC_TEST_CLIENT_MAIN(
728 IPCChannelMojoTestSendPlatformHandleAndPipeClient) {
729 ListenerThatExpectsFileAndPipe listener;
730 ChannelClient client(&listener,
731 "IPCChannelMojoTestSendPlatformHandleAndPipeClient");
732 client.Connect();
733 listener.set_sender(client.channel());
734
735 base::MessageLoop::current()->Run();
736
rockotcbca72f2015-03-03 16:31:04737 client.Close();
738
morrita81b17e02015-02-06 00:58:30739 return 0;
740}
741
[email protected]64860882014-08-04 23:44:17742#endif
743
morrita0bd20bd2015-02-25 20:11:27744#if defined(OS_LINUX)
745
746const base::ProcessId kMagicChildId = 54321;
747
748class ListenerThatVerifiesPeerPid : public IPC::Listener {
749 public:
750 void OnChannelConnected(int32 peer_pid) override {
751 EXPECT_EQ(peer_pid, kMagicChildId);
752 base::MessageLoop::current()->Quit();
753 }
754
755 bool OnMessageReceived(const IPC::Message& message) override {
756 NOTREACHED();
757 return true;
758 }
759};
760
761TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:04762 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:27763
764 ListenerThatVerifiesPeerPid listener;
765 CreateChannel(&listener);
766 ASSERT_TRUE(ConnectChannel());
767 ASSERT_TRUE(StartClient());
768
769 base::MessageLoop::current()->Run();
rockotcbca72f2015-03-03 16:31:04770 channel()->Close();
morrita0bd20bd2015-02-25 20:11:27771
772 EXPECT_TRUE(WaitForClientShutdown());
773 DestroyChannel();
774}
775
776MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestVerifyGlobalPidClient) {
777 IPC::Channel::SetGlobalPid(kMagicChildId);
778 ListenerThatQuits listener;
779 ChannelClient client(&listener,
780 "IPCChannelMojoTestVerifyGlobalPidClient");
781 client.Connect();
782
783 base::MessageLoop::current()->Run();
784
rockotcbca72f2015-03-03 16:31:04785 client.Close();
786
morrita0bd20bd2015-02-25 20:11:27787 return 0;
788}
789
790#endif // OS_LINUX
791
[email protected]64860882014-08-04 23:44:17792} // namespace