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