blob: 47a7ad79a30165c76041075be10b9be8c13f5e75 [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
Ken Rockota47da1e2018-04-05 23:21:357#include <cstdint>
danakj03de39b22016-04-23 04:21:098#include <memory>
Ken Rockota47da1e2018-04-05 23:21:359#include <utility>
avi246998d82015-12-22 02:39:0410
rockotcf1d7d02016-11-22 05:27:2711#include "base/run_loop.h"
Gabriel Charettec7108742019-08-23 03:31:4012#include "base/test/task_environment.h"
gabf08ccc02016-05-11 18:51:1113#include "base/threading/thread_task_runner_handle.h"
amistryd4aa70d2016-06-23 07:52:3714#include "ipc/ipc.mojom.h"
morrita54f6f80c2014-09-23 21:16:0015#include "ipc/ipc_test_base.h"
Ken Rockot8a7f35f2018-07-04 19:40:5616#include "mojo/core/test/multiprocess_test_helper.h"
Julie Jeongeun Kim903b34b2019-09-25 11:11:5417#include "mojo/public/cpp/bindings/associated_receiver.h"
morrita54f6f80c2014-09-23 21:16:0018
morrita54f6f80c2014-09-23 21:16:0019namespace {
20
rockota628d0b2017-02-09 08:40:1521constexpr int32_t kTestServerPid = 42;
22constexpr int32_t kTestClientPid = 4242;
23
Roman Karaseva43d5b4e2017-12-21 03:06:0224class Connection {
25 public:
26 explicit Connection(std::unique_ptr<IPC::MojoBootstrap> bootstrap,
27 int32_t sender_id)
28 : bootstrap_(std::move(bootstrap)) {
29 bootstrap_->Connect(&sender_, &receiver_);
30 sender_->SetPeerPid(sender_id);
31 }
32
Julie Jeongeun Kim903b34b2019-09-25 11:11:5433 void TakeReceiver(
34 mojo::PendingAssociatedReceiver<IPC::mojom::Channel>* receiver) {
Roman Karaseva43d5b4e2017-12-21 03:06:0235 *receiver = std::move(receiver_);
36 }
37
Julie Jeongeun Kim903b34b2019-09-25 11:11:5438 mojo::AssociatedRemote<IPC::mojom::Channel>& GetSender() { return sender_; }
Roman Karaseva43d5b4e2017-12-21 03:06:0239
40 private:
Julie Jeongeun Kim903b34b2019-09-25 11:11:5441 mojo::AssociatedRemote<IPC::mojom::Channel> sender_;
42 mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver_;
Roman Karaseva43d5b4e2017-12-21 03:06:0243 std::unique_ptr<IPC::MojoBootstrap> bootstrap_;
44};
45
rockota628d0b2017-02-09 08:40:1546class PeerPidReceiver : public IPC::mojom::Channel {
47 public:
Roman Karaseva43d5b4e2017-12-21 03:06:0248 enum class MessageExpectation {
49 kNotExpected,
50 kExpectedValid,
Wez3fe9c082018-03-12 23:19:2351 kExpectedInvalid
Roman Karaseva43d5b4e2017-12-21 03:06:0252 };
53
54 PeerPidReceiver(
Julie Jeongeun Kim903b34b2019-09-25 11:11:5455 mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver,
Roman Karaseva43d5b4e2017-12-21 03:06:0256 const base::Closure& on_peer_pid_set,
57 MessageExpectation message_expectation = MessageExpectation::kNotExpected)
Julie Jeongeun Kim903b34b2019-09-25 11:11:5458 : receiver_(this, std::move(receiver)),
Roman Karaseva43d5b4e2017-12-21 03:06:0259 on_peer_pid_set_(on_peer_pid_set),
Ken Rockota47da1e2018-04-05 23:21:3560 message_expectation_(message_expectation) {
Julie Jeongeun Kim903b34b2019-09-25 11:11:5461 receiver_.set_disconnect_handler(disconnect_run_loop_.QuitClosure());
Ken Rockota47da1e2018-04-05 23:21:3562 }
63
Wez3fe9c082018-03-12 23:19:2364 ~PeerPidReceiver() override {
65 bool expected_message =
66 message_expectation_ != MessageExpectation::kNotExpected;
67 EXPECT_EQ(expected_message, received_message_);
68 }
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
Ken Rockot4c5bd802018-07-12 01:37:1176 void Receive(IPC::MessageView message_view) override {
Roman Karaseva43d5b4e2017-12-21 03:06:0277 ASSERT_NE(MessageExpectation::kNotExpected, message_expectation_);
Wez3fe9c082018-03-12 23:19:2378 received_message_ = true;
Roman Karaseva43d5b4e2017-12-21 03:06:0279
Ken Rockot4c5bd802018-07-12 01:37:1180 IPC::Message message(message_view.data(), message_view.size());
Roman Karaseva43d5b4e2017-12-21 03:06:0281 bool expected_valid =
82 message_expectation_ == MessageExpectation::kExpectedValid;
83 EXPECT_EQ(expected_valid, message.IsValid());
84 }
rockota628d0b2017-02-09 08:40:1585
86 void GetAssociatedInterface(
87 const std::string& name,
Julie Jeongeun Kim69604f62019-12-04 01:59:5288 mojo::PendingAssociatedReceiver<IPC::mojom::GenericInterface> receiver)
89 override {}
rockota628d0b2017-02-09 08:40:1590
91 int32_t peer_pid() const { return peer_pid_; }
92
Ken Rockota47da1e2018-04-05 23:21:3593 void RunUntilDisconnect() { disconnect_run_loop_.Run(); }
Ken Rockot146d0892018-03-27 03:31:0794
rockota628d0b2017-02-09 08:40:1595 private:
Julie Jeongeun Kim903b34b2019-09-25 11:11:5496 mojo::AssociatedReceiver<IPC::mojom::Channel> receiver_;
rockota628d0b2017-02-09 08:40:1597 const base::Closure on_peer_pid_set_;
Roman Karaseva43d5b4e2017-12-21 03:06:0298 MessageExpectation message_expectation_;
rockota628d0b2017-02-09 08:40:1599 int32_t peer_pid_ = -1;
Wez3fe9c082018-03-12 23:19:23100 bool received_message_ = false;
Ken Rockota47da1e2018-04-05 23:21:35101 base::RunLoop disconnect_run_loop_;
Wez3fe9c082018-03-12 23:19:23102
rockota628d0b2017-02-09 08:40:15103 DISALLOW_COPY_AND_ASSIGN(PeerPidReceiver);
104};
105
sammc57ed9f982016-03-10 06:28:35106class IPCMojoBootstrapTest : public testing::Test {
morrita54f6f80c2014-09-23 21:16:00107 protected:
Ken Rockot8a7f35f2018-07-04 19:40:56108 mojo::core::test::MultiprocessTestHelper helper_;
morrita54f6f80c2014-09-23 21:16:00109};
110
amistry6de2ee4f2016-05-05 05:12:09111TEST_F(IPCMojoBootstrapTest, Connect) {
Gabriel Charettec523fa62019-09-09 23:03:32112 base::test::SingleThreadTaskEnvironment task_environment;
Roman Karaseva43d5b4e2017-12-21 03:06:02113 Connection connection(
114 IPC::MojoBootstrap::Create(
115 helper_.StartChild("IPCMojoBootstrapTestClient"),
116 IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(),
Sigurdur Asgeirssond655dd65f2019-11-12 19:32:20117 base::ThreadTaskRunnerHandle::Get(), nullptr),
Roman Karaseva43d5b4e2017-12-21 03:06:02118 kTestServerPid);
morrita54f6f80c2014-09-23 21:16:00119
Julie Jeongeun Kim903b34b2019-09-25 11:11:54120 mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
Roman Karaseva43d5b4e2017-12-21 03:06:02121 connection.TakeReceiver(&receiver);
rockota628d0b2017-02-09 08:40:15122
123 base::RunLoop run_loop;
124 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
sammce4d0abd2016-03-07 22:38:04125 run_loop.Run();
morrita54f6f80c2014-09-23 21:16:00126
rockota628d0b2017-02-09 08:40:15127 EXPECT_EQ(kTestClientPid, impl.peer_pid());
128
Ken Rockot146d0892018-03-27 03:31:07129 impl.RunUntilDisconnect();
Roman Karaseva43d5b4e2017-12-21 03:06:02130 EXPECT_TRUE(helper_.WaitForChildTestShutdown());
131}
132
sammce4d0abd2016-03-07 22:38:04133// A long running process that connects to us.
sammc57ed9f982016-03-10 06:28:35134MULTIPROCESS_TEST_MAIN_WITH_SETUP(
135 IPCMojoBootstrapTestClientTestChildMain,
Ken Rockot8a7f35f2018-07-04 19:40:56136 ::mojo::core::test::MultiprocessTestHelper::ChildSetup) {
Gabriel Charettec523fa62019-09-09 23:03:32137 base::test::SingleThreadTaskEnvironment task_environment;
Roman Karaseva43d5b4e2017-12-21 03:06:02138 Connection connection(
139 IPC::MojoBootstrap::Create(
Ken Rockot8a7f35f2018-07-04 19:40:56140 std::move(mojo::core::test::MultiprocessTestHelper::primordial_pipe),
Roman Karaseva43d5b4e2017-12-21 03:06:02141 IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(),
Sigurdur Asgeirssond655dd65f2019-11-12 19:32:20142 base::ThreadTaskRunnerHandle::Get(), nullptr),
Roman Karaseva43d5b4e2017-12-21 03:06:02143 kTestClientPid);
morrita54f6f80c2014-09-23 21:16:00144
Julie Jeongeun Kim903b34b2019-09-25 11:11:54145 mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
Roman Karaseva43d5b4e2017-12-21 03:06:02146 connection.TakeReceiver(&receiver);
morrita54f6f80c2014-09-23 21:16:00147
rockota628d0b2017-02-09 08:40:15148 base::RunLoop run_loop;
149 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
sammce4d0abd2016-03-07 22:38:04150 run_loop.Run();
morrita54f6f80c2014-09-23 21:16:00151
rockota628d0b2017-02-09 08:40:15152 EXPECT_EQ(kTestServerPid, impl.peer_pid());
153
154 return 0;
morrita54f6f80c2014-09-23 21:16:00155}
156
Ken Rockota47da1e2018-04-05 23:21:35157TEST_F(IPCMojoBootstrapTest, ReceiveEmptyMessage) {
Gabriel Charettec523fa62019-09-09 23:03:32158 base::test::SingleThreadTaskEnvironment task_environment;
Ken Rockot146d0892018-03-27 03:31:07159 Connection connection(
160 IPC::MojoBootstrap::Create(
161 helper_.StartChild("IPCMojoBootstrapTestEmptyMessage"),
162 IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(),
Sigurdur Asgeirssond655dd65f2019-11-12 19:32:20163 base::ThreadTaskRunnerHandle::Get(), nullptr),
Ken Rockot146d0892018-03-27 03:31:07164 kTestServerPid);
165
Julie Jeongeun Kim903b34b2019-09-25 11:11:54166 mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
Ken Rockot146d0892018-03-27 03:31:07167 connection.TakeReceiver(&receiver);
168
169 base::RunLoop run_loop;
170 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure(),
171 PeerPidReceiver::MessageExpectation::kExpectedInvalid);
172 run_loop.Run();
173
174 // Wait for the Channel to be disconnected so we can reasonably assert that
175 // the child's empty message must have been received before we pass the test.
176 impl.RunUntilDisconnect();
177
178 EXPECT_TRUE(helper_.WaitForChildTestShutdown());
179}
180
Roman Karaseva43d5b4e2017-12-21 03:06:02181// A long running process that connects to us.
182MULTIPROCESS_TEST_MAIN_WITH_SETUP(
183 IPCMojoBootstrapTestEmptyMessageTestChildMain,
Ken Rockot8a7f35f2018-07-04 19:40:56184 ::mojo::core::test::MultiprocessTestHelper::ChildSetup) {
Gabriel Charettec523fa62019-09-09 23:03:32185 base::test::SingleThreadTaskEnvironment task_environment;
Roman Karaseva43d5b4e2017-12-21 03:06:02186 Connection connection(
187 IPC::MojoBootstrap::Create(
Ken Rockot8a7f35f2018-07-04 19:40:56188 std::move(mojo::core::test::MultiprocessTestHelper::primordial_pipe),
Roman Karaseva43d5b4e2017-12-21 03:06:02189 IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(),
Sigurdur Asgeirssond655dd65f2019-11-12 19:32:20190 base::ThreadTaskRunnerHandle::Get(), nullptr),
Roman Karaseva43d5b4e2017-12-21 03:06:02191 kTestClientPid);
192
Julie Jeongeun Kim903b34b2019-09-25 11:11:54193 mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
Roman Karaseva43d5b4e2017-12-21 03:06:02194 connection.TakeReceiver(&receiver);
195 auto& sender = connection.GetSender();
196
197 uint8_t data = 0;
Ken Rockot4c5bd802018-07-12 01:37:11198 sender->Receive(
199 IPC::MessageView(mojo_base::BigBufferView(base::make_span(&data, 0)),
200 base::nullopt /* handles */));
Roman Karaseva43d5b4e2017-12-21 03:06:02201
202 base::RunLoop run_loop;
203 PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
204 run_loop.Run();
205
206 return 0;
207}
208
morrita54f6f80c2014-09-23 21:16:00209} // namespace