blob: 4958372d72a6e9506806cbdf9afae164404f53da [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
tbansalf82cc8e2015-10-14 20:05:497#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:468#include "base/macros.h"
riceabafe0f22015-01-23 05:31:259#include "base/message_loop/message_loop.h"
10#include "base/run_loop.h"
11#include "base/time/time.h"
martijna2e83bd2016-03-18 13:10:4512#include "net/base/ip_address.h"
[email protected]654866142014-06-24 22:53:3113#include "net/base/net_errors.h"
mikecironef22f9812016-10-04 03:40:1914#include "net/log/net_log_with_source.h"
[email protected]654866142014-06-24 22:53:3115#include "net/socket/next_proto.h"
16#include "net/socket/socket_test_util.h"
17#include "net/socket/stream_socket.h"
robpercival214763f2016-07-01 23:27:0118#include "net/test/gtest_util.h"
[email protected]a2b2cfc2017-12-06 09:06:0819#include "net/traffic_annotation/network_traffic_annotation.h"
robpercival214763f2016-07-01 23:27:0120#include "testing/gmock/include/gmock/gmock.h"
[email protected]654866142014-06-24 22:53:3121#include "testing/gtest/include/gtest/gtest.h"
22
robpercival214763f2016-07-01 23:27:0123using net::test::IsOk;
24
[email protected]654866142014-06-24 22:53:3125namespace net {
26
27namespace {
28
29// A StreamSocket implementation with no functionality at all.
30// TODO(ricea): If you need to use this in another file, please move it to
31// socket_test_util.h.
32class FakeStreamSocket : public StreamSocket {
33 public:
Chris Watkins2a30ec22017-11-30 05:14:5034 FakeStreamSocket() = default;
[email protected]654866142014-06-24 22:53:3135
36 // StreamSocket implementation
dchengb03027d2014-10-21 12:00:2037 int Connect(const CompletionCallback& callback) override {
[email protected]654866142014-06-24 22:53:3138 return ERR_FAILED;
39 }
40
dchengb03027d2014-10-21 12:00:2041 void Disconnect() override { return; }
[email protected]654866142014-06-24 22:53:3142
dchengb03027d2014-10-21 12:00:2043 bool IsConnected() const override { return false; }
[email protected]654866142014-06-24 22:53:3144
dchengb03027d2014-10-21 12:00:2045 bool IsConnectedAndIdle() const override { return false; }
[email protected]654866142014-06-24 22:53:3146
dchengb03027d2014-10-21 12:00:2047 int GetPeerAddress(IPEndPoint* address) const override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3148
dchengb03027d2014-10-21 12:00:2049 int GetLocalAddress(IPEndPoint* address) const override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3150
tfarina428341112016-09-22 13:38:2051 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]654866142014-06-24 22:53:3152
dchengb03027d2014-10-21 12:00:2053 void SetSubresourceSpeculation() override { return; }
54 void SetOmniboxSpeculation() override { return; }
[email protected]654866142014-06-24 22:53:3155
dchengb03027d2014-10-21 12:00:2056 bool WasEverUsed() const override { return false; }
[email protected]654866142014-06-24 22:53:3157
tfarina2846404c2016-12-25 14:31:3758 bool WasAlpnNegotiated() const override { return false; }
[email protected]654866142014-06-24 22:53:3159
dchengb03027d2014-10-21 12:00:2060 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]654866142014-06-24 22:53:3161
dchengb03027d2014-10-21 12:00:2062 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]654866142014-06-24 22:53:3163
ttuttle23fdb7b2015-05-15 01:28:0364 void GetConnectionAttempts(ConnectionAttempts* out) const override {
65 out->clear();
66 }
67
68 void ClearConnectionAttempts() override {}
69
70 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
71
tbansalf82cc8e2015-10-14 20:05:4972 int64_t GetTotalReceivedBytes() const override {
73 NOTIMPLEMENTED();
74 return 0;
75 }
76
Paul Jensen0f49dec2017-12-12 23:39:5877 void ApplySocketTag(const SocketTag& tag) override {}
78
[email protected]654866142014-06-24 22:53:3179 // Socket implementation
dchengb03027d2014-10-21 12:00:2080 int Read(IOBuffer* buf,
81 int buf_len,
82 const CompletionCallback& callback) override {
[email protected]654866142014-06-24 22:53:3183 return ERR_FAILED;
84 }
85
dchengb03027d2014-10-21 12:00:2086 int Write(IOBuffer* buf,
87 int buf_len,
[email protected]a2b2cfc2017-12-06 09:06:0888 const CompletionCallback& callback,
89 const NetworkTrafficAnnotationTag& traffic_annotation) override {
[email protected]654866142014-06-24 22:53:3190 return ERR_FAILED;
91 }
92
Avi Drissman13fc8932015-12-20 04:40:4693 int SetReceiveBufferSize(int32_t size) override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3194
Avi Drissman13fc8932015-12-20 04:40:4695 int SetSendBufferSize(int32_t size) override { return ERR_FAILED; }
[email protected]654866142014-06-24 22:53:3196
97 private:
tfarina428341112016-09-22 13:38:2098 NetLogWithSource net_log_;
[email protected]654866142014-06-24 22:53:3199
100 DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket);
101};
102
103class FakeWaiter : public WebSocketEndpointLockManager::Waiter {
104 public:
105 FakeWaiter() : called_(false) {}
106
dchengb03027d2014-10-21 12:00:20107 void GotEndpointLock() override {
[email protected]654866142014-06-24 22:53:31108 CHECK(!called_);
109 called_ = true;
110 }
111
112 bool called() const { return called_; }
113
114 private:
115 bool called_;
116};
117
ricea6da0ff62015-01-27 08:15:19118class BlockingWaiter : public FakeWaiter {
119 public:
120 void WaitForLock() {
121 while (!called()) {
122 run_loop_.Run();
123 }
124 }
125
126 void GotEndpointLock() override {
127 FakeWaiter::GotEndpointLock();
128 run_loop_.Quit();
129 }
130
131 private:
132 base::RunLoop run_loop_;
133};
134
[email protected]654866142014-06-24 22:53:31135class WebSocketEndpointLockManagerTest : public ::testing::Test {
136 protected:
Bence Békyda280c62018-04-12 15:08:37137 WebSocketEndpointLockManagerTest() {
138 websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
139 base::TimeDelta());
140 }
141
dcheng67be2b1f2014-10-27 21:47:29142 ~WebSocketEndpointLockManagerTest() override {
riceabafe0f22015-01-23 05:31:25143 // Permit any pending asynchronous unlock operations to complete.
144 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31145 // If this check fails then subsequent tests may fail.
Bence Békyda280c62018-04-12 15:08:37146 CHECK(websocket_endpoint_lock_manager_.IsEmpty());
[email protected]654866142014-06-24 22:53:31147 }
148
[email protected]654866142014-06-24 22:53:31149 IPEndPoint DummyEndpoint() {
martijna2e83bd2016-03-18 13:10:45150 return IPEndPoint(IPAddress::IPv4Localhost(), 80);
[email protected]654866142014-06-24 22:53:31151 }
152
153 void UnlockDummyEndpoint(int times) {
154 for (int i = 0; i < times; ++i) {
Bence Békyda280c62018-04-12 15:08:37155 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25156 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31157 }
158 }
159
riceabafe0f22015-01-23 05:31:25160 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
161
Bence Békyda280c62018-04-12 15:08:37162 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
[email protected]654866142014-06-24 22:53:31163};
164
[email protected]654866142014-06-24 22:53:31165TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) {
166 FakeWaiter waiters[2];
Bence Békyda280c62018-04-12 15:08:37167 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
168 &waiters[0]),
169 IsOk());
170 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
171 DummyEndpoint(), &waiters[1]));
[email protected]654866142014-06-24 22:53:31172
173 UnlockDummyEndpoint(2);
174}
175
176TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
177 FakeWaiter waiter;
Bence Békyda280c62018-04-12 15:08:37178 EXPECT_THAT(
179 websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(), &waiter),
180 IsOk());
riceabafe0f22015-01-23 05:31:25181 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31182 EXPECT_FALSE(waiter.called());
183
184 UnlockDummyEndpoint(1);
185}
186
187TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) {
188 FakeWaiter waiters[2];
Bence Békyda280c62018-04-12 15:08:37189 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
190 &waiters[0]),
191 IsOk());
192 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
193 DummyEndpoint(), &waiters[1]));
riceabafe0f22015-01-23 05:31:25194 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31195 EXPECT_FALSE(waiters[1].called());
196
197 UnlockDummyEndpoint(2);
198}
199
200TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) {
201 FakeWaiter waiters[2];
Bence Békyda280c62018-04-12 15:08:37202 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
203 &waiters[0]),
204 IsOk());
205 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
206 DummyEndpoint(), &waiters[1]));
207 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25208 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31209 EXPECT_TRUE(waiters[1].called());
210
211 UnlockDummyEndpoint(1);
212}
213
214TEST_F(WebSocketEndpointLockManagerTest,
215 EndpointUnlockedIfWaiterAlreadyDeleted) {
216 FakeWaiter first_lock_holder;
Bence Békyda280c62018-04-12 15:08:37217 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
218 &first_lock_holder),
robpercival214763f2016-07-01 23:27:01219 IsOk());
[email protected]654866142014-06-24 22:53:31220
221 {
222 FakeWaiter short_lived_waiter;
Bence Békyda280c62018-04-12 15:08:37223 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
224 DummyEndpoint(), &short_lived_waiter));
[email protected]654866142014-06-24 22:53:31225 }
226
Bence Békyda280c62018-04-12 15:08:37227 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25228 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31229
230 FakeWaiter second_lock_holder;
Bence Békyda280c62018-04-12 15:08:37231 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(
232 DummyEndpoint(), &second_lock_holder),
robpercival214763f2016-07-01 23:27:01233 IsOk());
[email protected]654866142014-06-24 22:53:31234
235 UnlockDummyEndpoint(1);
236}
237
238TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) {
239 FakeWaiter waiters[2];
240 FakeStreamSocket dummy_socket;
Bence Békyda280c62018-04-12 15:08:37241 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
242 &waiters[0]),
243 IsOk());
244 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
245 DummyEndpoint(), &waiters[1]));
[email protected]654866142014-06-24 22:53:31246
Bence Békyda280c62018-04-12 15:08:37247 websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
248 DummyEndpoint());
249 websocket_endpoint_lock_manager_.UnlockSocket(&dummy_socket);
riceabafe0f22015-01-23 05:31:25250 RunUntilIdle();
[email protected]654866142014-06-24 22:53:31251 EXPECT_TRUE(waiters[1].called());
252
253 UnlockDummyEndpoint(1);
254}
255
[email protected]6bcd67d2014-08-05 16:31:24256// UnlockEndpoint() should cause any sockets remembered for this endpoint
257// to be forgotten.
258TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
[email protected]654866142014-06-24 22:53:31259 FakeWaiter waiter;
260 FakeStreamSocket dummy_socket;
[email protected]6bcd67d2014-08-05 16:31:24261
Bence Békyda280c62018-04-12 15:08:37262 EXPECT_THAT(
263 websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(), &waiter),
264 IsOk());
265 websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
266 DummyEndpoint());
267 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25268 RunUntilIdle();
Bence Békyda280c62018-04-12 15:08:37269 EXPECT_TRUE(websocket_endpoint_lock_manager_.IsEmpty());
[email protected]6bcd67d2014-08-05 16:31:24270}
271
272// When ownership of the endpoint is passed to a new waiter, the new waiter can
273// call RememberSocket() again.
274TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) {
275 FakeWaiter waiters[2];
276 FakeStreamSocket dummy_sockets[2];
Bence Békyda280c62018-04-12 15:08:37277 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
278 &waiters[0]),
279 IsOk());
280 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
281 DummyEndpoint(), &waiters[1]));
[email protected]6bcd67d2014-08-05 16:31:24282
Bence Békyda280c62018-04-12 15:08:37283 websocket_endpoint_lock_manager_.RememberSocket(&dummy_sockets[0],
284 DummyEndpoint());
285 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25286 RunUntilIdle();
[email protected]6bcd67d2014-08-05 16:31:24287 EXPECT_TRUE(waiters[1].called());
Bence Békyda280c62018-04-12 15:08:37288 websocket_endpoint_lock_manager_.RememberSocket(&dummy_sockets[1],
289 DummyEndpoint());
[email protected]6bcd67d2014-08-05 16:31:24290
291 UnlockDummyEndpoint(1);
[email protected]654866142014-06-24 22:53:31292}
293
riceabafe0f22015-01-23 05:31:25294// Calling UnlockSocket() after UnlockEndpoint() does nothing.
295TEST_F(WebSocketEndpointLockManagerTest,
296 UnlockSocketAfterUnlockEndpointDoesNothing) {
297 FakeWaiter waiters[3];
298 FakeStreamSocket dummy_socket;
299
Bence Békyda280c62018-04-12 15:08:37300 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
301 &waiters[0]),
302 IsOk());
303 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
304 DummyEndpoint(), &waiters[1]));
305 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
306 DummyEndpoint(), &waiters[2]));
307 websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
308 DummyEndpoint());
309 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
310 websocket_endpoint_lock_manager_.UnlockSocket(&dummy_socket);
riceabafe0f22015-01-23 05:31:25311 RunUntilIdle();
312 EXPECT_TRUE(waiters[1].called());
313 EXPECT_FALSE(waiters[2].called());
314
315 UnlockDummyEndpoint(2);
316}
317
318// UnlockEndpoint() should always be asynchronous.
319TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsAsynchronous) {
320 FakeWaiter waiters[2];
Bence Békyda280c62018-04-12 15:08:37321 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
322 &waiters[0]),
323 IsOk());
324 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
325 DummyEndpoint(), &waiters[1]));
riceabafe0f22015-01-23 05:31:25326
Bence Békyda280c62018-04-12 15:08:37327 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
riceabafe0f22015-01-23 05:31:25328 EXPECT_FALSE(waiters[1].called());
329 RunUntilIdle();
330 EXPECT_TRUE(waiters[1].called());
331
332 UnlockDummyEndpoint(1);
333}
334
335// UnlockEndpoint() should normally have a delay.
336TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) {
ricea6da0ff62015-01-27 08:15:19337 using base::TimeTicks;
riceabafe0f22015-01-23 05:31:25338
riceaba683622015-02-01 18:16:53339 // This 1ms delay is too short for very slow environments (usually those
340 // running memory checkers). In those environments, the code takes >1ms to run
341 // and no delay is needed. Rather than increase the delay and slow down the
342 // test everywhere, the test doesn't explicitly verify that a delay has been
343 // applied. Instead it just verifies that the whole thing took >=1ms. 1ms is
344 // easily enough for normal compiles even on Android, so the fact that there
345 // is a delay is still checked on every platform.
ricea6da0ff62015-01-27 08:15:19346 const base::TimeDelta unlock_delay = base::TimeDelta::FromMilliseconds(1);
Bence Békyda280c62018-04-12 15:08:37347 websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(unlock_delay);
ricea6da0ff62015-01-27 08:15:19348 FakeWaiter fake_waiter;
349 BlockingWaiter blocking_waiter;
Bence Békyda280c62018-04-12 15:08:37350 EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
351 &fake_waiter),
352 IsOk());
353 EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
354 DummyEndpoint(), &blocking_waiter));
ricea6da0ff62015-01-27 08:15:19355
356 TimeTicks before_unlock = TimeTicks::Now();
Bence Békyda280c62018-04-12 15:08:37357 websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
ricea6da0ff62015-01-27 08:15:19358 blocking_waiter.WaitForLock();
359 TimeTicks after_unlock = TimeTicks::Now();
360 EXPECT_GE(after_unlock - before_unlock, unlock_delay);
Bence Békyda280c62018-04-12 15:08:37361 websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(base::TimeDelta());
riceabafe0f22015-01-23 05:31:25362 UnlockDummyEndpoint(1);
363}
364
[email protected]654866142014-06-24 22:53:31365} // namespace
366
367} // namespace net