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