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