xref: /aosp_15_r20/external/cronet/ipc/ipc_mojo_bootstrap_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_bootstrap.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <cstdint>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
14*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc.mojom.h"
15*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test_base.h"
16*6777b538SAndroid Build Coastguard Worker #include "mojo/core/test/multiprocess_test_helper.h"
17*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_receiver.h"
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker namespace {
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker constexpr int32_t kTestServerPid = 42;
22*6777b538SAndroid Build Coastguard Worker constexpr int32_t kTestClientPid = 4242;
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker class Connection {
25*6777b538SAndroid Build Coastguard Worker  public:
Connection(std::unique_ptr<IPC::MojoBootstrap> bootstrap,int32_t sender_id)26*6777b538SAndroid Build Coastguard Worker   explicit Connection(std::unique_ptr<IPC::MojoBootstrap> bootstrap,
27*6777b538SAndroid Build Coastguard Worker                       int32_t sender_id)
28*6777b538SAndroid Build Coastguard Worker       : bootstrap_(std::move(bootstrap)) {
29*6777b538SAndroid Build Coastguard Worker     mojo::PendingAssociatedRemote<IPC::mojom::Channel> sender;
30*6777b538SAndroid Build Coastguard Worker     bootstrap_->Connect(&sender, &receiver_);
31*6777b538SAndroid Build Coastguard Worker     sender_.Bind(std::move(sender));
32*6777b538SAndroid Build Coastguard Worker     sender_->SetPeerPid(sender_id);
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker     // It's OK to start receiving right away even though `receiver_` isn't
35*6777b538SAndroid Build Coastguard Worker     // bound, because all of these tests are single-threaded and it will be
36*6777b538SAndroid Build Coastguard Worker     // bound before any incoming messages can be scheduled for processing.
37*6777b538SAndroid Build Coastguard Worker     bootstrap_->StartReceiving();
38*6777b538SAndroid Build Coastguard Worker   }
39*6777b538SAndroid Build Coastguard Worker 
TakeReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::Channel> * receiver)40*6777b538SAndroid Build Coastguard Worker   void TakeReceiver(
41*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::Channel>* receiver) {
42*6777b538SAndroid Build Coastguard Worker     *receiver = std::move(receiver_);
43*6777b538SAndroid Build Coastguard Worker   }
44*6777b538SAndroid Build Coastguard Worker 
GetSender()45*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::Channel>& GetSender() { return sender_; }
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker  private:
48*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::Channel> sender_;
49*6777b538SAndroid Build Coastguard Worker   mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver_;
50*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<IPC::MojoBootstrap> bootstrap_;
51*6777b538SAndroid Build Coastguard Worker };
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker class PeerPidReceiver : public IPC::mojom::Channel {
54*6777b538SAndroid Build Coastguard Worker  public:
55*6777b538SAndroid Build Coastguard Worker   enum class MessageExpectation {
56*6777b538SAndroid Build Coastguard Worker     kNotExpected,
57*6777b538SAndroid Build Coastguard Worker     kExpectedValid,
58*6777b538SAndroid Build Coastguard Worker     kExpectedInvalid
59*6777b538SAndroid Build Coastguard Worker   };
60*6777b538SAndroid Build Coastguard Worker 
PeerPidReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver,base::OnceClosure on_peer_pid_set,MessageExpectation message_expectation=MessageExpectation::kNotExpected)61*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver(
62*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver,
63*6777b538SAndroid Build Coastguard Worker       base::OnceClosure on_peer_pid_set,
64*6777b538SAndroid Build Coastguard Worker       MessageExpectation message_expectation = MessageExpectation::kNotExpected)
65*6777b538SAndroid Build Coastguard Worker       : receiver_(this, std::move(receiver)),
66*6777b538SAndroid Build Coastguard Worker         on_peer_pid_set_(std::move(on_peer_pid_set)),
67*6777b538SAndroid Build Coastguard Worker         message_expectation_(message_expectation) {
68*6777b538SAndroid Build Coastguard Worker     receiver_.set_disconnect_handler(disconnect_run_loop_.QuitClosure());
69*6777b538SAndroid Build Coastguard Worker   }
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver(const PeerPidReceiver&) = delete;
72*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver& operator=(const PeerPidReceiver&) = delete;
73*6777b538SAndroid Build Coastguard Worker 
~PeerPidReceiver()74*6777b538SAndroid Build Coastguard Worker   ~PeerPidReceiver() override {
75*6777b538SAndroid Build Coastguard Worker     bool expected_message =
76*6777b538SAndroid Build Coastguard Worker         message_expectation_ != MessageExpectation::kNotExpected;
77*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_message, received_message_);
78*6777b538SAndroid Build Coastguard Worker   }
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   // mojom::Channel:
SetPeerPid(int32_t pid)81*6777b538SAndroid Build Coastguard Worker   void SetPeerPid(int32_t pid) override {
82*6777b538SAndroid Build Coastguard Worker     peer_pid_ = pid;
83*6777b538SAndroid Build Coastguard Worker     std::move(on_peer_pid_set_).Run();
84*6777b538SAndroid Build Coastguard Worker   }
85*6777b538SAndroid Build Coastguard Worker 
Receive(IPC::MessageView message_view)86*6777b538SAndroid Build Coastguard Worker   void Receive(IPC::MessageView message_view) override {
87*6777b538SAndroid Build Coastguard Worker     ASSERT_NE(MessageExpectation::kNotExpected, message_expectation_);
88*6777b538SAndroid Build Coastguard Worker     received_message_ = true;
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker     IPC::Message message(
91*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<const char*>(message_view.bytes().data()),
92*6777b538SAndroid Build Coastguard Worker         message_view.bytes().size());
93*6777b538SAndroid Build Coastguard Worker     bool expected_valid =
94*6777b538SAndroid Build Coastguard Worker         message_expectation_ == MessageExpectation::kExpectedValid;
95*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_valid, message.IsValid());
96*6777b538SAndroid Build Coastguard Worker   }
97*6777b538SAndroid Build Coastguard Worker 
GetAssociatedInterface(mojo::GenericPendingAssociatedReceiver receiver)98*6777b538SAndroid Build Coastguard Worker   void GetAssociatedInterface(
99*6777b538SAndroid Build Coastguard Worker       mojo::GenericPendingAssociatedReceiver receiver) override {}
100*6777b538SAndroid Build Coastguard Worker 
peer_pid() const101*6777b538SAndroid Build Coastguard Worker   int32_t peer_pid() const { return peer_pid_; }
102*6777b538SAndroid Build Coastguard Worker 
RunUntilDisconnect()103*6777b538SAndroid Build Coastguard Worker   void RunUntilDisconnect() { disconnect_run_loop_.Run(); }
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker  private:
106*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::Channel> receiver_;
107*6777b538SAndroid Build Coastguard Worker   base::OnceClosure on_peer_pid_set_;
108*6777b538SAndroid Build Coastguard Worker   MessageExpectation message_expectation_;
109*6777b538SAndroid Build Coastguard Worker   int32_t peer_pid_ = -1;
110*6777b538SAndroid Build Coastguard Worker   bool received_message_ = false;
111*6777b538SAndroid Build Coastguard Worker   base::RunLoop disconnect_run_loop_;
112*6777b538SAndroid Build Coastguard Worker };
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker class IPCMojoBootstrapTest : public testing::Test {
115*6777b538SAndroid Build Coastguard Worker  protected:
116*6777b538SAndroid Build Coastguard Worker   mojo::core::test::MultiprocessTestHelper helper_;
117*6777b538SAndroid Build Coastguard Worker };
118*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCMojoBootstrapTest,Connect)119*6777b538SAndroid Build Coastguard Worker TEST_F(IPCMojoBootstrapTest, Connect) {
120*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
121*6777b538SAndroid Build Coastguard Worker   Connection connection(IPC::MojoBootstrap::Create(
122*6777b538SAndroid Build Coastguard Worker                             helper_.StartChild("IPCMojoBootstrapTestClient"),
123*6777b538SAndroid Build Coastguard Worker                             IPC::Channel::MODE_SERVER,
124*6777b538SAndroid Build Coastguard Worker                             base::SingleThreadTaskRunner::GetCurrentDefault(),
125*6777b538SAndroid Build Coastguard Worker                             base::SingleThreadTaskRunner::GetCurrentDefault()),
126*6777b538SAndroid Build Coastguard Worker                         kTestServerPid);
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
129*6777b538SAndroid Build Coastguard Worker   connection.TakeReceiver(&receiver);
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
132*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
133*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
134*6777b538SAndroid Build Coastguard Worker 
135*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestClientPid, impl.peer_pid());
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker   impl.RunUntilDisconnect();
138*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper_.WaitForChildTestShutdown());
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker 
141*6777b538SAndroid Build Coastguard Worker // A long running process that connects to us.
MULTIPROCESS_TEST_MAIN_WITH_SETUP(IPCMojoBootstrapTestClientTestChildMain,::mojo::core::test::MultiprocessTestHelper::ChildSetup)142*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN_WITH_SETUP(
143*6777b538SAndroid Build Coastguard Worker     IPCMojoBootstrapTestClientTestChildMain,
144*6777b538SAndroid Build Coastguard Worker     ::mojo::core::test::MultiprocessTestHelper::ChildSetup) {
145*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
146*6777b538SAndroid Build Coastguard Worker   Connection connection(
147*6777b538SAndroid Build Coastguard Worker       IPC::MojoBootstrap::Create(
148*6777b538SAndroid Build Coastguard Worker           std::move(mojo::core::test::MultiprocessTestHelper::primordial_pipe),
149*6777b538SAndroid Build Coastguard Worker           IPC::Channel::MODE_CLIENT,
150*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault(),
151*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault()),
152*6777b538SAndroid Build Coastguard Worker       kTestClientPid);
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
155*6777b538SAndroid Build Coastguard Worker   connection.TakeReceiver(&receiver);
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
158*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
159*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestServerPid, impl.peer_pid());
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   return 0;
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCMojoBootstrapTest,ReceiveEmptyMessage)166*6777b538SAndroid Build Coastguard Worker TEST_F(IPCMojoBootstrapTest, ReceiveEmptyMessage) {
167*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
168*6777b538SAndroid Build Coastguard Worker   Connection connection(
169*6777b538SAndroid Build Coastguard Worker       IPC::MojoBootstrap::Create(
170*6777b538SAndroid Build Coastguard Worker           helper_.StartChild("IPCMojoBootstrapTestEmptyMessage"),
171*6777b538SAndroid Build Coastguard Worker           IPC::Channel::MODE_SERVER,
172*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault(),
173*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault()),
174*6777b538SAndroid Build Coastguard Worker       kTestServerPid);
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker   mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
177*6777b538SAndroid Build Coastguard Worker   connection.TakeReceiver(&receiver);
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
180*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure(),
181*6777b538SAndroid Build Coastguard Worker                        PeerPidReceiver::MessageExpectation::kExpectedInvalid);
182*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   // Wait for the Channel to be disconnected so we can reasonably assert that
185*6777b538SAndroid Build Coastguard Worker   // the child's empty message must have been received before we pass the test.
186*6777b538SAndroid Build Coastguard Worker   impl.RunUntilDisconnect();
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper_.WaitForChildTestShutdown());
189*6777b538SAndroid Build Coastguard Worker }
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker // A long running process that connects to us.
MULTIPROCESS_TEST_MAIN_WITH_SETUP(IPCMojoBootstrapTestEmptyMessageTestChildMain,::mojo::core::test::MultiprocessTestHelper::ChildSetup)192*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN_WITH_SETUP(
193*6777b538SAndroid Build Coastguard Worker     IPCMojoBootstrapTestEmptyMessageTestChildMain,
194*6777b538SAndroid Build Coastguard Worker     ::mojo::core::test::MultiprocessTestHelper::ChildSetup) {
195*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
196*6777b538SAndroid Build Coastguard Worker   Connection connection(
197*6777b538SAndroid Build Coastguard Worker       IPC::MojoBootstrap::Create(
198*6777b538SAndroid Build Coastguard Worker           std::move(mojo::core::test::MultiprocessTestHelper::primordial_pipe),
199*6777b538SAndroid Build Coastguard Worker           IPC::Channel::MODE_CLIENT,
200*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault(),
201*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault()),
202*6777b538SAndroid Build Coastguard Worker       kTestClientPid);
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker   mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
205*6777b538SAndroid Build Coastguard Worker   connection.TakeReceiver(&receiver);
206*6777b538SAndroid Build Coastguard Worker   auto& sender = connection.GetSender();
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   uint8_t data = 0;
209*6777b538SAndroid Build Coastguard Worker   sender->Receive(
210*6777b538SAndroid Build Coastguard Worker       IPC::MessageView(base::make_span(&data, 0u), std::nullopt /* handles */));
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
213*6777b538SAndroid Build Coastguard Worker   PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
214*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
215*6777b538SAndroid Build Coastguard Worker 
216*6777b538SAndroid Build Coastguard Worker   return 0;
217*6777b538SAndroid Build Coastguard Worker }
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker }  // namespace
220