blob: 2974b5a3d50ad5622aea77359036fd40359fe810 [file] [log] [blame]
[email protected]654866142014-06-24 22:53:311// Copyright 2014 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 "net/socket/websocket_endpoint_lock_manager.h"
6
riceabafe0f22015-01-23 05:31:257#include "base/message_loop/message_loop.h"
8#include "base/run_loop.h"
9#include "base/time/time.h"
[email protected]654866142014-06-24 22:53:3110#include "net/base/net_errors.h"
11#include "net/socket/next_proto.h"
12#include "net/socket/socket_test_util.h"
13#include "net/socket/stream_socket.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16namespace net {
17
18namespace {
19
20// A StreamSocket implementation with no functionality at all.
21// TODO(ricea): If you need to use this in another file, please move it to
22// socket_test_util.h.
23class FakeStreamSocket : public StreamSocket {
24 public:
25 FakeStreamSocket() {}
26
27 // StreamSocket implementation
dchengb03027d2014-10-21 12:00:2028 int Connect(const CompletionCallback& callback) override {
[email protected]654866142014-06-24 22:53:3129 return ERR_FAILED;
30 }
31
dchengb03027d2014-10-21 12:00:2032 void Disconnect() override { return; }
[email protected]654866142014-06-24 22:53:3133
dchengb03027d2014-10-21 12:00:2034 bool IsConnected() const override { return false; }
[email protected]654866142014-06-24 22:53:3135
dchengb03027d2014-10-21 12:00:2036 bool IsConnectedAndIdle() const override { return false; }
[email protected]654866142014-06-24 22:53:3137
dchengb03027d2014-10-21 12:00:2038 int GetPeerAddress(IPEndPoint* address) const override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3139
dchengb03027d2014-10-21 12:00:2040 int GetLocalAddress(IPEndPoint* address) const override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3141
dchengb03027d2014-10-21 12:00:2042 const BoundNetLog& NetLog() const override { return bound_net_log_; }
[email protected]654866142014-06-24 22:53:3143
dchengb03027d2014-10-21 12:00:2044 void SetSubresourceSpeculation() override { return; }
45 void SetOmniboxSpeculation() override { return; }
[email protected]654866142014-06-24 22:53:3146
dchengb03027d2014-10-21 12:00:2047 bool WasEverUsed() const override { return false; }
[email protected]654866142014-06-24 22:53:3148
dchengb03027d2014-10-21 12:00:2049 bool UsingTCPFastOpen() const override { return false; }
[email protected]654866142014-06-24 22:53:3150
dchengb03027d2014-10-21 12:00:2051 bool WasNpnNegotiated() const override { return false; }
[email protected]654866142014-06-24 22:53:3152
dchengb03027d2014-10-21 12:00:2053 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]654866142014-06-24 22:53:3154
dchengb03027d2014-10-21 12:00:2055 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]654866142014-06-24 22:53:3156
57 // Socket implementation
dchengb03027d2014-10-21 12:00:2058 int Read(IOBuffer* buf,
59 int buf_len,
60 const CompletionCallback& callback) override {
[email protected]654866142014-06-24 22:53:3161 return ERR_FAILED;
62 }
63
dchengb03027d2014-10-21 12:00:2064 int Write(IOBuffer* buf,
65 int buf_len,
66 const CompletionCallback& callback) override {
[email protected]654866142014-06-24 22:53:3167 return ERR_FAILED;
68 }
69
dchengb03027d2014-10-21 12:00:2070 int SetReceiveBufferSize(int32 size) override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3171
dchengb03027d2014-10-21 12:00:2072 int SetSendBufferSize(int32 size) override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3173
74 private:
75 BoundNetLog bound_net_log_;
76
77 DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket);
78};
79
80class FakeWaiter : public WebSocketEndpointLockManager::Waiter {
81 public:
82 FakeWaiter() : called_(false) {}
83
dchengb03027d2014-10-21 12:00:2084 void GotEndpointLock() override {
[email protected]654866142014-06-24 22:53:3185 CHECK(!called_);
86 called_ = true;
87 }
88
89 bool called() const { return called_; }
90
91 private:
92 bool called_;
93};
94
95class WebSocketEndpointLockManagerTest : public ::testing::Test {
96 protected:
97 WebSocketEndpointLockManagerTest()
98 : instance_(WebSocketEndpointLockManager::GetInstance()) {}
dcheng67be2b1f2014-10-27 21:47:2999 ~WebSocketEndpointLockManagerTest() override {
riceabafe0f22015-01-23 05:31:25100 // Permit any pending asynchronous unlock operations to complete.
101 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31102 // If this check fails then subsequent tests may fail.
103 CHECK(instance_->IsEmpty());
104 }
105
106 WebSocketEndpointLockManager* instance() const { return instance_; }
107
108 IPEndPoint DummyEndpoint() {
109 IPAddressNumber ip_address_number;
110 CHECK(ParseIPLiteralToNumber("127.0.0.1", &ip_address_number));
111 return IPEndPoint(ip_address_number, 80);
112 }
113
114 void UnlockDummyEndpoint(int times) {
115 for (int i = 0; i < times; ++i) {
116 instance()->UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25117 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31118 }
119 }
120
riceabafe0f22015-01-23 05:31:25121 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
122
[email protected]654866142014-06-24 22:53:31123 WebSocketEndpointLockManager* const instance_;
riceabafe0f22015-01-23 05:31:25124 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
[email protected]654866142014-06-24 22:53:31125};
126
127TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) {
128 // All the work is done by the test framework.
129}
130
131TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) {
132 FakeWaiter waiters[2];
133 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
134 EXPECT_EQ(ERR_IO_PENDING,
135 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
136
137 UnlockDummyEndpoint(2);
138}
139
140TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
141 FakeWaiter waiter;
142 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
riceabafe0f22015-01-23 05:31:25143 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31144 EXPECT_FALSE(waiter.called());
145
146 UnlockDummyEndpoint(1);
147}
148
149TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) {
150 FakeWaiter waiters[2];
151 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
152 EXPECT_EQ(ERR_IO_PENDING,
153 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
riceabafe0f22015-01-23 05:31:25154 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31155 EXPECT_FALSE(waiters[1].called());
156
157 UnlockDummyEndpoint(2);
158}
159
160TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) {
161 FakeWaiter waiters[2];
162 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
163 EXPECT_EQ(ERR_IO_PENDING,
164 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
165 instance()->UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25166 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31167 EXPECT_TRUE(waiters[1].called());
168
169 UnlockDummyEndpoint(1);
170}
171
172TEST_F(WebSocketEndpointLockManagerTest,
173 EndpointUnlockedIfWaiterAlreadyDeleted) {
174 FakeWaiter first_lock_holder;
175 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder));
176
177 {
178 FakeWaiter short_lived_waiter;
179 EXPECT_EQ(ERR_IO_PENDING,
180 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter));
181 }
182
183 instance()->UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25184 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31185
186 FakeWaiter second_lock_holder;
187 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder));
188
189 UnlockDummyEndpoint(1);
190}
191
192TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) {
193 FakeWaiter waiters[2];
194 FakeStreamSocket dummy_socket;
195 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
196 EXPECT_EQ(ERR_IO_PENDING,
197 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
198
199 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
200 instance()->UnlockSocket(&dummy_socket);
riceabafe0f22015-01-23 05:31:25201 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31202 EXPECT_TRUE(waiters[1].called());
203
204 UnlockDummyEndpoint(1);
205}
206
[email protected]6bcd67d2014-08-05 16:31:24207// UnlockEndpoint() should cause any sockets remembered for this endpoint
208// to be forgotten.
209TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
[email protected]654866142014-06-24 22:53:31210 FakeWaiter waiter;
211 FakeStreamSocket dummy_socket;
[email protected]6bcd67d2014-08-05 16:31:24212
[email protected]654866142014-06-24 22:53:31213 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
214 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
[email protected]6bcd67d2014-08-05 16:31:24215 instance()->UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25216 RunUntilIdle();
[email protected]6bcd67d2014-08-05 16:31:24217 EXPECT_TRUE(instance()->IsEmpty());
218}
219
220// When ownership of the endpoint is passed to a new waiter, the new waiter can
221// call RememberSocket() again.
222TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) {
223 FakeWaiter waiters[2];
224 FakeStreamSocket dummy_sockets[2];
225 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
226 EXPECT_EQ(ERR_IO_PENDING,
227 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
228
229 instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint());
230 instance()->UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25231 RunUntilIdle();
[email protected]6bcd67d2014-08-05 16:31:24232 EXPECT_TRUE(waiters[1].called());
233 instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint());
234
235 UnlockDummyEndpoint(1);
[email protected]654866142014-06-24 22:53:31236}
237
riceabafe0f22015-01-23 05:31:25238// Calling UnlockSocket() after UnlockEndpoint() does nothing.
239TEST_F(WebSocketEndpointLockManagerTest,
240 UnlockSocketAfterUnlockEndpointDoesNothing) {
241 FakeWaiter waiters[3];
242 FakeStreamSocket dummy_socket;
243
244 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
245 EXPECT_EQ(ERR_IO_PENDING,
246 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
247 EXPECT_EQ(ERR_IO_PENDING,
248 instance()->LockEndpoint(DummyEndpoint(), &waiters[2]));
249 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
250 instance()->UnlockEndpoint(DummyEndpoint());
251 instance()->UnlockSocket(&dummy_socket);
252 RunUntilIdle();
253 EXPECT_TRUE(waiters[1].called());
254 EXPECT_FALSE(waiters[2].called());
255
256 UnlockDummyEndpoint(2);
257}
258
259// UnlockEndpoint() should always be asynchronous.
260TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsAsynchronous) {
261 FakeWaiter waiters[2];
262 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
263 EXPECT_EQ(ERR_IO_PENDING,
264 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
265
266 instance()->UnlockEndpoint(DummyEndpoint());
267 EXPECT_FALSE(waiters[1].called());
268 RunUntilIdle();
269 EXPECT_TRUE(waiters[1].called());
270
271 UnlockDummyEndpoint(1);
272}
273
274// UnlockEndpoint() should normally have a delay.
275TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) {
276 const base::TimeDelta one_millisecond = base::TimeDelta::FromMilliseconds(1);
277 instance()->SetUnlockDelayForTesting(one_millisecond);
278 FakeWaiter waiters[2];
279 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
280 EXPECT_EQ(ERR_IO_PENDING,
281 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
282
283 instance()->UnlockEndpoint(DummyEndpoint());
284 RunUntilIdle();
285 EXPECT_FALSE(waiters[1].called());
286 base::RunLoop run_loop;
287 base::MessageLoop::current()->PostDelayedTask(
288 FROM_HERE, run_loop.QuitClosure(), one_millisecond);
289 run_loop.Run();
290 EXPECT_TRUE(waiters[1].called());
291 instance()->SetUnlockDelayForTesting(base::TimeDelta());
292 UnlockDummyEndpoint(1);
293}
294
[email protected]654866142014-06-24 22:53:31295} // namespace
296
297} // namespace net