blob: 7e4089cb53ce7769b616aafc820bd1e57c63f4e8 [file] [log] [blame]
dalecurtis@chromium.org96b19df2013-10-20 07:13:19 +09001// 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}