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/macros.h"
      6 #include "base/sync_socket.h"
      7 #include "base/threading/simple_thread.h"
      8 #include "base/time/time.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 namespace {
     12 
     13 const int kReceiveTimeoutInMilliseconds = 750;
     14 
     15 class HangingReceiveThread : public base::DelegateSimpleThread::Delegate {
     16  public:
     17   explicit HangingReceiveThread(base::SyncSocket* socket)
     18       : socket_(socket),
     19         thread_(this, "HangingReceiveThread") {
     20     thread_.Start();
     21   }
     22 
     23   ~HangingReceiveThread() override {}
     24 
     25   void Run() override {
     26     int data = 0;
     27     ASSERT_EQ(socket_->Peek(), 0u);
     28 
     29     // Use receive with timeout so we don't hang the test harness indefinitely.
     30     ASSERT_EQ(0u, socket_->ReceiveWithTimeout(
     31         &data, sizeof(data), base::TimeDelta::FromMilliseconds(
     32             kReceiveTimeoutInMilliseconds)));
     33   }
     34 
     35   void Stop() {
     36     thread_.Join();
     37   }
     38 
     39  private:
     40   base::SyncSocket* socket_;
     41   base::DelegateSimpleThread thread_;
     42 
     43   DISALLOW_COPY_AND_ASSIGN(HangingReceiveThread);
     44 };
     45 
     46 // Tests sending data between two SyncSockets.  Uses ASSERT() and thus will exit
     47 // early upon failure.  Callers should use ASSERT_NO_FATAL_FAILURE() if testing
     48 // continues after return.
     49 void SendReceivePeek(base::SyncSocket* socket_a, base::SyncSocket* socket_b) {
     50   int received = 0;
     51   const int kSending = 123;
     52   static_assert(sizeof(kSending) == sizeof(received), "invalid data size");
     53 
     54   ASSERT_EQ(0u, socket_a->Peek());
     55   ASSERT_EQ(0u, socket_b->Peek());
     56 
     57   // Verify |socket_a| can send to |socket_a| and |socket_a| can Receive from
     58   // |socket_a|.
     59   ASSERT_EQ(sizeof(kSending), socket_a->Send(&kSending, sizeof(kSending)));
     60   ASSERT_EQ(sizeof(kSending), socket_b->Peek());
     61   ASSERT_EQ(sizeof(kSending), socket_b->Receive(&received, sizeof(kSending)));
     62   ASSERT_EQ(kSending, received);
     63 
     64   ASSERT_EQ(0u, socket_a->Peek());
     65   ASSERT_EQ(0u, socket_b->Peek());
     66 
     67   // Now verify the reverse.
     68   received = 0;
     69   ASSERT_EQ(sizeof(kSending), socket_b->Send(&kSending, sizeof(kSending)));
     70   ASSERT_EQ(sizeof(kSending), socket_a->Peek());
     71   ASSERT_EQ(sizeof(kSending), socket_a->Receive(&received, sizeof(kSending)));
     72   ASSERT_EQ(kSending, received);
     73 
     74   ASSERT_EQ(0u, socket_a->Peek());
     75   ASSERT_EQ(0u, socket_b->Peek());
     76 
     77   ASSERT_TRUE(socket_a->Close());
     78   ASSERT_TRUE(socket_b->Close());
     79 }
     80 
     81 template <class SocketType>
     82 void NormalSendReceivePeek() {
     83   SocketType socket_a, socket_b;
     84   ASSERT_TRUE(SocketType::CreatePair(&socket_a, &socket_b));
     85   SendReceivePeek(&socket_a, &socket_b);
     86 }
     87 
     88 template <class SocketType>
     89 void ClonedSendReceivePeek() {
     90   SocketType socket_a, socket_b;
     91   ASSERT_TRUE(SocketType::CreatePair(&socket_a, &socket_b));
     92 
     93   // Create new SyncSockets from the paired handles.
     94   SocketType socket_c(socket_a.handle()), socket_d(socket_b.handle());
     95   SendReceivePeek(&socket_c, &socket_d);
     96 }
     97 
     98 }  // namespace
     99 
    100 TEST(SyncSocket, NormalSendReceivePeek) {
    101   NormalSendReceivePeek<base::SyncSocket>();
    102 }
    103 
    104 TEST(SyncSocket, ClonedSendReceivePeek) {
    105   ClonedSendReceivePeek<base::SyncSocket>();
    106 }
    107 
    108 TEST(CancelableSyncSocket, NormalSendReceivePeek) {
    109   NormalSendReceivePeek<base::CancelableSyncSocket>();
    110 }
    111 
    112 TEST(CancelableSyncSocket, ClonedSendReceivePeek) {
    113   ClonedSendReceivePeek<base::CancelableSyncSocket>();
    114 }
    115 
    116 TEST(CancelableSyncSocket, CancelReceiveShutdown) {
    117   base::CancelableSyncSocket socket_a, socket_b;
    118   ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&socket_a, &socket_b));
    119 
    120   base::TimeTicks start = base::TimeTicks::Now();
    121   HangingReceiveThread thread(&socket_b);
    122   ASSERT_TRUE(socket_b.Shutdown());
    123   thread.Stop();
    124 
    125   // Ensure the receive didn't just timeout.
    126   ASSERT_LT((base::TimeTicks::Now() - start).InMilliseconds(),
    127             kReceiveTimeoutInMilliseconds);
    128 
    129   ASSERT_TRUE(socket_a.Close());
    130   ASSERT_TRUE(socket_b.Close());
    131 }
    132