1*635a8641SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/sync_socket.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
8*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
9*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
12*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*635a8641SAndroid Build Coastguard Worker
14*635a8641SAndroid Build Coastguard Worker namespace base {
15*635a8641SAndroid Build Coastguard Worker
16*635a8641SAndroid Build Coastguard Worker namespace {
17*635a8641SAndroid Build Coastguard Worker
18*635a8641SAndroid Build Coastguard Worker constexpr TimeDelta kReceiveTimeout = base::TimeDelta::FromMilliseconds(750);
19*635a8641SAndroid Build Coastguard Worker
20*635a8641SAndroid Build Coastguard Worker class HangingReceiveThread : public DelegateSimpleThread::Delegate {
21*635a8641SAndroid Build Coastguard Worker public:
HangingReceiveThread(SyncSocket * socket,bool with_timeout)22*635a8641SAndroid Build Coastguard Worker explicit HangingReceiveThread(SyncSocket* socket, bool with_timeout)
23*635a8641SAndroid Build Coastguard Worker : socket_(socket),
24*635a8641SAndroid Build Coastguard Worker thread_(this, "HangingReceiveThread"),
25*635a8641SAndroid Build Coastguard Worker with_timeout_(with_timeout),
26*635a8641SAndroid Build Coastguard Worker started_event_(WaitableEvent::ResetPolicy::MANUAL,
27*635a8641SAndroid Build Coastguard Worker WaitableEvent::InitialState::NOT_SIGNALED),
28*635a8641SAndroid Build Coastguard Worker done_event_(WaitableEvent::ResetPolicy::MANUAL,
29*635a8641SAndroid Build Coastguard Worker WaitableEvent::InitialState::NOT_SIGNALED) {
30*635a8641SAndroid Build Coastguard Worker thread_.Start();
31*635a8641SAndroid Build Coastguard Worker }
32*635a8641SAndroid Build Coastguard Worker
33*635a8641SAndroid Build Coastguard Worker ~HangingReceiveThread() override = default;
34*635a8641SAndroid Build Coastguard Worker
Run()35*635a8641SAndroid Build Coastguard Worker void Run() override {
36*635a8641SAndroid Build Coastguard Worker int data = 0;
37*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(socket_->Peek(), 0u);
38*635a8641SAndroid Build Coastguard Worker
39*635a8641SAndroid Build Coastguard Worker started_event_.Signal();
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker if (with_timeout_) {
42*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_->ReceiveWithTimeout(&data, sizeof(data),
43*635a8641SAndroid Build Coastguard Worker kReceiveTimeout));
44*635a8641SAndroid Build Coastguard Worker } else {
45*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_->Receive(&data, sizeof(data)));
46*635a8641SAndroid Build Coastguard Worker }
47*635a8641SAndroid Build Coastguard Worker
48*635a8641SAndroid Build Coastguard Worker done_event_.Signal();
49*635a8641SAndroid Build Coastguard Worker }
50*635a8641SAndroid Build Coastguard Worker
Stop()51*635a8641SAndroid Build Coastguard Worker void Stop() {
52*635a8641SAndroid Build Coastguard Worker thread_.Join();
53*635a8641SAndroid Build Coastguard Worker }
54*635a8641SAndroid Build Coastguard Worker
started_event()55*635a8641SAndroid Build Coastguard Worker WaitableEvent* started_event() { return &started_event_; }
done_event()56*635a8641SAndroid Build Coastguard Worker WaitableEvent* done_event() { return &done_event_; }
57*635a8641SAndroid Build Coastguard Worker
58*635a8641SAndroid Build Coastguard Worker private:
59*635a8641SAndroid Build Coastguard Worker SyncSocket* socket_;
60*635a8641SAndroid Build Coastguard Worker DelegateSimpleThread thread_;
61*635a8641SAndroid Build Coastguard Worker bool with_timeout_;
62*635a8641SAndroid Build Coastguard Worker WaitableEvent started_event_;
63*635a8641SAndroid Build Coastguard Worker WaitableEvent done_event_;
64*635a8641SAndroid Build Coastguard Worker
65*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(HangingReceiveThread);
66*635a8641SAndroid Build Coastguard Worker };
67*635a8641SAndroid Build Coastguard Worker
68*635a8641SAndroid Build Coastguard Worker // Tests sending data between two SyncSockets. Uses ASSERT() and thus will exit
69*635a8641SAndroid Build Coastguard Worker // early upon failure. Callers should use ASSERT_NO_FATAL_FAILURE() if testing
70*635a8641SAndroid Build Coastguard Worker // continues after return.
SendReceivePeek(SyncSocket * socket_a,SyncSocket * socket_b)71*635a8641SAndroid Build Coastguard Worker void SendReceivePeek(SyncSocket* socket_a, SyncSocket* socket_b) {
72*635a8641SAndroid Build Coastguard Worker int received = 0;
73*635a8641SAndroid Build Coastguard Worker const int kSending = 123;
74*635a8641SAndroid Build Coastguard Worker static_assert(sizeof(kSending) == sizeof(received), "invalid data size");
75*635a8641SAndroid Build Coastguard Worker
76*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_a->Peek());
77*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_b->Peek());
78*635a8641SAndroid Build Coastguard Worker
79*635a8641SAndroid Build Coastguard Worker // Verify |socket_a| can send to |socket_a| and |socket_a| can Receive from
80*635a8641SAndroid Build Coastguard Worker // |socket_a|.
81*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kSending), socket_a->Send(&kSending, sizeof(kSending)));
82*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kSending), socket_b->Peek());
83*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kSending), socket_b->Receive(&received, sizeof(kSending)));
84*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kSending, received);
85*635a8641SAndroid Build Coastguard Worker
86*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_a->Peek());
87*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_b->Peek());
88*635a8641SAndroid Build Coastguard Worker
89*635a8641SAndroid Build Coastguard Worker // Now verify the reverse.
90*635a8641SAndroid Build Coastguard Worker received = 0;
91*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kSending), socket_b->Send(&kSending, sizeof(kSending)));
92*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kSending), socket_a->Peek());
93*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kSending), socket_a->Receive(&received, sizeof(kSending)));
94*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kSending, received);
95*635a8641SAndroid Build Coastguard Worker
96*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_a->Peek());
97*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0u, socket_b->Peek());
98*635a8641SAndroid Build Coastguard Worker
99*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(socket_a->Close());
100*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(socket_b->Close());
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker
103*635a8641SAndroid Build Coastguard Worker } // namespace
104*635a8641SAndroid Build Coastguard Worker
105*635a8641SAndroid Build Coastguard Worker class SyncSocketTest : public testing::Test {
106*635a8641SAndroid Build Coastguard Worker public:
SetUp()107*635a8641SAndroid Build Coastguard Worker void SetUp() override {
108*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(SyncSocket::CreatePair(&socket_a_, &socket_b_));
109*635a8641SAndroid Build Coastguard Worker }
110*635a8641SAndroid Build Coastguard Worker
111*635a8641SAndroid Build Coastguard Worker protected:
112*635a8641SAndroid Build Coastguard Worker SyncSocket socket_a_;
113*635a8641SAndroid Build Coastguard Worker SyncSocket socket_b_;
114*635a8641SAndroid Build Coastguard Worker };
115*635a8641SAndroid Build Coastguard Worker
TEST_F(SyncSocketTest,NormalSendReceivePeek)116*635a8641SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, NormalSendReceivePeek) {
117*635a8641SAndroid Build Coastguard Worker SendReceivePeek(&socket_a_, &socket_b_);
118*635a8641SAndroid Build Coastguard Worker }
119*635a8641SAndroid Build Coastguard Worker
TEST_F(SyncSocketTest,ClonedSendReceivePeek)120*635a8641SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, ClonedSendReceivePeek) {
121*635a8641SAndroid Build Coastguard Worker SyncSocket socket_c(socket_a_.Release());
122*635a8641SAndroid Build Coastguard Worker SyncSocket socket_d(socket_b_.Release());
123*635a8641SAndroid Build Coastguard Worker SendReceivePeek(&socket_c, &socket_d);
124*635a8641SAndroid Build Coastguard Worker };
125*635a8641SAndroid Build Coastguard Worker
126*635a8641SAndroid Build Coastguard Worker class CancelableSyncSocketTest : public testing::Test {
127*635a8641SAndroid Build Coastguard Worker public:
SetUp()128*635a8641SAndroid Build Coastguard Worker void SetUp() override {
129*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(CancelableSyncSocket::CreatePair(&socket_a_, &socket_b_));
130*635a8641SAndroid Build Coastguard Worker }
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker protected:
133*635a8641SAndroid Build Coastguard Worker CancelableSyncSocket socket_a_;
134*635a8641SAndroid Build Coastguard Worker CancelableSyncSocket socket_b_;
135*635a8641SAndroid Build Coastguard Worker };
136*635a8641SAndroid Build Coastguard Worker
TEST_F(CancelableSyncSocketTest,NormalSendReceivePeek)137*635a8641SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, NormalSendReceivePeek) {
138*635a8641SAndroid Build Coastguard Worker SendReceivePeek(&socket_a_, &socket_b_);
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker
TEST_F(CancelableSyncSocketTest,ClonedSendReceivePeek)141*635a8641SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ClonedSendReceivePeek) {
142*635a8641SAndroid Build Coastguard Worker CancelableSyncSocket socket_c(socket_a_.Release());
143*635a8641SAndroid Build Coastguard Worker CancelableSyncSocket socket_d(socket_b_.Release());
144*635a8641SAndroid Build Coastguard Worker SendReceivePeek(&socket_c, &socket_d);
145*635a8641SAndroid Build Coastguard Worker }
146*635a8641SAndroid Build Coastguard Worker
TEST_F(CancelableSyncSocketTest,ShutdownCancelsReceive)147*635a8641SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceive) {
148*635a8641SAndroid Build Coastguard Worker HangingReceiveThread thread(&socket_b_, /* with_timeout = */ false);
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker // Wait for the thread to be started. Note that this doesn't guarantee that
151*635a8641SAndroid Build Coastguard Worker // Receive() is called before Shutdown().
152*635a8641SAndroid Build Coastguard Worker thread.started_event()->Wait();
153*635a8641SAndroid Build Coastguard Worker
154*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(socket_b_.Shutdown());
155*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
156*635a8641SAndroid Build Coastguard Worker
157*635a8641SAndroid Build Coastguard Worker thread.Stop();
158*635a8641SAndroid Build Coastguard Worker }
159*635a8641SAndroid Build Coastguard Worker
TEST_F(CancelableSyncSocketTest,ShutdownCancelsReceiveWithTimeout)160*635a8641SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceiveWithTimeout) {
161*635a8641SAndroid Build Coastguard Worker HangingReceiveThread thread(&socket_b_, /* with_timeout = */ true);
162*635a8641SAndroid Build Coastguard Worker
163*635a8641SAndroid Build Coastguard Worker // Wait for the thread to be started. Note that this doesn't guarantee that
164*635a8641SAndroid Build Coastguard Worker // Receive() is called before Shutdown().
165*635a8641SAndroid Build Coastguard Worker thread.started_event()->Wait();
166*635a8641SAndroid Build Coastguard Worker
167*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(socket_b_.Shutdown());
168*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
169*635a8641SAndroid Build Coastguard Worker
170*635a8641SAndroid Build Coastguard Worker thread.Stop();
171*635a8641SAndroid Build Coastguard Worker }
172*635a8641SAndroid Build Coastguard Worker
TEST_F(CancelableSyncSocketTest,ReceiveAfterShutdown)173*635a8641SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ReceiveAfterShutdown) {
174*635a8641SAndroid Build Coastguard Worker socket_a_.Shutdown();
175*635a8641SAndroid Build Coastguard Worker int data = 0;
176*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0u, socket_a_.Receive(&data, sizeof(data)));
177*635a8641SAndroid Build Coastguard Worker }
178*635a8641SAndroid Build Coastguard Worker
TEST_F(CancelableSyncSocketTest,ReceiveWithTimeoutAfterShutdown)179*635a8641SAndroid Build Coastguard Worker TEST_F(CancelableSyncSocketTest, ReceiveWithTimeoutAfterShutdown) {
180*635a8641SAndroid Build Coastguard Worker socket_a_.Shutdown();
181*635a8641SAndroid Build Coastguard Worker TimeTicks start = TimeTicks::Now();
182*635a8641SAndroid Build Coastguard Worker int data = 0;
183*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0u,
184*635a8641SAndroid Build Coastguard Worker socket_a_.ReceiveWithTimeout(&data, sizeof(data), kReceiveTimeout));
185*635a8641SAndroid Build Coastguard Worker
186*635a8641SAndroid Build Coastguard Worker // Ensure the receive didn't just timeout.
187*635a8641SAndroid Build Coastguard Worker EXPECT_LT(TimeTicks::Now() - start, kReceiveTimeout);
188*635a8641SAndroid Build Coastguard Worker }
189*635a8641SAndroid Build Coastguard Worker
190*635a8641SAndroid Build Coastguard Worker } // namespace base
191