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 11namespace { 12 13const int kReceiveTimeoutInMilliseconds = 750; 14 15class 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 virtual ~HangingReceiveThread() {} 24 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 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. 49void 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 81template <class SocketType> 82void NormalSendReceivePeek() { 83 SocketType socket_a, socket_b; 84 ASSERT_TRUE(SocketType::CreatePair(&socket_a, &socket_b)); 85 SendReceivePeek(&socket_a, &socket_b); 86} 87 88template <class SocketType> 89void 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 100TEST(SyncSocket, NormalSendReceivePeek) { 101 NormalSendReceivePeek<base::SyncSocket>(); 102} 103 104TEST(SyncSocket, ClonedSendReceivePeek) { 105 ClonedSendReceivePeek<base::SyncSocket>(); 106} 107 108TEST(CancelableSyncSocket, NormalSendReceivePeek) { 109 NormalSendReceivePeek<base::CancelableSyncSocket>(); 110} 111 112TEST(CancelableSyncSocket, ClonedSendReceivePeek) { 113 ClonedSendReceivePeek<base::CancelableSyncSocket>(); 114} 115 116TEST(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