xref: /aosp_15_r20/external/perfetto/src/base/unix_socket_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/unix_socket.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <signal.h>
20*6dbdd20aSAndroid Build Coastguard Worker #include <sys/types.h>
21*6dbdd20aSAndroid Build Coastguard Worker #include <list>
22*6dbdd20aSAndroid Build Coastguard Worker #include <thread>
23*6dbdd20aSAndroid Build Coastguard Worker 
24*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
25*6dbdd20aSAndroid Build Coastguard Worker #include <sys/mman.h>
26*6dbdd20aSAndroid Build Coastguard Worker #include <sys/socket.h>
27*6dbdd20aSAndroid Build Coastguard Worker #include <sys/un.h>
28*6dbdd20aSAndroid Build Coastguard Worker #endif
29*6dbdd20aSAndroid Build Coastguard Worker 
30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
32*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
33*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/periodic_task.h"
34*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/pipe.h"
35*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_utils.h"
36*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/temp_file.h"
37*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/utils.h"
38*6dbdd20aSAndroid Build Coastguard Worker #include "src/base/test/test_task_runner.h"
39*6dbdd20aSAndroid Build Coastguard Worker #include "src/ipc/test/test_socket.h"
40*6dbdd20aSAndroid Build Coastguard Worker #include "test/gtest_and_gmock.h"
41*6dbdd20aSAndroid Build Coastguard Worker 
42*6dbdd20aSAndroid Build Coastguard Worker #if (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
43*6dbdd20aSAndroid Build Coastguard Worker      PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
44*6dbdd20aSAndroid Build Coastguard Worker #define SKIP_IF_VSOCK_LOOPBACK_NOT_SUPPORTED()                                 \
45*6dbdd20aSAndroid Build Coastguard Worker   do {                                                                         \
46*6dbdd20aSAndroid Build Coastguard Worker     if (!UnixSocketRaw::CreateMayFail(SockFamily::kVsock, SockType::kStream)   \
47*6dbdd20aSAndroid Build Coastguard Worker              .Bind("vsock://1:10000")) {                                       \
48*6dbdd20aSAndroid Build Coastguard Worker       GTEST_SKIP() << "vsock testing skipped: loopback address unsupported.\n" \
49*6dbdd20aSAndroid Build Coastguard Worker                    << "Please run sudo modprobe vsock-loopback";               \
50*6dbdd20aSAndroid Build Coastguard Worker     }                                                                          \
51*6dbdd20aSAndroid Build Coastguard Worker   } while (0)
52*6dbdd20aSAndroid Build Coastguard Worker #endif
53*6dbdd20aSAndroid Build Coastguard Worker 
54*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
55*6dbdd20aSAndroid Build Coastguard Worker namespace base {
56*6dbdd20aSAndroid Build Coastguard Worker namespace {
57*6dbdd20aSAndroid Build Coastguard Worker 
58*6dbdd20aSAndroid Build Coastguard Worker using ::testing::_;
59*6dbdd20aSAndroid Build Coastguard Worker using ::testing::AtLeast;
60*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Invoke;
61*6dbdd20aSAndroid Build Coastguard Worker using ::testing::InvokeWithoutArgs;
62*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Mock;
63*6dbdd20aSAndroid Build Coastguard Worker 
64*6dbdd20aSAndroid Build Coastguard Worker ipc::TestSocket kTestSocket{"unix_socket_unittest"};
65*6dbdd20aSAndroid Build Coastguard Worker 
66*6dbdd20aSAndroid Build Coastguard Worker class MockEventListener : public UnixSocket::EventListener {
67*6dbdd20aSAndroid Build Coastguard Worker  public:
68*6dbdd20aSAndroid Build Coastguard Worker   MOCK_METHOD(void, OnNewIncomingConnection, (UnixSocket*, UnixSocket*));
69*6dbdd20aSAndroid Build Coastguard Worker   MOCK_METHOD(void, OnConnect, (UnixSocket*, bool), (override));
70*6dbdd20aSAndroid Build Coastguard Worker   MOCK_METHOD(void, OnDisconnect, (UnixSocket*), (override));
71*6dbdd20aSAndroid Build Coastguard Worker   MOCK_METHOD(void, OnDataAvailable, (UnixSocket*), (override));
72*6dbdd20aSAndroid Build Coastguard Worker 
73*6dbdd20aSAndroid Build Coastguard Worker   // GMock doesn't support mocking methods with non-copiable args.
OnNewIncomingConnection(UnixSocket * self,std::unique_ptr<UnixSocket> new_connection)74*6dbdd20aSAndroid Build Coastguard Worker   void OnNewIncomingConnection(
75*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket* self,
76*6dbdd20aSAndroid Build Coastguard Worker       std::unique_ptr<UnixSocket> new_connection) override {
77*6dbdd20aSAndroid Build Coastguard Worker     incoming_connections_.emplace_back(std::move(new_connection));
78*6dbdd20aSAndroid Build Coastguard Worker     OnNewIncomingConnection(self, incoming_connections_.back().get());
79*6dbdd20aSAndroid Build Coastguard Worker   }
80*6dbdd20aSAndroid Build Coastguard Worker 
GetIncomingConnection()81*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<UnixSocket> GetIncomingConnection() {
82*6dbdd20aSAndroid Build Coastguard Worker     if (incoming_connections_.empty())
83*6dbdd20aSAndroid Build Coastguard Worker       return nullptr;
84*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<UnixSocket> sock = std::move(incoming_connections_.front());
85*6dbdd20aSAndroid Build Coastguard Worker     incoming_connections_.pop_front();
86*6dbdd20aSAndroid Build Coastguard Worker     return sock;
87*6dbdd20aSAndroid Build Coastguard Worker   }
88*6dbdd20aSAndroid Build Coastguard Worker 
89*6dbdd20aSAndroid Build Coastguard Worker  private:
90*6dbdd20aSAndroid Build Coastguard Worker   std::list<std::unique_ptr<UnixSocket>> incoming_connections_;
91*6dbdd20aSAndroid Build Coastguard Worker };
92*6dbdd20aSAndroid Build Coastguard Worker 
93*6dbdd20aSAndroid Build Coastguard Worker class UnixSocketTest : public ::testing::Test {
94*6dbdd20aSAndroid Build Coastguard Worker  protected:
SetUp()95*6dbdd20aSAndroid Build Coastguard Worker   void SetUp() override { kTestSocket.Destroy(); }
TearDown()96*6dbdd20aSAndroid Build Coastguard Worker   void TearDown() override { kTestSocket.Destroy(); }
97*6dbdd20aSAndroid Build Coastguard Worker 
98*6dbdd20aSAndroid Build Coastguard Worker   TestTaskRunner task_runner_;
99*6dbdd20aSAndroid Build Coastguard Worker   MockEventListener event_listener_;
100*6dbdd20aSAndroid Build Coastguard Worker };
101*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ConnectionFailureIfUnreachable)102*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ConnectionFailureIfUnreachable) {
103*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
104*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
105*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
106*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_FALSE(cli->is_connected());
107*6dbdd20aSAndroid Build Coastguard Worker   auto checkpoint = task_runner_.CreateCheckpoint("failure");
108*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), false))
109*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(checkpoint));
110*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("failure");
111*6dbdd20aSAndroid Build Coastguard Worker }
112*6dbdd20aSAndroid Build Coastguard Worker 
113*6dbdd20aSAndroid Build Coastguard Worker // Both server and client should see an OnDisconnect() if the server drops
114*6dbdd20aSAndroid Build Coastguard Worker // incoming connections immediately as they are created.
TEST_F(UnixSocketTest,ConnectionImmediatelyDroppedByServer)115*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ConnectionImmediatelyDroppedByServer) {
116*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
117*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
118*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
119*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
120*6dbdd20aSAndroid Build Coastguard Worker 
121*6dbdd20aSAndroid Build Coastguard Worker   // The server will immediately shutdown the connection upon
122*6dbdd20aSAndroid Build Coastguard Worker   // OnNewIncomingConnection().
123*6dbdd20aSAndroid Build Coastguard Worker   auto srv_did_shutdown = task_runner_.CreateCheckpoint("srv_did_shutdown");
124*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
125*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(
126*6dbdd20aSAndroid Build Coastguard Worker           Invoke([this, srv_did_shutdown](UnixSocket*, UnixSocket* new_conn) {
127*6dbdd20aSAndroid Build Coastguard Worker             EXPECT_CALL(event_listener_, OnDisconnect(new_conn));
128*6dbdd20aSAndroid Build Coastguard Worker             new_conn->Shutdown(true);
129*6dbdd20aSAndroid Build Coastguard Worker             srv_did_shutdown();
130*6dbdd20aSAndroid Build Coastguard Worker           }));
131*6dbdd20aSAndroid Build Coastguard Worker 
132*6dbdd20aSAndroid Build Coastguard Worker   auto checkpoint = task_runner_.CreateCheckpoint("cli_connected");
133*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
134*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
135*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
136*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
137*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(checkpoint));
138*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_connected");
139*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_did_shutdown");
140*6dbdd20aSAndroid Build Coastguard Worker 
141*6dbdd20aSAndroid Build Coastguard Worker   // Trying to send something will trigger the disconnection notification.
142*6dbdd20aSAndroid Build Coastguard Worker   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
143*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDisconnect(cli.get()))
144*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_disconnected));
145*6dbdd20aSAndroid Build Coastguard Worker 
146*6dbdd20aSAndroid Build Coastguard Worker   // On Windows the first send immediately after the disconnection succeeds, the
147*6dbdd20aSAndroid Build Coastguard Worker   // kernel will detect the disconnection only later.
148*6dbdd20aSAndroid Build Coastguard Worker   cli->SendStr(".");
149*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(cli->SendStr("should_fail_both_on_win_and_unix"));
150*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_disconnected");
151*6dbdd20aSAndroid Build Coastguard Worker }
152*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ClientAndServerExchangeData)153*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ClientAndServerExchangeData) {
154*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
155*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
156*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
157*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
158*6dbdd20aSAndroid Build Coastguard Worker 
159*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
160*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
161*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
162*6dbdd20aSAndroid Build Coastguard Worker   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
163*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
164*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_connected));
165*6dbdd20aSAndroid Build Coastguard Worker   auto srv_conn_seen = task_runner_.CreateCheckpoint("srv_conn_seen");
166*6dbdd20aSAndroid Build Coastguard Worker   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
167*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
168*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([this, srv_conn_seen, srv_disconnected](
169*6dbdd20aSAndroid Build Coastguard Worker                            UnixSocket*, UnixSocket* srv_conn) {
170*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDisconnect(srv_conn))
171*6dbdd20aSAndroid Build Coastguard Worker             .WillOnce(InvokeWithoutArgs(srv_disconnected));
172*6dbdd20aSAndroid Build Coastguard Worker         srv_conn_seen();
173*6dbdd20aSAndroid Build Coastguard Worker       }));
174*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_conn_seen");
175*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_connected");
176*6dbdd20aSAndroid Build Coastguard Worker 
177*6dbdd20aSAndroid Build Coastguard Worker   auto srv_conn = event_listener_.GetIncomingConnection();
178*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv_conn);
179*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(cli->is_connected());
180*6dbdd20aSAndroid Build Coastguard Worker 
181*6dbdd20aSAndroid Build Coastguard Worker   auto cli_did_recv = task_runner_.CreateCheckpoint("cli_did_recv");
182*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
183*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([cli_did_recv](UnixSocket* s) {
184*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ("srv>cli", s->ReceiveString());
185*6dbdd20aSAndroid Build Coastguard Worker         cli_did_recv();
186*6dbdd20aSAndroid Build Coastguard Worker       }));
187*6dbdd20aSAndroid Build Coastguard Worker 
188*6dbdd20aSAndroid Build Coastguard Worker   auto srv_did_recv = task_runner_.CreateCheckpoint("srv_did_recv");
189*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn.get()))
190*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([srv_did_recv](UnixSocket* s) {
191*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ("cli>srv", s->ReceiveString());
192*6dbdd20aSAndroid Build Coastguard Worker         srv_did_recv();
193*6dbdd20aSAndroid Build Coastguard Worker       }));
194*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(cli->SendStr("cli>srv"));
195*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv_conn->SendStr("srv>cli"));
196*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_did_recv");
197*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_did_recv");
198*6dbdd20aSAndroid Build Coastguard Worker 
199*6dbdd20aSAndroid Build Coastguard Worker   // Check that Send/Receive() fails gracefully once the socket is closed.
200*6dbdd20aSAndroid Build Coastguard Worker   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
201*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDisconnect(cli.get()))
202*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_disconnected));
203*6dbdd20aSAndroid Build Coastguard Worker   cli->Shutdown(true);
204*6dbdd20aSAndroid Build Coastguard Worker   char msg[4];
205*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(0u, cli->Receive(&msg, sizeof(msg)));
206*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ("", cli->ReceiveString());
207*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(0u, srv_conn->Receive(&msg, sizeof(msg)));
208*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ("", srv_conn->ReceiveString());
209*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_FALSE(cli->SendStr("foo"));
210*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_FALSE(srv_conn->SendStr("bar"));
211*6dbdd20aSAndroid Build Coastguard Worker   srv->Shutdown(true);
212*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_disconnected");
213*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_disconnected");
214*6dbdd20aSAndroid Build Coastguard Worker }
215*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ListenWithPassedSocketHandle)216*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ListenWithPassedSocketHandle) {
217*6dbdd20aSAndroid Build Coastguard Worker   auto sock_raw =
218*6dbdd20aSAndroid Build Coastguard Worker       UnixSocketRaw::CreateMayFail(kTestSocket.family(), SockType::kStream);
219*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(sock_raw.Bind(kTestSocket.name()));
220*6dbdd20aSAndroid Build Coastguard Worker   auto fd = sock_raw.ReleaseFd();
221*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen(std::move(fd), &event_listener_, &task_runner_,
222*6dbdd20aSAndroid Build Coastguard Worker                                 kTestSocket.family(), SockType::kStream);
223*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
224*6dbdd20aSAndroid Build Coastguard Worker 
225*6dbdd20aSAndroid Build Coastguard Worker   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
226*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
227*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
228*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
229*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
230*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_connected));
231*6dbdd20aSAndroid Build Coastguard Worker   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
232*6dbdd20aSAndroid Build Coastguard Worker   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
233*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
234*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([this, srv_connected, srv_disconnected](
235*6dbdd20aSAndroid Build Coastguard Worker                            UnixSocket*, UnixSocket* srv_conn) {
236*6dbdd20aSAndroid Build Coastguard Worker         // An empty OnDataAvailable might be raised to signal the EOF state.
237*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn))
238*6dbdd20aSAndroid Build Coastguard Worker             .WillRepeatedly(
239*6dbdd20aSAndroid Build Coastguard Worker                 InvokeWithoutArgs([srv_conn] { srv_conn->ReceiveString(); }));
240*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDisconnect(srv_conn))
241*6dbdd20aSAndroid Build Coastguard Worker             .WillOnce(InvokeWithoutArgs(srv_disconnected));
242*6dbdd20aSAndroid Build Coastguard Worker         srv_connected();
243*6dbdd20aSAndroid Build Coastguard Worker       }));
244*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_connected");
245*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_connected");
246*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(cli->is_connected());
247*6dbdd20aSAndroid Build Coastguard Worker   cli.reset();
248*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_disconnected");
249*6dbdd20aSAndroid Build Coastguard Worker }
250*6dbdd20aSAndroid Build Coastguard Worker 
251*6dbdd20aSAndroid Build Coastguard Worker // Mostly a stress tests. Connects kNumClients clients to the same server and
252*6dbdd20aSAndroid Build Coastguard Worker // tests that all can exchange data and can see the expected sequence of events.
TEST_F(UnixSocketTest,SeveralClients)253*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, SeveralClients) {
254*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
255*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
256*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
257*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
258*6dbdd20aSAndroid Build Coastguard Worker   constexpr size_t kNumClients = 32;
259*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<UnixSocket> cli[kNumClients];
260*6dbdd20aSAndroid Build Coastguard Worker 
261*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
262*6dbdd20aSAndroid Build Coastguard Worker       .Times(kNumClients)
263*6dbdd20aSAndroid Build Coastguard Worker       .WillRepeatedly(Invoke([this](UnixSocket*, UnixSocket* s) {
264*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDataAvailable(s))
265*6dbdd20aSAndroid Build Coastguard Worker             .WillOnce(Invoke([](UnixSocket* t) {
266*6dbdd20aSAndroid Build Coastguard Worker               ASSERT_EQ("PING", t->ReceiveString());
267*6dbdd20aSAndroid Build Coastguard Worker               ASSERT_TRUE(t->SendStr("PONG"));
268*6dbdd20aSAndroid Build Coastguard Worker             }));
269*6dbdd20aSAndroid Build Coastguard Worker       }));
270*6dbdd20aSAndroid Build Coastguard Worker 
271*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumClients; i++) {
272*6dbdd20aSAndroid Build Coastguard Worker     cli[i] =
273*6dbdd20aSAndroid Build Coastguard Worker         UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
274*6dbdd20aSAndroid Build Coastguard Worker                             kTestSocket.family(), SockType::kStream);
275*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true))
276*6dbdd20aSAndroid Build Coastguard Worker         .WillOnce(Invoke([](UnixSocket* s, bool success) {
277*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_TRUE(success);
278*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_TRUE(s->SendStr("PING"));
279*6dbdd20aSAndroid Build Coastguard Worker         }));
280*6dbdd20aSAndroid Build Coastguard Worker 
281*6dbdd20aSAndroid Build Coastguard Worker     auto checkpoint = task_runner_.CreateCheckpoint(std::to_string(i));
282*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnDataAvailable(cli[i].get()))
283*6dbdd20aSAndroid Build Coastguard Worker         .WillOnce(Invoke([checkpoint](UnixSocket* s) {
284*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_EQ("PONG", s->ReceiveString());
285*6dbdd20aSAndroid Build Coastguard Worker           checkpoint();
286*6dbdd20aSAndroid Build Coastguard Worker         }));
287*6dbdd20aSAndroid Build Coastguard Worker   }
288*6dbdd20aSAndroid Build Coastguard Worker 
289*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumClients; i++) {
290*6dbdd20aSAndroid Build Coastguard Worker     task_runner_.RunUntilCheckpoint(std::to_string(i));
291*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(Mock::VerifyAndClearExpectations(cli[i].get()));
292*6dbdd20aSAndroid Build Coastguard Worker   }
293*6dbdd20aSAndroid Build Coastguard Worker }
294*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,BlockingSend)295*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, BlockingSend) {
296*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
297*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
298*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
299*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
300*6dbdd20aSAndroid Build Coastguard Worker 
301*6dbdd20aSAndroid Build Coastguard Worker   auto all_frames_done = task_runner_.CreateCheckpoint("all_frames_done");
302*6dbdd20aSAndroid Build Coastguard Worker   size_t total_bytes_received = 0;
303*6dbdd20aSAndroid Build Coastguard Worker   static constexpr size_t kTotalBytes = 1024 * 1024 * 4;
304*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
305*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([this, &total_bytes_received, all_frames_done](
306*6dbdd20aSAndroid Build Coastguard Worker                            UnixSocket*, UnixSocket* srv_conn) {
307*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn))
308*6dbdd20aSAndroid Build Coastguard Worker             .WillRepeatedly(
309*6dbdd20aSAndroid Build Coastguard Worker                 Invoke([&total_bytes_received, all_frames_done](UnixSocket* s) {
310*6dbdd20aSAndroid Build Coastguard Worker                   char buf[1024];
311*6dbdd20aSAndroid Build Coastguard Worker                   size_t res = s->Receive(buf, sizeof(buf));
312*6dbdd20aSAndroid Build Coastguard Worker                   total_bytes_received += res;
313*6dbdd20aSAndroid Build Coastguard Worker                   if (total_bytes_received == kTotalBytes)
314*6dbdd20aSAndroid Build Coastguard Worker                     all_frames_done();
315*6dbdd20aSAndroid Build Coastguard Worker                 }));
316*6dbdd20aSAndroid Build Coastguard Worker       }));
317*6dbdd20aSAndroid Build Coastguard Worker 
318*6dbdd20aSAndroid Build Coastguard Worker   // Override default timeout as this test can take time on the emulator.
319*6dbdd20aSAndroid Build Coastguard Worker   static constexpr int kTimeoutMs = 60000 * 3;
320*6dbdd20aSAndroid Build Coastguard Worker 
321*6dbdd20aSAndroid Build Coastguard Worker   // Perform the blocking send form another thread.
322*6dbdd20aSAndroid Build Coastguard Worker   std::thread tx_thread([] {
323*6dbdd20aSAndroid Build Coastguard Worker     TestTaskRunner tx_task_runner;
324*6dbdd20aSAndroid Build Coastguard Worker     MockEventListener tx_events;
325*6dbdd20aSAndroid Build Coastguard Worker     auto cli =
326*6dbdd20aSAndroid Build Coastguard Worker         UnixSocket::Connect(kTestSocket.name(), &tx_events, &tx_task_runner,
327*6dbdd20aSAndroid Build Coastguard Worker                             kTestSocket.family(), SockType::kStream);
328*6dbdd20aSAndroid Build Coastguard Worker 
329*6dbdd20aSAndroid Build Coastguard Worker     auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
330*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
331*6dbdd20aSAndroid Build Coastguard Worker         .WillOnce(InvokeWithoutArgs(cli_connected));
332*6dbdd20aSAndroid Build Coastguard Worker     tx_task_runner.RunUntilCheckpoint("cli_connected");
333*6dbdd20aSAndroid Build Coastguard Worker 
334*6dbdd20aSAndroid Build Coastguard Worker     auto all_sent = tx_task_runner.CreateCheckpoint("all_sent");
335*6dbdd20aSAndroid Build Coastguard Worker     std::string buf(1024 * 32, '\0');
336*6dbdd20aSAndroid Build Coastguard Worker     tx_task_runner.PostTask([&cli, &buf, all_sent] {
337*6dbdd20aSAndroid Build Coastguard Worker       for (size_t i = 0; i < kTotalBytes / buf.size(); i++)
338*6dbdd20aSAndroid Build Coastguard Worker         cli->Send(buf.data(), buf.size());
339*6dbdd20aSAndroid Build Coastguard Worker       all_sent();
340*6dbdd20aSAndroid Build Coastguard Worker     });
341*6dbdd20aSAndroid Build Coastguard Worker     tx_task_runner.RunUntilCheckpoint("all_sent", kTimeoutMs);
342*6dbdd20aSAndroid Build Coastguard Worker   });
343*6dbdd20aSAndroid Build Coastguard Worker 
344*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("all_frames_done", kTimeoutMs);
345*6dbdd20aSAndroid Build Coastguard Worker   tx_thread.join();
346*6dbdd20aSAndroid Build Coastguard Worker }
347*6dbdd20aSAndroid Build Coastguard Worker 
348*6dbdd20aSAndroid Build Coastguard Worker // Regression test for b/76155349 . If the receiver end disconnects while the
349*6dbdd20aSAndroid Build Coastguard Worker // sender is in the middle of a large send(), the socket should gracefully give
350*6dbdd20aSAndroid Build Coastguard Worker // up (i.e. Shutdown()) but not crash.
TEST_F(UnixSocketTest,ReceiverDisconnectsDuringSend)351*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ReceiverDisconnectsDuringSend) {
352*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
353*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
354*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
355*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
356*6dbdd20aSAndroid Build Coastguard Worker   static constexpr int kTimeoutMs = 30000;
357*6dbdd20aSAndroid Build Coastguard Worker 
358*6dbdd20aSAndroid Build Coastguard Worker   auto receive_done = task_runner_.CreateCheckpoint("receive_done");
359*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
360*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([this, receive_done](UnixSocket*, UnixSocket* srv_conn) {
361*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn))
362*6dbdd20aSAndroid Build Coastguard Worker             .WillOnce(Invoke([receive_done](UnixSocket* s) {
363*6dbdd20aSAndroid Build Coastguard Worker               char buf[1024];
364*6dbdd20aSAndroid Build Coastguard Worker               size_t res = s->Receive(buf, sizeof(buf));
365*6dbdd20aSAndroid Build Coastguard Worker               ASSERT_EQ(1024u, res);
366*6dbdd20aSAndroid Build Coastguard Worker               s->Shutdown(false /*notify*/);
367*6dbdd20aSAndroid Build Coastguard Worker               receive_done();
368*6dbdd20aSAndroid Build Coastguard Worker             }));
369*6dbdd20aSAndroid Build Coastguard Worker       }));
370*6dbdd20aSAndroid Build Coastguard Worker 
371*6dbdd20aSAndroid Build Coastguard Worker   // Perform the blocking send form another thread.
372*6dbdd20aSAndroid Build Coastguard Worker   std::thread tx_thread([] {
373*6dbdd20aSAndroid Build Coastguard Worker     TestTaskRunner tx_task_runner;
374*6dbdd20aSAndroid Build Coastguard Worker     MockEventListener tx_events;
375*6dbdd20aSAndroid Build Coastguard Worker     auto cli =
376*6dbdd20aSAndroid Build Coastguard Worker         UnixSocket::Connect(kTestSocket.name(), &tx_events, &tx_task_runner,
377*6dbdd20aSAndroid Build Coastguard Worker                             kTestSocket.family(), SockType::kStream);
378*6dbdd20aSAndroid Build Coastguard Worker 
379*6dbdd20aSAndroid Build Coastguard Worker     auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
380*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
381*6dbdd20aSAndroid Build Coastguard Worker         .WillOnce(InvokeWithoutArgs(cli_connected));
382*6dbdd20aSAndroid Build Coastguard Worker     tx_task_runner.RunUntilCheckpoint("cli_connected");
383*6dbdd20aSAndroid Build Coastguard Worker 
384*6dbdd20aSAndroid Build Coastguard Worker     auto send_done = tx_task_runner.CreateCheckpoint("send_done");
385*6dbdd20aSAndroid Build Coastguard Worker     static constexpr size_t kBufSize = 32 * 1024 * 1024;
386*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<char[]> buf(new char[kBufSize]());
387*6dbdd20aSAndroid Build Coastguard Worker     tx_task_runner.PostTask([&cli, &buf, send_done] {
388*6dbdd20aSAndroid Build Coastguard Worker       cli->Send(buf.get(), kBufSize);
389*6dbdd20aSAndroid Build Coastguard Worker       send_done();
390*6dbdd20aSAndroid Build Coastguard Worker     });
391*6dbdd20aSAndroid Build Coastguard Worker 
392*6dbdd20aSAndroid Build Coastguard Worker     tx_task_runner.RunUntilCheckpoint("send_done", kTimeoutMs);
393*6dbdd20aSAndroid Build Coastguard Worker   });
394*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("receive_done", kTimeoutMs);
395*6dbdd20aSAndroid Build Coastguard Worker   tx_thread.join();
396*6dbdd20aSAndroid Build Coastguard Worker }
397*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ReleaseSocket)398*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ReleaseSocket) {
399*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
400*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
401*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
402*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
403*6dbdd20aSAndroid Build Coastguard Worker   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
404*6dbdd20aSAndroid Build Coastguard Worker   UnixSocket* peer = nullptr;
405*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
406*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(
407*6dbdd20aSAndroid Build Coastguard Worker           Invoke([srv_connected, &peer](UnixSocket*, UnixSocket* new_conn) {
408*6dbdd20aSAndroid Build Coastguard Worker             peer = new_conn;
409*6dbdd20aSAndroid Build Coastguard Worker             srv_connected();
410*6dbdd20aSAndroid Build Coastguard Worker           }));
411*6dbdd20aSAndroid Build Coastguard Worker 
412*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
413*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
414*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
415*6dbdd20aSAndroid Build Coastguard Worker   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
416*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
417*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_connected));
418*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_connected");
419*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_connected");
420*6dbdd20aSAndroid Build Coastguard Worker   srv->Shutdown(true);
421*6dbdd20aSAndroid Build Coastguard Worker 
422*6dbdd20aSAndroid Build Coastguard Worker   cli->SendStr("test");
423*6dbdd20aSAndroid Build Coastguard Worker 
424*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_NE(peer, nullptr);
425*6dbdd20aSAndroid Build Coastguard Worker   auto raw_sock = peer->ReleaseSocket();
426*6dbdd20aSAndroid Build Coastguard Worker 
427*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(_)).Times(0);
428*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilIdle();
429*6dbdd20aSAndroid Build Coastguard Worker 
430*6dbdd20aSAndroid Build Coastguard Worker   char buf[5];
431*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(raw_sock);
432*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(raw_sock.Receive(buf, sizeof(buf)), 4);
433*6dbdd20aSAndroid Build Coastguard Worker   buf[sizeof(buf) - 1] = '\0';
434*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_STREQ(buf, "test");
435*6dbdd20aSAndroid Build Coastguard Worker }
436*6dbdd20aSAndroid Build Coastguard Worker 
437*6dbdd20aSAndroid Build Coastguard Worker // Tests that the return value of GetSockAddr() returns a well formatted address
438*6dbdd20aSAndroid Build Coastguard Worker // that can be passed to UnixSocket::Connect().
TEST_F(UnixSocketTest,GetSockAddrTcp4)439*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, GetSockAddrTcp4) {
440*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen("127.0.0.1:0", &event_listener_, &task_runner_,
441*6dbdd20aSAndroid Build Coastguard Worker                                 SockFamily::kInet, SockType::kStream);
442*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
443*6dbdd20aSAndroid Build Coastguard Worker 
444*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
445*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
446*6dbdd20aSAndroid Build Coastguard Worker                           SockFamily::kInet, SockType::kStream);
447*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
448*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
449*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("connected");
450*6dbdd20aSAndroid Build Coastguard Worker }
451*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,GetSockAddrTcp6)452*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, GetSockAddrTcp6) {
453*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen("[::1]:0", &event_listener_, &task_runner_,
454*6dbdd20aSAndroid Build Coastguard Worker                                 SockFamily::kInet6, SockType::kStream);
455*6dbdd20aSAndroid Build Coastguard Worker   if (!srv)
456*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP() << "This test requires IPv6 support in the OS. Skipping";
457*6dbdd20aSAndroid Build Coastguard Worker 
458*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
459*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
460*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
461*6dbdd20aSAndroid Build Coastguard Worker                           SockFamily::kInet6, SockType::kStream);
462*6dbdd20aSAndroid Build Coastguard Worker 
463*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
464*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
465*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("connected");
466*6dbdd20aSAndroid Build Coastguard Worker }
467*6dbdd20aSAndroid Build Coastguard Worker 
468*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
469*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
470*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_MAC)
TEST_F(UnixSocketTest,GetSockAddrUnixLinked)471*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, GetSockAddrUnixLinked) {
472*6dbdd20aSAndroid Build Coastguard Worker   TempDir tmp_dir = TempDir::Create();
473*6dbdd20aSAndroid Build Coastguard Worker   std::string sock_path = tmp_dir.path() + "/test.sock";
474*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen(sock_path, &event_listener_, &task_runner_,
475*6dbdd20aSAndroid Build Coastguard Worker                                 SockFamily::kUnix, SockType::kStream);
476*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
477*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(sock_path, srv->GetSockAddr());
478*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
479*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
480*6dbdd20aSAndroid Build Coastguard Worker                           SockFamily::kUnix, SockType::kStream);
481*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
482*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
483*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("connected");
484*6dbdd20aSAndroid Build Coastguard Worker   cli.reset();
485*6dbdd20aSAndroid Build Coastguard Worker   srv.reset();
486*6dbdd20aSAndroid Build Coastguard Worker   remove(sock_path.c_str());
487*6dbdd20aSAndroid Build Coastguard Worker }
488*6dbdd20aSAndroid Build Coastguard Worker #endif
489*6dbdd20aSAndroid Build Coastguard Worker 
490*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
491*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
TEST_F(UnixSocketTest,GetSockAddrUnixAbstract)492*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, GetSockAddrUnixAbstract) {
493*6dbdd20aSAndroid Build Coastguard Worker   StackString<128> sock_name("@perfetto_sock_%d_%d", getpid(), rand() % 100000);
494*6dbdd20aSAndroid Build Coastguard Worker 
495*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
496*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(sock_name.ToStdString(), &event_listener_,
497*6dbdd20aSAndroid Build Coastguard Worker                          &task_runner_, SockFamily::kUnix, SockType::kStream);
498*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
499*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(sock_name.ToStdString(), srv->GetSockAddr());
500*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
501*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
502*6dbdd20aSAndroid Build Coastguard Worker                           SockFamily::kUnix, SockType::kStream);
503*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
504*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
505*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("connected");
506*6dbdd20aSAndroid Build Coastguard Worker }
507*6dbdd20aSAndroid Build Coastguard Worker #endif
508*6dbdd20aSAndroid Build Coastguard Worker 
509*6dbdd20aSAndroid Build Coastguard Worker #if (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
510*6dbdd20aSAndroid Build Coastguard Worker      PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
TEST_F(UnixSocketTest,GetSockAddrVsock)511*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, GetSockAddrVsock) {
512*6dbdd20aSAndroid Build Coastguard Worker   SKIP_IF_VSOCK_LOOPBACK_NOT_SUPPORTED();
513*6dbdd20aSAndroid Build Coastguard Worker 
514*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen("vsock://1:-1", &event_listener_, &task_runner_,
515*6dbdd20aSAndroid Build Coastguard Worker                                 SockFamily::kVsock, SockType::kStream);
516*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
517*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
518*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
519*6dbdd20aSAndroid Build Coastguard Worker                           SockFamily::kVsock, SockType::kStream);
520*6dbdd20aSAndroid Build Coastguard Worker 
521*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
522*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
523*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("connected");
524*6dbdd20aSAndroid Build Coastguard Worker }
525*6dbdd20aSAndroid Build Coastguard Worker #endif
526*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,TcpStream)527*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, TcpStream) {
528*6dbdd20aSAndroid Build Coastguard Worker   // Listen on a random port.
529*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<UnixSocket> srv =
530*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen("127.0.0.1:0", &event_listener_, &task_runner_,
531*6dbdd20aSAndroid Build Coastguard Worker                          SockFamily::kInet, SockType::kStream);
532*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
533*6dbdd20aSAndroid Build Coastguard Worker   std::string host_and_port = srv->GetSockAddr();
534*6dbdd20aSAndroid Build Coastguard Worker   constexpr size_t kNumClients = 3;
535*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<UnixSocket> cli[kNumClients];
536*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
537*6dbdd20aSAndroid Build Coastguard Worker       .Times(kNumClients)
538*6dbdd20aSAndroid Build Coastguard Worker       .WillRepeatedly(Invoke([&](UnixSocket*, UnixSocket* s) {
539*6dbdd20aSAndroid Build Coastguard Worker         // OnDisconnect() might spuriously happen depending on the dtor order.
540*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDisconnect(s)).Times(AtLeast(0));
541*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDataAvailable(s))
542*6dbdd20aSAndroid Build Coastguard Worker             .WillRepeatedly(Invoke([](UnixSocket* cli_sock) {
543*6dbdd20aSAndroid Build Coastguard Worker               cli_sock->ReceiveString();  // Read connection EOF;
544*6dbdd20aSAndroid Build Coastguard Worker             }));
545*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_TRUE(s->SendStr("welcome"));
546*6dbdd20aSAndroid Build Coastguard Worker       }));
547*6dbdd20aSAndroid Build Coastguard Worker 
548*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumClients; i++) {
549*6dbdd20aSAndroid Build Coastguard Worker     cli[i] = UnixSocket::Connect(host_and_port, &event_listener_, &task_runner_,
550*6dbdd20aSAndroid Build Coastguard Worker                                  SockFamily::kInet, SockType::kStream);
551*6dbdd20aSAndroid Build Coastguard Worker     auto checkpoint = task_runner_.CreateCheckpoint(std::to_string(i));
552*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnDisconnect(cli[i].get())).Times(AtLeast(0));
553*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true));
554*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnDataAvailable(cli[i].get()))
555*6dbdd20aSAndroid Build Coastguard Worker         .WillRepeatedly(Invoke([checkpoint](UnixSocket* s) {
556*6dbdd20aSAndroid Build Coastguard Worker           auto str = s->ReceiveString();
557*6dbdd20aSAndroid Build Coastguard Worker           if (str == "")
558*6dbdd20aSAndroid Build Coastguard Worker             return;  // Connection EOF.
559*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_EQ("welcome", str);
560*6dbdd20aSAndroid Build Coastguard Worker           checkpoint();
561*6dbdd20aSAndroid Build Coastguard Worker         }));
562*6dbdd20aSAndroid Build Coastguard Worker   }
563*6dbdd20aSAndroid Build Coastguard Worker 
564*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumClients; i++) {
565*6dbdd20aSAndroid Build Coastguard Worker     task_runner_.RunUntilCheckpoint(std::to_string(i));
566*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(Mock::VerifyAndClearExpectations(cli[i].get()));
567*6dbdd20aSAndroid Build Coastguard Worker   }
568*6dbdd20aSAndroid Build Coastguard Worker }
569*6dbdd20aSAndroid Build Coastguard Worker 
570*6dbdd20aSAndroid Build Coastguard Worker // ---------------------------------
571*6dbdd20aSAndroid Build Coastguard Worker // Posix-only tests below this point
572*6dbdd20aSAndroid Build Coastguard Worker // ---------------------------------
573*6dbdd20aSAndroid Build Coastguard Worker 
574*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
575*6dbdd20aSAndroid Build Coastguard Worker 
576*6dbdd20aSAndroid Build Coastguard Worker // Tests the SockPeerCredMode::kIgnore logic.
TEST_F(UnixSocketTest,IgnorePeerCredentials)577*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, IgnorePeerCredentials) {
578*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
579*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
580*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
581*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
582*6dbdd20aSAndroid Build Coastguard Worker   auto cli1_connected = task_runner_.CreateCheckpoint("cli1_connected");
583*6dbdd20aSAndroid Build Coastguard Worker   auto cli1 = UnixSocket::Connect(kTestSocket.name(), &event_listener_,
584*6dbdd20aSAndroid Build Coastguard Worker                                   &task_runner_, kTestSocket.family(),
585*6dbdd20aSAndroid Build Coastguard Worker                                   SockType::kStream, SockPeerCredMode::kIgnore);
586*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli1.get(), true))
587*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli1_connected));
588*6dbdd20aSAndroid Build Coastguard Worker 
589*6dbdd20aSAndroid Build Coastguard Worker   auto cli2_connected = task_runner_.CreateCheckpoint("cli2_connected");
590*6dbdd20aSAndroid Build Coastguard Worker   auto cli2 = UnixSocket::Connect(
591*6dbdd20aSAndroid Build Coastguard Worker       kTestSocket.name(), &event_listener_, &task_runner_, kTestSocket.family(),
592*6dbdd20aSAndroid Build Coastguard Worker       SockType::kStream, SockPeerCredMode::kReadOnConnect);
593*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli2.get(), true))
594*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli2_connected));
595*6dbdd20aSAndroid Build Coastguard Worker 
596*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli1_connected");
597*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli2_connected");
598*6dbdd20aSAndroid Build Coastguard Worker 
599*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(cli1->peer_uid_posix(/*skip_check_for_testing=*/true), kInvalidUid);
600*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(cli2->peer_uid_posix(), geteuid());
601*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
602*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
603*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(cli1->peer_pid_linux(/*skip_check_for_testing=*/true), kInvalidPid);
604*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(cli2->peer_pid_linux(), getpid());
605*6dbdd20aSAndroid Build Coastguard Worker #endif
606*6dbdd20aSAndroid Build Coastguard Worker }
607*6dbdd20aSAndroid Build Coastguard Worker 
608*6dbdd20aSAndroid Build Coastguard Worker // Checks that the peer_uid() is retained after the client disconnects. The IPC
609*6dbdd20aSAndroid Build Coastguard Worker // layer needs to rely on this to validate messages received immediately before
610*6dbdd20aSAndroid Build Coastguard Worker // a client disconnects.
TEST_F(UnixSocketTest,PeerCredentialsRetainedAfterDisconnect)611*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, PeerCredentialsRetainedAfterDisconnect) {
612*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
613*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
614*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
615*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
616*6dbdd20aSAndroid Build Coastguard Worker   UnixSocket* srv_client_conn = nullptr;
617*6dbdd20aSAndroid Build Coastguard Worker   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
618*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
619*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([&srv_client_conn, srv_connected](UnixSocket*,
620*6dbdd20aSAndroid Build Coastguard Worker                                                          UnixSocket* srv_conn) {
621*6dbdd20aSAndroid Build Coastguard Worker         srv_client_conn = srv_conn;
622*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(geteuid(), static_cast<uint32_t>(srv_conn->peer_uid_posix()));
623*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
624*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
625*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(getpid(), static_cast<pid_t>(srv_conn->peer_pid_linux()));
626*6dbdd20aSAndroid Build Coastguard Worker #endif
627*6dbdd20aSAndroid Build Coastguard Worker         srv_connected();
628*6dbdd20aSAndroid Build Coastguard Worker       }));
629*6dbdd20aSAndroid Build Coastguard Worker   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
630*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
631*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
632*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
633*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
634*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_connected));
635*6dbdd20aSAndroid Build Coastguard Worker 
636*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_connected");
637*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_connected");
638*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_NE(nullptr, srv_client_conn);
639*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv_client_conn->is_connected());
640*6dbdd20aSAndroid Build Coastguard Worker 
641*6dbdd20aSAndroid Build Coastguard Worker   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
642*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDisconnect(srv_client_conn))
643*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_disconnected));
644*6dbdd20aSAndroid Build Coastguard Worker 
645*6dbdd20aSAndroid Build Coastguard Worker   // TODO(primiano): when the a peer disconnects, the other end receives a
646*6dbdd20aSAndroid Build Coastguard Worker   // spurious OnDataAvailable() that needs to be acked with a Receive() to read
647*6dbdd20aSAndroid Build Coastguard Worker   // the EOF. See b/69536434.
648*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(srv_client_conn))
649*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([](UnixSocket* sock) { sock->ReceiveString(); }));
650*6dbdd20aSAndroid Build Coastguard Worker 
651*6dbdd20aSAndroid Build Coastguard Worker   cli.reset();
652*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_disconnected");
653*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_FALSE(srv_client_conn->is_connected());
654*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(geteuid(),
655*6dbdd20aSAndroid Build Coastguard Worker             static_cast<uint32_t>(srv_client_conn->peer_uid_posix()));
656*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
657*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
658*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(getpid(), static_cast<pid_t>(srv_client_conn->peer_pid_linux()));
659*6dbdd20aSAndroid Build Coastguard Worker #endif
660*6dbdd20aSAndroid Build Coastguard Worker }
661*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ClientAndServerExchangeFDs)662*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ClientAndServerExchangeFDs) {
663*6dbdd20aSAndroid Build Coastguard Worker   static constexpr char cli_str[] = "cli>srv";
664*6dbdd20aSAndroid Build Coastguard Worker   static constexpr char srv_str[] = "srv>cli";
665*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
666*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
667*6dbdd20aSAndroid Build Coastguard Worker                          kTestSocket.family(), SockType::kStream);
668*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv->is_listening());
669*6dbdd20aSAndroid Build Coastguard Worker 
670*6dbdd20aSAndroid Build Coastguard Worker   auto cli =
671*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
672*6dbdd20aSAndroid Build Coastguard Worker                           kTestSocket.family(), SockType::kStream);
673*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
674*6dbdd20aSAndroid Build Coastguard Worker   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
675*6dbdd20aSAndroid Build Coastguard Worker   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
676*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
677*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([this, cli_connected, srv_disconnected](
678*6dbdd20aSAndroid Build Coastguard Worker                            UnixSocket*, UnixSocket* srv_conn) {
679*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDisconnect(srv_conn))
680*6dbdd20aSAndroid Build Coastguard Worker             .WillOnce(InvokeWithoutArgs(srv_disconnected));
681*6dbdd20aSAndroid Build Coastguard Worker         cli_connected();
682*6dbdd20aSAndroid Build Coastguard Worker       }));
683*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_connected");
684*6dbdd20aSAndroid Build Coastguard Worker 
685*6dbdd20aSAndroid Build Coastguard Worker   auto srv_conn = event_listener_.GetIncomingConnection();
686*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv_conn);
687*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(cli->is_connected());
688*6dbdd20aSAndroid Build Coastguard Worker 
689*6dbdd20aSAndroid Build Coastguard Worker   ScopedFile null_fd(base::OpenFile("/dev/null", O_RDONLY));
690*6dbdd20aSAndroid Build Coastguard Worker   ScopedFile zero_fd(base::OpenFile("/dev/zero", O_RDONLY));
691*6dbdd20aSAndroid Build Coastguard Worker 
692*6dbdd20aSAndroid Build Coastguard Worker   auto cli_did_recv = task_runner_.CreateCheckpoint("cli_did_recv");
693*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
694*6dbdd20aSAndroid Build Coastguard Worker       .WillRepeatedly(Invoke([cli_did_recv](UnixSocket* s) {
695*6dbdd20aSAndroid Build Coastguard Worker         ScopedFile fd_buf[3];
696*6dbdd20aSAndroid Build Coastguard Worker         char buf[sizeof(cli_str)];
697*6dbdd20aSAndroid Build Coastguard Worker         if (!s->Receive(buf, sizeof(buf), fd_buf, ArraySize(fd_buf)))
698*6dbdd20aSAndroid Build Coastguard Worker           return;
699*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_STREQ(srv_str, buf);
700*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_NE(*fd_buf[0], -1);
701*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_NE(*fd_buf[1], -1);
702*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(*fd_buf[2], -1);
703*6dbdd20aSAndroid Build Coastguard Worker 
704*6dbdd20aSAndroid Build Coastguard Worker         char rd_buf[1];
705*6dbdd20aSAndroid Build Coastguard Worker         // /dev/null
706*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(read(*fd_buf[0], rd_buf, sizeof(rd_buf)), 0);
707*6dbdd20aSAndroid Build Coastguard Worker         // /dev/zero
708*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(read(*fd_buf[1], rd_buf, sizeof(rd_buf)), 1);
709*6dbdd20aSAndroid Build Coastguard Worker         cli_did_recv();
710*6dbdd20aSAndroid Build Coastguard Worker       }));
711*6dbdd20aSAndroid Build Coastguard Worker 
712*6dbdd20aSAndroid Build Coastguard Worker   auto srv_did_recv = task_runner_.CreateCheckpoint("srv_did_recv");
713*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn.get()))
714*6dbdd20aSAndroid Build Coastguard Worker       .WillRepeatedly(Invoke([srv_did_recv](UnixSocket* s) {
715*6dbdd20aSAndroid Build Coastguard Worker         ScopedFile fd_buf[3];
716*6dbdd20aSAndroid Build Coastguard Worker         char buf[sizeof(srv_str)];
717*6dbdd20aSAndroid Build Coastguard Worker         if (!s->Receive(buf, sizeof(buf), fd_buf, ArraySize(fd_buf)))
718*6dbdd20aSAndroid Build Coastguard Worker           return;
719*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_STREQ(cli_str, buf);
720*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_NE(*fd_buf[0], -1);
721*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_NE(*fd_buf[1], -1);
722*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(*fd_buf[2], -1);
723*6dbdd20aSAndroid Build Coastguard Worker 
724*6dbdd20aSAndroid Build Coastguard Worker         char rd_buf[1];
725*6dbdd20aSAndroid Build Coastguard Worker         // /dev/null
726*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(read(*fd_buf[0], rd_buf, sizeof(rd_buf)), 0);
727*6dbdd20aSAndroid Build Coastguard Worker         // /dev/zero
728*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(read(*fd_buf[1], rd_buf, sizeof(rd_buf)), 1);
729*6dbdd20aSAndroid Build Coastguard Worker         srv_did_recv();
730*6dbdd20aSAndroid Build Coastguard Worker       }));
731*6dbdd20aSAndroid Build Coastguard Worker 
732*6dbdd20aSAndroid Build Coastguard Worker   int buf_fd[2] = {null_fd.get(), zero_fd.get()};
733*6dbdd20aSAndroid Build Coastguard Worker 
734*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(
735*6dbdd20aSAndroid Build Coastguard Worker       cli->Send(cli_str, sizeof(cli_str), buf_fd, base::ArraySize(buf_fd)));
736*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv_conn->Send(srv_str, sizeof(srv_str), buf_fd,
737*6dbdd20aSAndroid Build Coastguard Worker                              base::ArraySize(buf_fd)));
738*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_did_recv");
739*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_did_recv");
740*6dbdd20aSAndroid Build Coastguard Worker 
741*6dbdd20aSAndroid Build Coastguard Worker   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
742*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDisconnect(cli.get()))
743*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(InvokeWithoutArgs(cli_disconnected));
744*6dbdd20aSAndroid Build Coastguard Worker   cli->Shutdown(true);
745*6dbdd20aSAndroid Build Coastguard Worker   srv->Shutdown(true);
746*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("srv_disconnected");
747*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("cli_disconnected");
748*6dbdd20aSAndroid Build Coastguard Worker }
749*6dbdd20aSAndroid Build Coastguard Worker 
750*6dbdd20aSAndroid Build Coastguard Worker // Creates two processes. The server process creates a file and passes it over
751*6dbdd20aSAndroid Build Coastguard Worker // the socket to the client. Both processes mmap the file in shared mode and
752*6dbdd20aSAndroid Build Coastguard Worker // check that they see the same contents.
TEST_F(UnixSocketTest,SharedMemory)753*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, SharedMemory) {
754*6dbdd20aSAndroid Build Coastguard Worker   Pipe pipe = Pipe::Create();
755*6dbdd20aSAndroid Build Coastguard Worker   pid_t pid = fork();
756*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(pid, 0);
757*6dbdd20aSAndroid Build Coastguard Worker   constexpr size_t kTmpSize = 4096;
758*6dbdd20aSAndroid Build Coastguard Worker 
759*6dbdd20aSAndroid Build Coastguard Worker   if (pid == 0) {
760*6dbdd20aSAndroid Build Coastguard Worker     // Child process.
761*6dbdd20aSAndroid Build Coastguard Worker     TempFile scoped_tmp = TempFile::CreateUnlinked();
762*6dbdd20aSAndroid Build Coastguard Worker     int tmp_fd = scoped_tmp.fd();
763*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_FALSE(ftruncate(tmp_fd, kTmpSize));
764*6dbdd20aSAndroid Build Coastguard Worker     char* mem = reinterpret_cast<char*>(
765*6dbdd20aSAndroid Build Coastguard Worker         mmap(nullptr, kTmpSize, PROT_READ | PROT_WRITE, MAP_SHARED, tmp_fd, 0));
766*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, mem);
767*6dbdd20aSAndroid Build Coastguard Worker     memcpy(mem, "shm rocks", 10);
768*6dbdd20aSAndroid Build Coastguard Worker 
769*6dbdd20aSAndroid Build Coastguard Worker     auto srv =
770*6dbdd20aSAndroid Build Coastguard Worker         UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
771*6dbdd20aSAndroid Build Coastguard Worker                            kTestSocket.family(), SockType::kStream);
772*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(srv->is_listening());
773*6dbdd20aSAndroid Build Coastguard Worker     // Signal the other process that it can connect.
774*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(1, base::WriteAll(*pipe.wr, ".", 1));
775*6dbdd20aSAndroid Build Coastguard Worker     auto checkpoint = task_runner_.CreateCheckpoint("change_seen_by_server");
776*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
777*6dbdd20aSAndroid Build Coastguard Worker         .WillOnce(Invoke(
778*6dbdd20aSAndroid Build Coastguard Worker             [this, tmp_fd, checkpoint, mem](UnixSocket*, UnixSocket* new_conn) {
779*6dbdd20aSAndroid Build Coastguard Worker               ASSERT_EQ(geteuid(),
780*6dbdd20aSAndroid Build Coastguard Worker                         static_cast<uint32_t>(new_conn->peer_uid_posix()));
781*6dbdd20aSAndroid Build Coastguard Worker               ASSERT_TRUE(new_conn->Send("txfd", 5, tmp_fd));
782*6dbdd20aSAndroid Build Coastguard Worker               // Wait for the client to change this again.
783*6dbdd20aSAndroid Build Coastguard Worker               EXPECT_CALL(event_listener_, OnDataAvailable(new_conn))
784*6dbdd20aSAndroid Build Coastguard Worker                   .WillOnce(Invoke([checkpoint, mem](UnixSocket* s) {
785*6dbdd20aSAndroid Build Coastguard Worker                     ASSERT_EQ("change notify", s->ReceiveString());
786*6dbdd20aSAndroid Build Coastguard Worker                     ASSERT_STREQ("rock more", mem);
787*6dbdd20aSAndroid Build Coastguard Worker                     checkpoint();
788*6dbdd20aSAndroid Build Coastguard Worker                   }));
789*6dbdd20aSAndroid Build Coastguard Worker             }));
790*6dbdd20aSAndroid Build Coastguard Worker     task_runner_.RunUntilCheckpoint("change_seen_by_server");
791*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(Mock::VerifyAndClearExpectations(&event_listener_));
792*6dbdd20aSAndroid Build Coastguard Worker     _exit(0);
793*6dbdd20aSAndroid Build Coastguard Worker   } else {
794*6dbdd20aSAndroid Build Coastguard Worker     char sync_cmd = '\0';
795*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(1, PERFETTO_EINTR(read(*pipe.rd, &sync_cmd, 1)));
796*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ('.', sync_cmd);
797*6dbdd20aSAndroid Build Coastguard Worker     auto cli =
798*6dbdd20aSAndroid Build Coastguard Worker         UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
799*6dbdd20aSAndroid Build Coastguard Worker                             kTestSocket.family(), SockType::kStream);
800*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
801*6dbdd20aSAndroid Build Coastguard Worker     auto checkpoint = task_runner_.CreateCheckpoint("change_seen_by_client");
802*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
803*6dbdd20aSAndroid Build Coastguard Worker         .WillOnce(Invoke([checkpoint](UnixSocket* s) {
804*6dbdd20aSAndroid Build Coastguard Worker           char msg[32];
805*6dbdd20aSAndroid Build Coastguard Worker           ScopedFile fd;
806*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_EQ(5u, s->Receive(msg, sizeof(msg), &fd));
807*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_STREQ("txfd", msg);
808*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_TRUE(fd);
809*6dbdd20aSAndroid Build Coastguard Worker           char* mem = reinterpret_cast<char*>(mmap(
810*6dbdd20aSAndroid Build Coastguard Worker               nullptr, kTmpSize, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0));
811*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_NE(nullptr, mem);
812*6dbdd20aSAndroid Build Coastguard Worker           mem[9] = '\0';  // Just to get a clean error in case of test failure.
813*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_STREQ("shm rocks", mem);
814*6dbdd20aSAndroid Build Coastguard Worker 
815*6dbdd20aSAndroid Build Coastguard Worker           // Now change the shared memory and ping the other process.
816*6dbdd20aSAndroid Build Coastguard Worker           memcpy(mem, "rock more", 10);
817*6dbdd20aSAndroid Build Coastguard Worker           ASSERT_TRUE(s->SendStr("change notify"));
818*6dbdd20aSAndroid Build Coastguard Worker           checkpoint();
819*6dbdd20aSAndroid Build Coastguard Worker         }));
820*6dbdd20aSAndroid Build Coastguard Worker     task_runner_.RunUntilCheckpoint("change_seen_by_client");
821*6dbdd20aSAndroid Build Coastguard Worker     int st = 0;
822*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_EINTR(waitpid(pid, &st, 0));
823*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_FALSE(WIFSIGNALED(st)) << "Server died with signal " << WTERMSIG(st);
824*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(WIFEXITED(st));
825*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(0, WEXITSTATUS(st));
826*6dbdd20aSAndroid Build Coastguard Worker   }
827*6dbdd20aSAndroid Build Coastguard Worker }
828*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ShiftMsgHdrSendPartialFirst)829*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ShiftMsgHdrSendPartialFirst) {
830*6dbdd20aSAndroid Build Coastguard Worker   // Send a part of the first iov, then send the rest.
831*6dbdd20aSAndroid Build Coastguard Worker   struct iovec iov[2] = {};
832*6dbdd20aSAndroid Build Coastguard Worker   char hello[] = "hello";
833*6dbdd20aSAndroid Build Coastguard Worker   char world[] = "world";
834*6dbdd20aSAndroid Build Coastguard Worker   iov[0].iov_base = &hello[0];
835*6dbdd20aSAndroid Build Coastguard Worker   iov[0].iov_len = base::ArraySize(hello);
836*6dbdd20aSAndroid Build Coastguard Worker 
837*6dbdd20aSAndroid Build Coastguard Worker   iov[1].iov_base = &world[0];
838*6dbdd20aSAndroid Build Coastguard Worker   iov[1].iov_len = base::ArraySize(world);
839*6dbdd20aSAndroid Build Coastguard Worker 
840*6dbdd20aSAndroid Build Coastguard Worker   struct msghdr hdr = {};
841*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iov = iov;
842*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iovlen = base::ArraySize(iov);
843*6dbdd20aSAndroid Build Coastguard Worker 
844*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw::ShiftMsgHdrPosix(1, &hdr);
845*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(hdr.msg_iov, nullptr);
846*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov[0].iov_base, &hello[1]);
847*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov[1].iov_base, &world[0]);
848*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 2);
849*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_STREQ(reinterpret_cast<char*>(hdr.msg_iov[0].iov_base), "ello");
850*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(iov[0].iov_len, base::ArraySize(hello) - 1);
851*6dbdd20aSAndroid Build Coastguard Worker 
852*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(hello) - 1, &hdr);
853*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov, &iov[1]);
854*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 1);
855*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_STREQ(reinterpret_cast<char*>(hdr.msg_iov[0].iov_base), world);
856*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov[0].iov_len, base::ArraySize(world));
857*6dbdd20aSAndroid Build Coastguard Worker 
858*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(world), &hdr);
859*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov, nullptr);
860*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 0);
861*6dbdd20aSAndroid Build Coastguard Worker }
862*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ShiftMsgHdrSendFirstAndPartial)863*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ShiftMsgHdrSendFirstAndPartial) {
864*6dbdd20aSAndroid Build Coastguard Worker   // Send first iov and part of the second iov, then send the rest.
865*6dbdd20aSAndroid Build Coastguard Worker   struct iovec iov[2] = {};
866*6dbdd20aSAndroid Build Coastguard Worker   char hello[] = "hello";
867*6dbdd20aSAndroid Build Coastguard Worker   char world[] = "world";
868*6dbdd20aSAndroid Build Coastguard Worker   iov[0].iov_base = &hello[0];
869*6dbdd20aSAndroid Build Coastguard Worker   iov[0].iov_len = base::ArraySize(hello);
870*6dbdd20aSAndroid Build Coastguard Worker 
871*6dbdd20aSAndroid Build Coastguard Worker   iov[1].iov_base = &world[0];
872*6dbdd20aSAndroid Build Coastguard Worker   iov[1].iov_len = base::ArraySize(world);
873*6dbdd20aSAndroid Build Coastguard Worker 
874*6dbdd20aSAndroid Build Coastguard Worker   struct msghdr hdr = {};
875*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iov = iov;
876*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iovlen = base::ArraySize(iov);
877*6dbdd20aSAndroid Build Coastguard Worker 
878*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(hello) + 1, &hdr);
879*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(hdr.msg_iov, nullptr);
880*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 1);
881*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_STREQ(reinterpret_cast<char*>(hdr.msg_iov[0].iov_base), "orld");
882*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov[0].iov_len, base::ArraySize(world) - 1);
883*6dbdd20aSAndroid Build Coastguard Worker 
884*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(world) - 1, &hdr);
885*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov, nullptr);
886*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 0);
887*6dbdd20aSAndroid Build Coastguard Worker }
888*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ShiftMsgHdrSendEverything)889*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ShiftMsgHdrSendEverything) {
890*6dbdd20aSAndroid Build Coastguard Worker   // Send everything at once.
891*6dbdd20aSAndroid Build Coastguard Worker   struct iovec iov[2] = {};
892*6dbdd20aSAndroid Build Coastguard Worker   char hello[] = "hello";
893*6dbdd20aSAndroid Build Coastguard Worker   char world[] = "world";
894*6dbdd20aSAndroid Build Coastguard Worker   iov[0].iov_base = &hello[0];
895*6dbdd20aSAndroid Build Coastguard Worker   iov[0].iov_len = base::ArraySize(hello);
896*6dbdd20aSAndroid Build Coastguard Worker 
897*6dbdd20aSAndroid Build Coastguard Worker   iov[1].iov_base = &world[0];
898*6dbdd20aSAndroid Build Coastguard Worker   iov[1].iov_len = base::ArraySize(world);
899*6dbdd20aSAndroid Build Coastguard Worker 
900*6dbdd20aSAndroid Build Coastguard Worker   struct msghdr hdr = {};
901*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iov = iov;
902*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iovlen = base::ArraySize(iov);
903*6dbdd20aSAndroid Build Coastguard Worker 
904*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw::ShiftMsgHdrPosix(
905*6dbdd20aSAndroid Build Coastguard Worker       base::ArraySize(world) + base::ArraySize(hello), &hdr);
906*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(hdr.msg_iov, nullptr);
907*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 0);
908*6dbdd20aSAndroid Build Coastguard Worker }
909*6dbdd20aSAndroid Build Coastguard Worker 
910*6dbdd20aSAndroid Build Coastguard Worker // For use in PartialSendMsgAll template argument. Cannot be a lambda.
RollbackSigaction(const struct sigaction * act)911*6dbdd20aSAndroid Build Coastguard Worker int RollbackSigaction(const struct sigaction* act) {
912*6dbdd20aSAndroid Build Coastguard Worker   return sigaction(SIGWINCH, act, nullptr);
913*6dbdd20aSAndroid Build Coastguard Worker }
914*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,PartialSendMsgAll)915*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, PartialSendMsgAll) {
916*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw send_sock;
917*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw recv_sock;
918*6dbdd20aSAndroid Build Coastguard Worker   std::tie(send_sock, recv_sock) =
919*6dbdd20aSAndroid Build Coastguard Worker       UnixSocketRaw::CreatePairPosix(kTestSocket.family(), SockType::kStream);
920*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(send_sock);
921*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(recv_sock);
922*6dbdd20aSAndroid Build Coastguard Worker 
923*6dbdd20aSAndroid Build Coastguard Worker   // Set bufsize to minimum.
924*6dbdd20aSAndroid Build Coastguard Worker   int bufsize = 1024;
925*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(setsockopt(send_sock.fd(), SOL_SOCKET, SO_SNDBUF, &bufsize,
926*6dbdd20aSAndroid Build Coastguard Worker                        sizeof(bufsize)),
927*6dbdd20aSAndroid Build Coastguard Worker             0);
928*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(setsockopt(recv_sock.fd(), SOL_SOCKET, SO_RCVBUF, &bufsize,
929*6dbdd20aSAndroid Build Coastguard Worker                        sizeof(bufsize)),
930*6dbdd20aSAndroid Build Coastguard Worker             0);
931*6dbdd20aSAndroid Build Coastguard Worker 
932*6dbdd20aSAndroid Build Coastguard Worker   // Send something larger than send + recv kernel buffers combined to make
933*6dbdd20aSAndroid Build Coastguard Worker   // sendmsg block.
934*6dbdd20aSAndroid Build Coastguard Worker   std::string send_buf(8192, '\0');
935*6dbdd20aSAndroid Build Coastguard Worker   // Make MSAN happy.
936*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < send_buf.size(); ++i)
937*6dbdd20aSAndroid Build Coastguard Worker     send_buf[i] = static_cast<char>(i % 256);
938*6dbdd20aSAndroid Build Coastguard Worker   std::string recv_buf(send_buf.size(), '\0');
939*6dbdd20aSAndroid Build Coastguard Worker 
940*6dbdd20aSAndroid Build Coastguard Worker   // Need to install signal handler to cause the interrupt to happen.
941*6dbdd20aSAndroid Build Coastguard Worker   // man 3 pthread_kill:
942*6dbdd20aSAndroid Build Coastguard Worker   //   Signal dispositions are process-wide: if a signal handler is
943*6dbdd20aSAndroid Build Coastguard Worker   //   installed, the handler will be invoked in the thread thread, but if
944*6dbdd20aSAndroid Build Coastguard Worker   //   the disposition of the signal is "stop", "continue", or "terminate",
945*6dbdd20aSAndroid Build Coastguard Worker   //   this action will affect the whole process.
946*6dbdd20aSAndroid Build Coastguard Worker   struct sigaction oldact;
947*6dbdd20aSAndroid Build Coastguard Worker   struct sigaction newact = {};
948*6dbdd20aSAndroid Build Coastguard Worker   newact.sa_handler = [](int) {};
949*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(sigaction(SIGWINCH, &newact, &oldact), 0);
950*6dbdd20aSAndroid Build Coastguard Worker   base::ScopedResource<const struct sigaction*, RollbackSigaction, nullptr>
951*6dbdd20aSAndroid Build Coastguard Worker       rollback(&oldact);
952*6dbdd20aSAndroid Build Coastguard Worker 
953*6dbdd20aSAndroid Build Coastguard Worker   auto blocked_thread = pthread_self();
954*6dbdd20aSAndroid Build Coastguard Worker   std::thread th([blocked_thread, &recv_sock, &recv_buf] {
955*6dbdd20aSAndroid Build Coastguard Worker     ssize_t rd = PERFETTO_EINTR(read(recv_sock.fd(), &recv_buf[0], 1));
956*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(rd, 1);
957*6dbdd20aSAndroid Build Coastguard Worker     // We are now sure the other thread is in sendmsg, interrupt send.
958*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(pthread_kill(blocked_thread, SIGWINCH), 0);
959*6dbdd20aSAndroid Build Coastguard Worker     // Drain the socket to allow SendMsgAllPosix to succeed.
960*6dbdd20aSAndroid Build Coastguard Worker     size_t offset = 1;
961*6dbdd20aSAndroid Build Coastguard Worker     while (offset < recv_buf.size()) {
962*6dbdd20aSAndroid Build Coastguard Worker       rd = PERFETTO_EINTR(
963*6dbdd20aSAndroid Build Coastguard Worker           read(recv_sock.fd(), &recv_buf[offset], recv_buf.size() - offset));
964*6dbdd20aSAndroid Build Coastguard Worker       ASSERT_GE(rd, 0);
965*6dbdd20aSAndroid Build Coastguard Worker       offset += static_cast<size_t>(rd);
966*6dbdd20aSAndroid Build Coastguard Worker     }
967*6dbdd20aSAndroid Build Coastguard Worker   });
968*6dbdd20aSAndroid Build Coastguard Worker 
969*6dbdd20aSAndroid Build Coastguard Worker   // Test sending the send_buf in several chunks as an iov to exercise the
970*6dbdd20aSAndroid Build Coastguard Worker   // more complicated code-paths of SendMsgAllPosix.
971*6dbdd20aSAndroid Build Coastguard Worker   struct msghdr hdr = {};
972*6dbdd20aSAndroid Build Coastguard Worker   struct iovec iov[4];
973*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(send_buf.size() % base::ArraySize(iov), 0u)
974*6dbdd20aSAndroid Build Coastguard Worker       << "Cannot split buffer into even pieces.";
975*6dbdd20aSAndroid Build Coastguard Worker   const size_t kChunkSize = send_buf.size() / base::ArraySize(iov);
976*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < base::ArraySize(iov); ++i) {
977*6dbdd20aSAndroid Build Coastguard Worker     iov[i].iov_base = &send_buf[i * kChunkSize];
978*6dbdd20aSAndroid Build Coastguard Worker     iov[i].iov_len = kChunkSize;
979*6dbdd20aSAndroid Build Coastguard Worker   }
980*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iov = iov;
981*6dbdd20aSAndroid Build Coastguard Worker   hdr.msg_iovlen = base::ArraySize(iov);
982*6dbdd20aSAndroid Build Coastguard Worker 
983*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(send_sock.SendMsgAllPosix(&hdr),
984*6dbdd20aSAndroid Build Coastguard Worker             static_cast<ssize_t>(send_buf.size()));
985*6dbdd20aSAndroid Build Coastguard Worker   send_sock.Shutdown();
986*6dbdd20aSAndroid Build Coastguard Worker   th.join();
987*6dbdd20aSAndroid Build Coastguard Worker   // Make sure the re-entry logic was actually triggered.
988*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(hdr.msg_iov, nullptr);
989*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(memcmp(&send_buf[0], &recv_buf[0], send_buf.size()), 0);
990*6dbdd20aSAndroid Build Coastguard Worker }
991*6dbdd20aSAndroid Build Coastguard Worker 
992*6dbdd20aSAndroid Build Coastguard Worker // Regression test for b/193234818. SO_SNDTIMEO is unreliable on most systems.
993*6dbdd20aSAndroid Build Coastguard Worker // It doesn't guarantee that the whole send() call blocks for at most X, as the
994*6dbdd20aSAndroid Build Coastguard Worker // kernel rearms the timeout if the send buffers frees up and allows a partial
995*6dbdd20aSAndroid Build Coastguard Worker // send. This test reproduces the issue 100% on Mac. Unfortunately on Linux the
996*6dbdd20aSAndroid Build Coastguard Worker // repro seem to happen only when a suspend happens in the middle.
TEST_F(UnixSocketTest,BlockingSendTimeout)997*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, BlockingSendTimeout) {
998*6dbdd20aSAndroid Build Coastguard Worker   TestTaskRunner ttr;
999*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw send_sock;
1000*6dbdd20aSAndroid Build Coastguard Worker   UnixSocketRaw recv_sock;
1001*6dbdd20aSAndroid Build Coastguard Worker   std::tie(send_sock, recv_sock) =
1002*6dbdd20aSAndroid Build Coastguard Worker       UnixSocketRaw::CreatePairPosix(kTestSocket.family(), SockType::kStream);
1003*6dbdd20aSAndroid Build Coastguard Worker 
1004*6dbdd20aSAndroid Build Coastguard Worker   auto blocking_send_done = ttr.CreateCheckpoint("blocking_send_done");
1005*6dbdd20aSAndroid Build Coastguard Worker 
1006*6dbdd20aSAndroid Build Coastguard Worker   std::thread tx_thread([&] {
1007*6dbdd20aSAndroid Build Coastguard Worker     // Fill the tx buffer in non-blocking mode.
1008*6dbdd20aSAndroid Build Coastguard Worker     send_sock.SetBlocking(false);
1009*6dbdd20aSAndroid Build Coastguard Worker     char buf[1024 * 16]{};
1010*6dbdd20aSAndroid Build Coastguard Worker     while (send_sock.Send(buf, sizeof(buf)) > 0) {
1011*6dbdd20aSAndroid Build Coastguard Worker     }
1012*6dbdd20aSAndroid Build Coastguard Worker 
1013*6dbdd20aSAndroid Build Coastguard Worker     // Then do a blocking send. It should return a partial value within the tx
1014*6dbdd20aSAndroid Build Coastguard Worker     // timeout.
1015*6dbdd20aSAndroid Build Coastguard Worker     send_sock.SetBlocking(true);
1016*6dbdd20aSAndroid Build Coastguard Worker     send_sock.SetTxTimeout(10);
1017*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_LT(send_sock.Send(buf, sizeof(buf)),
1018*6dbdd20aSAndroid Build Coastguard Worker               static_cast<ssize_t>(sizeof(buf)));
1019*6dbdd20aSAndroid Build Coastguard Worker     ttr.PostTask(blocking_send_done);
1020*6dbdd20aSAndroid Build Coastguard Worker   });
1021*6dbdd20aSAndroid Build Coastguard Worker 
1022*6dbdd20aSAndroid Build Coastguard Worker   // This task needs to be slow enough so that doesn't unblock the send, but
1023*6dbdd20aSAndroid Build Coastguard Worker   // fast enough so that within a blocking cycle, the send re-attempts and
1024*6dbdd20aSAndroid Build Coastguard Worker   // re-arms the timeout.
1025*6dbdd20aSAndroid Build Coastguard Worker   PeriodicTask read_slowly_task(&ttr);
1026*6dbdd20aSAndroid Build Coastguard Worker   PeriodicTask::Args args;
1027*6dbdd20aSAndroid Build Coastguard Worker   args.period_ms = 1;  // Read 1 byte every ms (1 KiB/s).
1028*6dbdd20aSAndroid Build Coastguard Worker   args.task = [&] {
1029*6dbdd20aSAndroid Build Coastguard Worker     char rxbuf[1]{};
1030*6dbdd20aSAndroid Build Coastguard Worker     recv_sock.Receive(rxbuf, sizeof(rxbuf));
1031*6dbdd20aSAndroid Build Coastguard Worker   };
1032*6dbdd20aSAndroid Build Coastguard Worker   read_slowly_task.Start(args);
1033*6dbdd20aSAndroid Build Coastguard Worker 
1034*6dbdd20aSAndroid Build Coastguard Worker   ttr.RunUntilCheckpoint("blocking_send_done");
1035*6dbdd20aSAndroid Build Coastguard Worker   read_slowly_task.Reset();
1036*6dbdd20aSAndroid Build Coastguard Worker   tx_thread.join();
1037*6dbdd20aSAndroid Build Coastguard Worker }
1038*6dbdd20aSAndroid Build Coastguard Worker 
1039*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
TEST_F(UnixSocketTest,SetsCloexec)1040*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, SetsCloexec) {
1041*6dbdd20aSAndroid Build Coastguard Worker   // CLOEXEC set when constructing sockets through helper:
1042*6dbdd20aSAndroid Build Coastguard Worker   {
1043*6dbdd20aSAndroid Build Coastguard Worker     auto raw = UnixSocketRaw::CreateMayFail(base::SockFamily::kUnix,
1044*6dbdd20aSAndroid Build Coastguard Worker                                             SockType::kStream);
1045*6dbdd20aSAndroid Build Coastguard Worker     int flags = fcntl(raw.fd(), F_GETFD, 0);
1046*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(flags & FD_CLOEXEC);
1047*6dbdd20aSAndroid Build Coastguard Worker   }
1048*6dbdd20aSAndroid Build Coastguard Worker   // CLOEXEC set when creating a UnixSocketRaw out of an existing fd:
1049*6dbdd20aSAndroid Build Coastguard Worker   {
1050*6dbdd20aSAndroid Build Coastguard Worker     int fd = socket(AF_UNIX, SOCK_STREAM, 0);
1051*6dbdd20aSAndroid Build Coastguard Worker     int flags = fcntl(fd, F_GETFD, 0);
1052*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(flags & FD_CLOEXEC);
1053*6dbdd20aSAndroid Build Coastguard Worker 
1054*6dbdd20aSAndroid Build Coastguard Worker     auto raw = UnixSocketRaw(ScopedSocketHandle(fd), base::SockFamily::kUnix,
1055*6dbdd20aSAndroid Build Coastguard Worker                              SockType::kStream);
1056*6dbdd20aSAndroid Build Coastguard Worker     flags = fcntl(raw.fd(), F_GETFD, 0);
1057*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(flags & FD_CLOEXEC);
1058*6dbdd20aSAndroid Build Coastguard Worker   }
1059*6dbdd20aSAndroid Build Coastguard Worker }
1060*6dbdd20aSAndroid Build Coastguard Worker #endif  // !OS_FUCHSIA
1061*6dbdd20aSAndroid Build Coastguard Worker 
1062*6dbdd20aSAndroid Build Coastguard Worker #endif  // !OS_WIN
1063*6dbdd20aSAndroid Build Coastguard Worker 
1064*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
1065*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
1066*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_MAC)
1067*6dbdd20aSAndroid Build Coastguard Worker 
1068*6dbdd20aSAndroid Build Coastguard Worker // Regression test for b/239725760.
TEST_F(UnixSocketTest,Sockaddr_FilesystemLinked)1069*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, Sockaddr_FilesystemLinked) {
1070*6dbdd20aSAndroid Build Coastguard Worker   TempDir tmp_dir = TempDir::Create();
1071*6dbdd20aSAndroid Build Coastguard Worker   std::string sock_path = tmp_dir.path() + "/test.sock";
1072*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen(sock_path, &event_listener_, &task_runner_,
1073*6dbdd20aSAndroid Build Coastguard Worker                                 SockFamily::kUnix, SockType::kStream);
1074*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv && srv->is_listening());
1075*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(FileExists(sock_path));
1076*6dbdd20aSAndroid Build Coastguard Worker 
1077*6dbdd20aSAndroid Build Coastguard Worker   // Create a raw socket and manually connect to that (to avoid getting affected
1078*6dbdd20aSAndroid Build Coastguard Worker   // by accidental future bugs in the logic that populates struct sockaddr_un).
1079*6dbdd20aSAndroid Build Coastguard Worker   auto cli = UnixSocketRaw::CreateMayFail(SockFamily::kUnix, SockType::kStream);
1080*6dbdd20aSAndroid Build Coastguard Worker   struct sockaddr_un addr {};
1081*6dbdd20aSAndroid Build Coastguard Worker   addr.sun_family = AF_UNIX;
1082*6dbdd20aSAndroid Build Coastguard Worker   StringCopy(addr.sun_path, sock_path.c_str(), sizeof(addr.sun_path));
1083*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(0, connect(cli.fd(), reinterpret_cast<struct sockaddr*>(&addr),
1084*6dbdd20aSAndroid Build Coastguard Worker                        sizeof(addr)));
1085*6dbdd20aSAndroid Build Coastguard Worker   cli.Shutdown();
1086*6dbdd20aSAndroid Build Coastguard Worker   remove(sock_path.c_str());
1087*6dbdd20aSAndroid Build Coastguard Worker }
1088*6dbdd20aSAndroid Build Coastguard Worker #endif  // OS_LINUX || OS_ANDROID || OS_MAC
1089*6dbdd20aSAndroid Build Coastguard Worker 
1090*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
1091*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1092*6dbdd20aSAndroid Build Coastguard Worker // Regression test for b/239725760.
1093*6dbdd20aSAndroid Build Coastguard Worker // Abstract sockets are not supported on Mac OS.
TEST_F(UnixSocketTest,Sockaddr_AbstractUnix)1094*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, Sockaddr_AbstractUnix) {
1095*6dbdd20aSAndroid Build Coastguard Worker   StackString<128> sock_name("@perfetto_test_%d_%d", getpid(), rand() % 100000);
1096*6dbdd20aSAndroid Build Coastguard Worker   auto srv =
1097*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Listen(sock_name.ToStdString(), &event_listener_,
1098*6dbdd20aSAndroid Build Coastguard Worker                          &task_runner_, SockFamily::kUnix, SockType::kStream);
1099*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv && srv->is_listening());
1100*6dbdd20aSAndroid Build Coastguard Worker 
1101*6dbdd20aSAndroid Build Coastguard Worker   auto cli = UnixSocketRaw::CreateMayFail(SockFamily::kUnix, SockType::kStream);
1102*6dbdd20aSAndroid Build Coastguard Worker   struct sockaddr_un addr {};
1103*6dbdd20aSAndroid Build Coastguard Worker   addr.sun_family = AF_UNIX;
1104*6dbdd20aSAndroid Build Coastguard Worker   StringCopy(addr.sun_path, sock_name.c_str(), sizeof(addr.sun_path));
1105*6dbdd20aSAndroid Build Coastguard Worker   addr.sun_path[0] = '\0';
1106*6dbdd20aSAndroid Build Coastguard Worker   auto addr_len = static_cast<socklen_t>(
1107*6dbdd20aSAndroid Build Coastguard Worker       __builtin_offsetof(sockaddr_un, sun_path) + sock_name.len());
1108*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(0, connect(cli.fd(), reinterpret_cast<struct sockaddr*>(&addr),
1109*6dbdd20aSAndroid Build Coastguard Worker                        addr_len));
1110*6dbdd20aSAndroid Build Coastguard Worker }
1111*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,VSockStream)1112*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, VSockStream) {
1113*6dbdd20aSAndroid Build Coastguard Worker   SKIP_IF_VSOCK_LOOPBACK_NOT_SUPPORTED();
1114*6dbdd20aSAndroid Build Coastguard Worker 
1115*6dbdd20aSAndroid Build Coastguard Worker   // Set up the server. Use the loopback CID (1) and a random port number.
1116*6dbdd20aSAndroid Build Coastguard Worker   auto srv = UnixSocket::Listen("vsock://1:-1", &event_listener_, &task_runner_,
1117*6dbdd20aSAndroid Build Coastguard Worker                                 SockFamily::kVsock, SockType::kStream);
1118*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(srv && srv->is_listening());
1119*6dbdd20aSAndroid Build Coastguard Worker 
1120*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<UnixSocket> prod;
1121*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
1122*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([&](UnixSocket*, UnixSocket* s) {
1123*6dbdd20aSAndroid Build Coastguard Worker         // OnDisconnect() might spuriously happen depending on the dtor order.
1124*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDisconnect(s)).Times(AtLeast(0));
1125*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_CALL(event_listener_, OnDataAvailable(s))
1126*6dbdd20aSAndroid Build Coastguard Worker             .WillRepeatedly(Invoke([](UnixSocket* prod_sock) {
1127*6dbdd20aSAndroid Build Coastguard Worker               prod_sock->ReceiveString();  // Read connection EOF;
1128*6dbdd20aSAndroid Build Coastguard Worker             }));
1129*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_TRUE(s->SendStr("welcome"));
1130*6dbdd20aSAndroid Build Coastguard Worker       }));
1131*6dbdd20aSAndroid Build Coastguard Worker 
1132*6dbdd20aSAndroid Build Coastguard Worker   // Set up the client.
1133*6dbdd20aSAndroid Build Coastguard Worker   prod =
1134*6dbdd20aSAndroid Build Coastguard Worker       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
1135*6dbdd20aSAndroid Build Coastguard Worker                           SockFamily::kVsock, SockType::kStream);
1136*6dbdd20aSAndroid Build Coastguard Worker   auto checkpoint = task_runner_.CreateCheckpoint("prod_connected");
1137*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDisconnect(prod.get())).Times(AtLeast(0));
1138*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnConnect(prod.get(), true));
1139*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(event_listener_, OnDataAvailable(prod.get()))
1140*6dbdd20aSAndroid Build Coastguard Worker       .WillRepeatedly(Invoke([checkpoint](UnixSocket* s) {
1141*6dbdd20aSAndroid Build Coastguard Worker         auto str = s->ReceiveString();
1142*6dbdd20aSAndroid Build Coastguard Worker         if (str.empty())
1143*6dbdd20aSAndroid Build Coastguard Worker           return;  // Connection EOF.
1144*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ("welcome", str);
1145*6dbdd20aSAndroid Build Coastguard Worker         checkpoint();
1146*6dbdd20aSAndroid Build Coastguard Worker       }));
1147*6dbdd20aSAndroid Build Coastguard Worker 
1148*6dbdd20aSAndroid Build Coastguard Worker   task_runner_.RunUntilCheckpoint("prod_connected");
1149*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(Mock::VerifyAndClearExpectations(prod.get()));
1150*6dbdd20aSAndroid Build Coastguard Worker }
1151*6dbdd20aSAndroid Build Coastguard Worker #endif  // OS_LINUX || OS_ANDROID
1152*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,GetSockFamily)1153*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, GetSockFamily) {
1154*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily(""), SockFamily::kUnspec);
1155*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("/path/to/sock"), SockFamily::kUnix);
1156*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("local_dir_sock"), SockFamily::kUnix);
1157*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("@abstract"), SockFamily::kUnix);
1158*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("0.0.0.0:80"), SockFamily::kInet);
1159*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("127.0.0.1:80"), SockFamily::kInet);
1160*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("[effe::acca]:1234"), SockFamily::kInet6);
1161*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("[::1]:123456"), SockFamily::kInet6);
1162*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
1163*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1164*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(GetSockFamily("vsock://-1:10000"), SockFamily::kVsock);
1165*6dbdd20aSAndroid Build Coastguard Worker #endif
1166*6dbdd20aSAndroid Build Coastguard Worker }
1167*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(UnixSocketTest,ShmemSupported)1168*6dbdd20aSAndroid Build Coastguard Worker TEST_F(UnixSocketTest, ShmemSupported) {
1169*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1170*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported(""), true);
1171*6dbdd20aSAndroid Build Coastguard Worker #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1172*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported(""), false);
1173*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("/path/to/sock"), true);
1174*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("local_dir_sock"), true);
1175*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("@abstract"), true);
1176*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("0.0.0.0:80"), false);
1177*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("127.0.0.1:80"), false);
1178*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("[effe::acca]:1234"), false);
1179*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("[::1]:123456"), false);
1180*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
1181*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1182*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(SockShmemSupported("vsock://-1:10000"), false);
1183*6dbdd20aSAndroid Build Coastguard Worker #endif
1184*6dbdd20aSAndroid Build Coastguard Worker #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1185*6dbdd20aSAndroid Build Coastguard Worker }
1186*6dbdd20aSAndroid Build Coastguard Worker 
1187*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
1188*6dbdd20aSAndroid Build Coastguard Worker }  // namespace base
1189*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
1190