xref: /aosp_15_r20/external/cronet/base/sync_socket_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/sync_socket.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
12*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker namespace base {
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker constexpr TimeDelta kReceiveTimeout = base::Milliseconds(750);
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker class HangingReceiveThread : public DelegateSimpleThread::Delegate {
21*6777b538SAndroid Build Coastguard Worker  public:
HangingReceiveThread(SyncSocket * socket,bool with_timeout)22*6777b538SAndroid Build Coastguard Worker   explicit HangingReceiveThread(SyncSocket* socket, bool with_timeout)
23*6777b538SAndroid Build Coastguard Worker       : socket_(socket),
24*6777b538SAndroid Build Coastguard Worker         thread_(this, "HangingReceiveThread"),
25*6777b538SAndroid Build Coastguard Worker         with_timeout_(with_timeout),
26*6777b538SAndroid Build Coastguard Worker         started_event_(WaitableEvent::ResetPolicy::MANUAL,
27*6777b538SAndroid Build Coastguard Worker                        WaitableEvent::InitialState::NOT_SIGNALED),
28*6777b538SAndroid Build Coastguard Worker         done_event_(WaitableEvent::ResetPolicy::MANUAL,
29*6777b538SAndroid Build Coastguard Worker                     WaitableEvent::InitialState::NOT_SIGNALED) {
30*6777b538SAndroid Build Coastguard Worker     thread_.Start();
31*6777b538SAndroid Build Coastguard Worker   }
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker   HangingReceiveThread(const HangingReceiveThread&) = delete;
34*6777b538SAndroid Build Coastguard Worker   HangingReceiveThread& operator=(const HangingReceiveThread&) = delete;
35*6777b538SAndroid Build Coastguard Worker   ~HangingReceiveThread() override = default;
36*6777b538SAndroid Build Coastguard Worker 
Run()37*6777b538SAndroid Build Coastguard Worker   void Run() override {
38*6777b538SAndroid Build Coastguard Worker     int data = 0;
39*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(socket_->Peek(), 0u);
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker     started_event_.Signal();
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker     if (with_timeout_) {
44*6777b538SAndroid Build Coastguard Worker       ASSERT_EQ(0u, socket_->ReceiveWithTimeout(&data, sizeof(data),
45*6777b538SAndroid Build Coastguard Worker                                                 kReceiveTimeout));
46*6777b538SAndroid Build Coastguard Worker     } else {
47*6777b538SAndroid Build Coastguard Worker       ASSERT_EQ(0u, socket_->Receive(&data, sizeof(data)));
48*6777b538SAndroid Build Coastguard Worker     }
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker     done_event_.Signal();
51*6777b538SAndroid Build Coastguard Worker   }
52*6777b538SAndroid Build Coastguard Worker 
Stop()53*6777b538SAndroid Build Coastguard Worker   void Stop() {
54*6777b538SAndroid Build Coastguard Worker     thread_.Join();
55*6777b538SAndroid Build Coastguard Worker   }
56*6777b538SAndroid Build Coastguard Worker 
started_event()57*6777b538SAndroid Build Coastguard Worker   WaitableEvent* started_event() { return &started_event_; }
done_event()58*6777b538SAndroid Build Coastguard Worker   WaitableEvent* done_event() { return &done_event_; }
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker  private:
61*6777b538SAndroid Build Coastguard Worker   raw_ptr<SyncSocket> socket_;
62*6777b538SAndroid Build Coastguard Worker   DelegateSimpleThread thread_;
63*6777b538SAndroid Build Coastguard Worker   bool with_timeout_;
64*6777b538SAndroid Build Coastguard Worker   WaitableEvent started_event_;
65*6777b538SAndroid Build Coastguard Worker   WaitableEvent done_event_;
66*6777b538SAndroid Build Coastguard Worker };
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker // Tests sending data between two SyncSockets. Uses ASSERT() and thus will exit
69*6777b538SAndroid Build Coastguard Worker // early upon failure.  Callers should use ASSERT_NO_FATAL_FAILURE() if testing
70*6777b538SAndroid Build Coastguard Worker // continues after return.
SendReceivePeek(SyncSocket * socket_a,SyncSocket * socket_b)71*6777b538SAndroid Build Coastguard Worker void SendReceivePeek(SyncSocket* socket_a, SyncSocket* socket_b) {
72*6777b538SAndroid Build Coastguard Worker   int received = 0;
73*6777b538SAndroid Build Coastguard Worker   const int kSending = 123;
74*6777b538SAndroid Build Coastguard Worker   static_assert(sizeof(kSending) == sizeof(received), "invalid data size");
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, socket_a->Peek());
77*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, socket_b->Peek());
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker   // Verify |socket_a| can send to |socket_a| and |socket_a| can Receive from
80*6777b538SAndroid Build Coastguard Worker   // |socket_a|.
81*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kSending),
82*6777b538SAndroid Build Coastguard Worker             socket_a->Send(as_bytes(make_span(&kSending, 1u))));
83*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kSending), socket_b->Peek());
84*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kSending),
85*6777b538SAndroid Build Coastguard Worker             socket_b->Receive(as_writable_bytes(make_span(&received, 1u))));
86*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSending, received);
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, socket_a->Peek());
89*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, socket_b->Peek());
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   // Now verify the reverse.
92*6777b538SAndroid Build Coastguard Worker   received = 0;
93*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kSending),
94*6777b538SAndroid Build Coastguard Worker             socket_b->Send(as_bytes(make_span(&kSending, 1u))));
95*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kSending), socket_a->Peek());
96*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kSending),
97*6777b538SAndroid Build Coastguard Worker             socket_a->Receive(as_writable_bytes(make_span(&received, 1u))));
98*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSending, received);
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, socket_a->Peek());
101*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, socket_b->Peek());
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   socket_a->Close();
104*6777b538SAndroid Build Coastguard Worker   socket_b->Close();
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker }  // namespace
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker class SyncSocketTest : public testing::Test {
110*6777b538SAndroid Build Coastguard Worker  public:
SetUp()111*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
112*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(SyncSocket::CreatePair(&socket_a_, &socket_b_));
113*6777b538SAndroid Build Coastguard Worker   }
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker  protected:
116*6777b538SAndroid Build Coastguard Worker   SyncSocket socket_a_;
117*6777b538SAndroid Build Coastguard Worker   SyncSocket socket_b_;
118*6777b538SAndroid Build Coastguard Worker };
119*6777b538SAndroid Build Coastguard Worker 
TEST_F(SyncSocketTest,NormalSendReceivePeek)120*6777b538SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, NormalSendReceivePeek) {
121*6777b538SAndroid Build Coastguard Worker   SendReceivePeek(&socket_a_, &socket_b_);
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker 
TEST_F(SyncSocketTest,ClonedSendReceivePeek)124*6777b538SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, ClonedSendReceivePeek) {
125*6777b538SAndroid Build Coastguard Worker   SyncSocket socket_c(socket_a_.Release());
126*6777b538SAndroid Build Coastguard Worker   SyncSocket socket_d(socket_b_.Release());
127*6777b538SAndroid Build Coastguard Worker   SendReceivePeek(&socket_c, &socket_d);
128*6777b538SAndroid Build Coastguard Worker }
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker class CancelableSyncSocketTest : public testing::Test {
131*6777b538SAndroid Build Coastguard Worker  public:
SetUp()132*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
133*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CancelableSyncSocket::CreatePair(&socket_a_, &socket_b_));
134*6777b538SAndroid Build Coastguard Worker   }
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker  protected:
137*6777b538SAndroid Build Coastguard Worker   CancelableSyncSocket socket_a_;
138*6777b538SAndroid Build Coastguard Worker   CancelableSyncSocket socket_b_;
139*6777b538SAndroid Build Coastguard Worker };
140*6777b538SAndroid Build Coastguard Worker 
TEST_F(CancelableSyncSocketTest,NormalSendReceivePeek)141*6777b538SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, NormalSendReceivePeek) {
142*6777b538SAndroid Build Coastguard Worker   SendReceivePeek(&socket_a_, &socket_b_);
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker 
TEST_F(CancelableSyncSocketTest,ClonedSendReceivePeek)145*6777b538SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ClonedSendReceivePeek) {
146*6777b538SAndroid Build Coastguard Worker   CancelableSyncSocket socket_c(socket_a_.Release());
147*6777b538SAndroid Build Coastguard Worker   CancelableSyncSocket socket_d(socket_b_.Release());
148*6777b538SAndroid Build Coastguard Worker   SendReceivePeek(&socket_c, &socket_d);
149*6777b538SAndroid Build Coastguard Worker }
150*6777b538SAndroid Build Coastguard Worker 
TEST_F(CancelableSyncSocketTest,ShutdownCancelsReceive)151*6777b538SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceive) {
152*6777b538SAndroid Build Coastguard Worker   HangingReceiveThread thread(&socket_b_, /* with_timeout = */ false);
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   // Wait for the thread to be started. Note that this doesn't guarantee that
155*6777b538SAndroid Build Coastguard Worker   // Receive() is called before Shutdown().
156*6777b538SAndroid Build Coastguard Worker   thread.started_event()->Wait();
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(socket_b_.Shutdown());
159*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   thread.Stop();
162*6777b538SAndroid Build Coastguard Worker }
163*6777b538SAndroid Build Coastguard Worker 
TEST_F(CancelableSyncSocketTest,ShutdownCancelsReceiveWithTimeout)164*6777b538SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceiveWithTimeout) {
165*6777b538SAndroid Build Coastguard Worker   HangingReceiveThread thread(&socket_b_, /* with_timeout = */ true);
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   // Wait for the thread to be started. Note that this doesn't guarantee that
168*6777b538SAndroid Build Coastguard Worker   // Receive() is called before Shutdown().
169*6777b538SAndroid Build Coastguard Worker   thread.started_event()->Wait();
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(socket_b_.Shutdown());
172*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker   thread.Stop();
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker 
TEST_F(CancelableSyncSocketTest,ReceiveAfterShutdown)177*6777b538SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ReceiveAfterShutdown) {
178*6777b538SAndroid Build Coastguard Worker   socket_a_.Shutdown();
179*6777b538SAndroid Build Coastguard Worker   int data = 0;
180*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, socket_a_.Receive(as_writable_bytes(make_span(&data, 1u))));
181*6777b538SAndroid Build Coastguard Worker }
182*6777b538SAndroid Build Coastguard Worker 
TEST_F(CancelableSyncSocketTest,ReceiveWithTimeoutAfterShutdown)183*6777b538SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ReceiveWithTimeoutAfterShutdown) {
184*6777b538SAndroid Build Coastguard Worker   socket_a_.Shutdown();
185*6777b538SAndroid Build Coastguard Worker   TimeTicks start = TimeTicks::Now();
186*6777b538SAndroid Build Coastguard Worker   int data = 0;
187*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u,
188*6777b538SAndroid Build Coastguard Worker             socket_a_.ReceiveWithTimeout(&data, sizeof(data), kReceiveTimeout));
189*6777b538SAndroid Build Coastguard Worker 
190*6777b538SAndroid Build Coastguard Worker   // Ensure the receive didn't just timeout.
191*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(TimeTicks::Now() - start, kReceiveTimeout);
192*6777b538SAndroid Build Coastguard Worker }
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker }  // namespace base
195