blob: c6c9c0a87bcdffe7ce0fa05949cbdb37fab38b79 [file] [log] [blame]
[email protected]62558f12013-10-19 22:13:191// 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
[email protected]62558f12013-10-19 22:13:195#include "base/sync_socket.h"
Sergey Ulanove9631752017-08-03 19:24:296
Sergey Ulanove9631752017-08-03 19:24:297#include "base/synchronization/waitable_event.h"
8#include "base/threading/platform_thread.h"
[email protected]62558f12013-10-19 22:13:199#include "base/threading/simple_thread.h"
10#include "base/time/time.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
Sergey Ulanove9631752017-08-03 19:24:2913namespace base {
14
[email protected]62558f12013-10-19 22:13:1915namespace {
16
Sergey Ulanove9631752017-08-03 19:24:2917constexpr TimeDelta kReceiveTimeout = base::TimeDelta::FromMilliseconds(750);
[email protected]62558f12013-10-19 22:13:1918
Sergey Ulanove9631752017-08-03 19:24:2919class HangingReceiveThread : public DelegateSimpleThread::Delegate {
[email protected]62558f12013-10-19 22:13:1920 public:
Sergey Ulanove9631752017-08-03 19:24:2921 explicit HangingReceiveThread(SyncSocket* socket, bool with_timeout)
[email protected]62558f12013-10-19 22:13:1922 : socket_(socket),
Sergey Ulanove9631752017-08-03 19:24:2923 thread_(this, "HangingReceiveThread"),
24 with_timeout_(with_timeout),
25 started_event_(WaitableEvent::ResetPolicy::MANUAL,
26 WaitableEvent::InitialState::NOT_SIGNALED),
27 done_event_(WaitableEvent::ResetPolicy::MANUAL,
28 WaitableEvent::InitialState::NOT_SIGNALED) {
[email protected]62558f12013-10-19 22:13:1929 thread_.Start();
30 }
31
David Bienvenu5f4d4f02020-09-27 16:55:0332 HangingReceiveThread(const HangingReceiveThread&) = delete;
33 HangingReceiveThread& operator=(const HangingReceiveThread&) = delete;
Chris Watkinsbb7211c2017-11-29 07:16:3834 ~HangingReceiveThread() override = default;
[email protected]62558f12013-10-19 22:13:1935
dcheng56488182014-10-21 10:54:5136 void Run() override {
[email protected]62558f12013-10-19 22:13:1937 int data = 0;
38 ASSERT_EQ(socket_->Peek(), 0u);
39
Sergey Ulanove9631752017-08-03 19:24:2940 started_event_.Signal();
41
42 if (with_timeout_) {
43 ASSERT_EQ(0u, socket_->ReceiveWithTimeout(&data, sizeof(data),
44 kReceiveTimeout));
45 } else {
46 ASSERT_EQ(0u, socket_->Receive(&data, sizeof(data)));
47 }
48
49 done_event_.Signal();
[email protected]62558f12013-10-19 22:13:1950 }
51
52 void Stop() {
53 thread_.Join();
54 }
55
Sergey Ulanove9631752017-08-03 19:24:2956 WaitableEvent* started_event() { return &started_event_; }
57 WaitableEvent* done_event() { return &done_event_; }
58
[email protected]62558f12013-10-19 22:13:1959 private:
Sergey Ulanove9631752017-08-03 19:24:2960 SyncSocket* socket_;
61 DelegateSimpleThread thread_;
62 bool with_timeout_;
63 WaitableEvent started_event_;
64 WaitableEvent done_event_;
[email protected]62558f12013-10-19 22:13:1965};
66
Sergey Ulanove9631752017-08-03 19:24:2967// Tests sending data between two SyncSockets. Uses ASSERT() and thus will exit
[email protected]62558f12013-10-19 22:13:1968// early upon failure. Callers should use ASSERT_NO_FATAL_FAILURE() if testing
69// continues after return.
Sergey Ulanove9631752017-08-03 19:24:2970void SendReceivePeek(SyncSocket* socket_a, SyncSocket* socket_b) {
[email protected]62558f12013-10-19 22:13:1971 int received = 0;
72 const int kSending = 123;
avi4ec0dff2015-11-24 14:26:2473 static_assert(sizeof(kSending) == sizeof(received), "invalid data size");
[email protected]62558f12013-10-19 22:13:1974
75 ASSERT_EQ(0u, socket_a->Peek());
76 ASSERT_EQ(0u, socket_b->Peek());
77
78 // Verify |socket_a| can send to |socket_a| and |socket_a| can Receive from
79 // |socket_a|.
80 ASSERT_EQ(sizeof(kSending), socket_a->Send(&kSending, sizeof(kSending)));
81 ASSERT_EQ(sizeof(kSending), socket_b->Peek());
82 ASSERT_EQ(sizeof(kSending), socket_b->Receive(&received, sizeof(kSending)));
83 ASSERT_EQ(kSending, received);
84
85 ASSERT_EQ(0u, socket_a->Peek());
86 ASSERT_EQ(0u, socket_b->Peek());
87
88 // Now verify the reverse.
89 received = 0;
90 ASSERT_EQ(sizeof(kSending), socket_b->Send(&kSending, sizeof(kSending)));
91 ASSERT_EQ(sizeof(kSending), socket_a->Peek());
92 ASSERT_EQ(sizeof(kSending), socket_a->Receive(&received, sizeof(kSending)));
93 ASSERT_EQ(kSending, received);
94
95 ASSERT_EQ(0u, socket_a->Peek());
96 ASSERT_EQ(0u, socket_b->Peek());
97
Robert Sesek6ab73b022020-02-13 16:42:3998 socket_a->Close();
99 socket_b->Close();
[email protected]62558f12013-10-19 22:13:19100}
101
Sergey Ulanove9631752017-08-03 19:24:29102} // namespace
103
104class SyncSocketTest : public testing::Test {
105 public:
106 void SetUp() override {
107 ASSERT_TRUE(SyncSocket::CreatePair(&socket_a_, &socket_b_));
108 }
109
110 protected:
111 SyncSocket socket_a_;
112 SyncSocket socket_b_;
113};
114
115TEST_F(SyncSocketTest, NormalSendReceivePeek) {
116 SendReceivePeek(&socket_a_, &socket_b_);
[email protected]62558f12013-10-19 22:13:19117}
118
Sergey Ulanove9631752017-08-03 19:24:29119TEST_F(SyncSocketTest, ClonedSendReceivePeek) {
120 SyncSocket socket_c(socket_a_.Release());
121 SyncSocket socket_d(socket_b_.Release());
122 SendReceivePeek(&socket_c, &socket_d);
Nico Weberca5f9592019-01-31 14:35:41123}
brucedawsond3509432015-09-18 18:28:13124
Sergey Ulanove9631752017-08-03 19:24:29125class CancelableSyncSocketTest : public testing::Test {
126 public:
127 void SetUp() override {
128 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&socket_a_, &socket_b_));
129 }
130
131 protected:
132 CancelableSyncSocket socket_a_;
133 CancelableSyncSocket socket_b_;
134};
135
136TEST_F(CancelableSyncSocketTest, NormalSendReceivePeek) {
137 SendReceivePeek(&socket_a_, &socket_b_);
138}
139
140TEST_F(CancelableSyncSocketTest, ClonedSendReceivePeek) {
141 CancelableSyncSocket socket_c(socket_a_.Release());
142 CancelableSyncSocket socket_d(socket_b_.Release());
brucedawsond3509432015-09-18 18:28:13143 SendReceivePeek(&socket_c, &socket_d);
144}
145
Sergey Ulanove9631752017-08-03 19:24:29146TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceive) {
147 HangingReceiveThread thread(&socket_b_, /* with_timeout = */ false);
[email protected]62558f12013-10-19 22:13:19148
Sergey Ulanove9631752017-08-03 19:24:29149 // Wait for the thread to be started. Note that this doesn't guarantee that
150 // Receive() is called before Shutdown().
151 thread.started_event()->Wait();
[email protected]62558f12013-10-19 22:13:19152
Sergey Ulanove9631752017-08-03 19:24:29153 EXPECT_TRUE(socket_b_.Shutdown());
154 EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
brucedawsond3509432015-09-18 18:28:13155
[email protected]62558f12013-10-19 22:13:19156 thread.Stop();
Sergey Ulanove9631752017-08-03 19:24:29157}
158
159TEST_F(CancelableSyncSocketTest, ShutdownCancelsReceiveWithTimeout) {
160 HangingReceiveThread thread(&socket_b_, /* with_timeout = */ true);
161
162 // Wait for the thread to be started. Note that this doesn't guarantee that
163 // Receive() is called before Shutdown().
164 thread.started_event()->Wait();
165
166 EXPECT_TRUE(socket_b_.Shutdown());
167 EXPECT_TRUE(thread.done_event()->TimedWait(kReceiveTimeout));
168
169 thread.Stop();
170}
171
172TEST_F(CancelableSyncSocketTest, ReceiveAfterShutdown) {
173 socket_a_.Shutdown();
174 int data = 0;
175 EXPECT_EQ(0u, socket_a_.Receive(&data, sizeof(data)));
176}
177
178TEST_F(CancelableSyncSocketTest, ReceiveWithTimeoutAfterShutdown) {
179 socket_a_.Shutdown();
180 TimeTicks start = TimeTicks::Now();
181 int data = 0;
182 EXPECT_EQ(0u,
183 socket_a_.ReceiveWithTimeout(&data, sizeof(data), kReceiveTimeout));
[email protected]62558f12013-10-19 22:13:19184
185 // Ensure the receive didn't just timeout.
Sergey Ulanove9631752017-08-03 19:24:29186 EXPECT_LT(TimeTicks::Now() - start, kReceiveTimeout);
[email protected]62558f12013-10-19 22:13:19187}
Sergey Ulanove9631752017-08-03 19:24:29188
189} // namespace base