blob: 46dca0efd0ef23a8ab5c39f1713e59fb7d85c339 [file] [log] [blame]
morrita54f6f80c2014-09-23 21:16:001// 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_mojo_bootstrap.h"
morrita54f6f80c2014-09-23 21:16:006
avi246998d82015-12-22 02:39:047#include <stdint.h>
danakj03de39b22016-04-23 04:21:098#include <memory>
avi246998d82015-12-22 02:39:049
morrita54f6f80c2014-09-23 21:16:0010#include "base/base_paths.h"
11#include "base/files/file.h"
12#include "base/message_loop/message_loop.h"
rockotcf1d7d02016-11-22 05:27:2713#include "base/run_loop.h"
gabf08ccc02016-05-11 18:51:1114#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0415#include "build/build_config.h"
amistryd4aa70d2016-06-23 07:52:3716#include "ipc/ipc.mojom.h"
morrita54f6f80c2014-09-23 21:16:0017#include "ipc/ipc_test_base.h"
sammce4d0abd2016-03-07 22:38:0418#include "mojo/edk/embedder/embedder.h"
19#include "mojo/edk/test/mojo_test_base.h"
20#include "mojo/edk/test/multiprocess_test_helper.h"
rockota628d0b2017-02-09 08:40:1521#include "mojo/public/cpp/bindings/associated_binding.h"
morrita54f6f80c2014-09-23 21:16:0022
23#if defined(OS_POSIX)
24#include "base/file_descriptor_posix.h"
25#endif
26
27namespace {
28
rockota628d0b2017-02-09 08:40:1529constexpr int32_t kTestServerPid = 42;
30constexpr int32_t kTestClientPid = 4242;
31
Roman Karaseva43d5b4e2017-12-21 03:06:0232class Connection {
33 public:
34 explicit Connection(std::unique_ptr<IPC::MojoBootstrap> bootstrap,
35 int32_t sender_id)
36 : bootstrap_(std::move(bootstrap)) {
37 bootstrap_->Connect(&sender_, &receiver_);
38 sender_->SetPeerPid(sender_id);
39 }
40
41 void TakeReceiver(IPC::mojom::ChannelAssociatedRequest* receiver) {
42 *receiver = std::move(receiver_);
43 }
44
45 IPC::mojom::ChannelAssociatedPtr& GetSender() { return sender_; }
46
47 private:
48 IPC::mojom::ChannelAssociatedPtr sender_;
49 IPC::mojom::ChannelAssociatedRequest receiver_;
50 std::unique_ptr<IPC::MojoBootstrap> bootstrap_;
51};
52
rockota628d0b2017-02-09 08:40:1553class PeerPidReceiver : public IPC::mojom::Channel {
54 public:
Roman Karaseva43d5b4e2017-12-21 03:06:0255 enum class MessageExpectation {
56 kNotExpected,
57 kExpectedValid,
58 kExptectedInvalid
59 };
60
61 PeerPidReceiver(
62 IPC::mojom::ChannelAssociatedRequest request,
63 const base::Closure& on_peer_pid_set,
64 MessageExpectation message_expectation = MessageExpectation::kNotExpected)
65 : binding_(this, std::move(request)),
66 on_peer_pid_set_(on_peer_pid_set),
67 message_expectation_(message_expectation) {}
68 ~PeerPidReceiver() override {}
rockota628d0b2017-02-09 08:40:1569
70 // mojom::Channel:
71 void SetPeerPid(int32_t pid) override {
72 peer_pid_ = pid;
73 on_peer_pid_set_.Run();
74 }
75
Yuzhu Shena0a2b362017-08-25 22:31:3976 void Receive(base::span<const uint8_t> data,
Ken Rockotfd907632017-09-14 04:23:4177 base::Optional<std::vector<mojo::native::SerializedHandlePtr>>
Roman Karaseva43d5b4e2017-12-21 03:06:0278 handles) override {
79 ASSERT_NE(MessageExpectation::kNotExpected, message_expectation_);
80
81 IPC::Message message(reinterpret_cast<const char*>(data.data()),
82 static_cast<uint32_t>(data.size()));
83 bool expected_valid =
84 message_expectation_ == MessageExpectation::kExpectedValid;
85 EXPECT_EQ(expected_valid, message.IsValid());
86 }
rockota628d0b2017-02-09 08:40:1587
88 void GetAssociatedInterface(
89 const std::string& name,
90 IPC::mojom::GenericInterfaceAssociatedRequest request) override {}
91
92 int32_t peer_pid() const { return peer_pid_; }
93
94 private:
95 mojo::AssociatedBinding<IPC::mojom::Channel> binding_;
96 const base::Closure on_peer_pid_set_;
Roman Karaseva43d5b4e2017-12-21 03:06:0297 MessageExpectation message_expectation_;
rockota628d0b2017-02-09 08:40:1598 int32_t peer_pid_ = -1;
99
100 DISALLOW_COPY_AND_ASSIGN(PeerPidReceiver);
101};
102
sammc57ed9f982016-03-10 06:28:35103class IPCMojoBootstrapTest : public testing::Test {
morrita54f6f80c2014-09-23 21:16:00104 protected:
sammc57ed9f982016-03-10 06:28:35105 mojo::edk::test::MultiprocessTestHelper helper_;
morrita54f6f80c2014-09-23 21:16:00106};
107
amistry6de2ee4f2016-05-05 05:12:09108TEST_F(IPCMojoBootstrapTest, Connect) {
sammce4d0abd2016-03-07 22:38:04109 base::MessageLoop message_loop;
Roman Karaseva43d5b4e2017-12-21 03:06:02110 Connection connection(
111 IPC::MojoBootstrap::Create(
112 helper_.StartChild("IPCMojoBootstrapTestClient"),
113 IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(),
114 base::ThreadTaskRunnerHandle::Get()),
115 kTestServerPid);
morrita54f6f80c2014-09-23 21:16:00116
rockota628d0b2017-02-09 08:40:15117 IPC::mojom::ChannelAssociatedRequest receiver;
Roman Karaseva43d5b4e2017-12-21 03:06:02118 connection.TakeReceiver(&receiver);
rockota628d0b2017-02-09 08:40:15119
120 base::RunLoop run_loop;
121 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
sammce4d0abd2016-03-07 22:38:04122 run_loop.Run();
morrita54f6f80c2014-09-23 21:16:00123
rockota628d0b2017-02-09 08:40:15124 EXPECT_EQ(kTestClientPid, impl.peer_pid());
125
sammc57ed9f982016-03-10 06:28:35126 EXPECT_TRUE(helper_.WaitForChildTestShutdown());
morrita54f6f80c2014-09-23 21:16:00127}
128
Roman Karaseva43d5b4e2017-12-21 03:06:02129TEST_F(IPCMojoBootstrapTest, ReceiveEmptyMessage) {
130 base::MessageLoop message_loop;
131 Connection connection(
132 IPC::MojoBootstrap::Create(
133 helper_.StartChild("IPCMojoBootstrapTestEmptyMessage"),
134 IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(),
135 base::ThreadTaskRunnerHandle::Get()),
136 kTestServerPid);
137
138 IPC::mojom::ChannelAssociatedRequest receiver;
139 connection.TakeReceiver(&receiver);
140
141 base::RunLoop run_loop;
142 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure(),
143 PeerPidReceiver::MessageExpectation::kExptectedInvalid);
144 run_loop.Run();
145
146 EXPECT_TRUE(helper_.WaitForChildTestShutdown());
147}
148
sammce4d0abd2016-03-07 22:38:04149// A long running process that connects to us.
sammc57ed9f982016-03-10 06:28:35150MULTIPROCESS_TEST_MAIN_WITH_SETUP(
151 IPCMojoBootstrapTestClientTestChildMain,
152 ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) {
sammce4d0abd2016-03-07 22:38:04153 base::MessageLoop message_loop;
Roman Karaseva43d5b4e2017-12-21 03:06:02154 Connection connection(
155 IPC::MojoBootstrap::Create(
156 std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe),
157 IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(),
158 base::ThreadTaskRunnerHandle::Get()),
159 kTestClientPid);
morrita54f6f80c2014-09-23 21:16:00160
rockota628d0b2017-02-09 08:40:15161 IPC::mojom::ChannelAssociatedRequest receiver;
Roman Karaseva43d5b4e2017-12-21 03:06:02162 connection.TakeReceiver(&receiver);
morrita54f6f80c2014-09-23 21:16:00163
rockota628d0b2017-02-09 08:40:15164 base::RunLoop run_loop;
165 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
sammce4d0abd2016-03-07 22:38:04166 run_loop.Run();
morrita54f6f80c2014-09-23 21:16:00167
rockota628d0b2017-02-09 08:40:15168 EXPECT_EQ(kTestServerPid, impl.peer_pid());
169
170 return 0;
morrita54f6f80c2014-09-23 21:16:00171}
172
Roman Karaseva43d5b4e2017-12-21 03:06:02173// A long running process that connects to us.
174MULTIPROCESS_TEST_MAIN_WITH_SETUP(
175 IPCMojoBootstrapTestEmptyMessageTestChildMain,
176 ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) {
177 base::MessageLoop message_loop;
178 Connection connection(
179 IPC::MojoBootstrap::Create(
180 std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe),
181 IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(),
182 base::ThreadTaskRunnerHandle::Get()),
183 kTestClientPid);
184
185 IPC::mojom::ChannelAssociatedRequest receiver;
186 connection.TakeReceiver(&receiver);
187 auto& sender = connection.GetSender();
188
189 uint8_t data = 0;
190 sender->Receive(base::make_span(&data, 0), {});
191
192 base::RunLoop run_loop;
193 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
194 run_loop.Run();
195
196 return 0;
197}
198
morrita54f6f80c2014-09-23 21:16:00199} // namespace