Home | History | Annotate | Download | only in base
      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:
     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 
     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 
     51   void Stop() {
     52     thread_.Join();
     53   }
     54 
     55   WaitableEvent* started_event() { return &started_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.
     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:
    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 
    116 TEST_F(SyncSocketTest, NormalSendReceivePeek) {
    117   SendReceivePeek(&socket_a_, &socket_b_);
    118 }
    119 
    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:
    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 
    137 TEST_F(CancelableSyncSocketTest, NormalSendReceivePeek) {
    138   SendReceivePeek(&socket_a_, &socket_b_);
    139 }
    140 
    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 
    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 
    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 
    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 
    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