• 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/basictypes.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:
HangingReceiveThread(base::SyncSocket * socket)17   explicit HangingReceiveThread(base::SyncSocket* socket)
18       : socket_(socket),
19         thread_(this, "HangingReceiveThread") {
20     thread_.Start();
21   }
22 
~HangingReceiveThread()23   virtual ~HangingReceiveThread() {}
24 
Run()25   virtual 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 
Stop()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.
SendReceivePeek(base::SyncSocket * socket_a,base::SyncSocket * socket_b)49 void SendReceivePeek(base::SyncSocket* socket_a, base::SyncSocket* socket_b) {
50   int received = 0;
51   const int kSending = 123;
52   COMPILE_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>
NormalSendReceivePeek()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>
ClonedSendReceivePeek()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 
TEST(SyncSocket,NormalSendReceivePeek)100 TEST(SyncSocket, NormalSendReceivePeek) {
101   NormalSendReceivePeek<base::SyncSocket>();
102 }
103 
TEST(SyncSocket,ClonedSendReceivePeek)104 TEST(SyncSocket, ClonedSendReceivePeek) {
105   ClonedSendReceivePeek<base::SyncSocket>();
106 }
107 
TEST(CancelableSyncSocket,NormalSendReceivePeek)108 TEST(CancelableSyncSocket, NormalSendReceivePeek) {
109   NormalSendReceivePeek<base::CancelableSyncSocket>();
110 }
111 
TEST(CancelableSyncSocket,ClonedSendReceivePeek)112 TEST(CancelableSyncSocket, ClonedSendReceivePeek) {
113   ClonedSendReceivePeek<base::CancelableSyncSocket>();
114 }
115 
TEST(CancelableSyncSocket,CancelReceiveShutdown)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