Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / net / socket / websocket_endpoint_lock_manager_unittest.cc
blobdbe8494f4f88baaf304d4b9a4e1c933b629e92a3
1 // 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.
5 #include "net/socket/websocket_endpoint_lock_manager.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/time/time.h"
10 #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"
16 namespace net {
18 namespace {
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.
23 class FakeStreamSocket : public StreamSocket {
24 public:
25 FakeStreamSocket() {}
27 // StreamSocket implementation
28 int Connect(const CompletionCallback& callback) override {
29 return ERR_FAILED;
32 void Disconnect() override { return; }
34 bool IsConnected() const override { return false; }
36 bool IsConnectedAndIdle() const override { return false; }
38 int GetPeerAddress(IPEndPoint* address) const override { return ERR_FAILED; }
40 int GetLocalAddress(IPEndPoint* address) const override { return ERR_FAILED; }
42 const BoundNetLog& NetLog() const override { return bound_net_log_; }
44 void SetSubresourceSpeculation() override { return; }
45 void SetOmniboxSpeculation() override { return; }
47 bool WasEverUsed() const override { return false; }
49 bool UsingTCPFastOpen() const override { return false; }
51 bool WasNpnNegotiated() const override { return false; }
53 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
55 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
57 // Socket implementation
58 int Read(IOBuffer* buf,
59 int buf_len,
60 const CompletionCallback& callback) override {
61 return ERR_FAILED;
64 int Write(IOBuffer* buf,
65 int buf_len,
66 const CompletionCallback& callback) override {
67 return ERR_FAILED;
70 int SetReceiveBufferSize(int32 size) override { return ERR_FAILED; }
72 int SetSendBufferSize(int32 size) override { return ERR_FAILED; }
74 private:
75 BoundNetLog bound_net_log_;
77 DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket);
80 class FakeWaiter : public WebSocketEndpointLockManager::Waiter {
81 public:
82 FakeWaiter() : called_(false) {}
84 void GotEndpointLock() override {
85 CHECK(!called_);
86 called_ = true;
89 bool called() const { return called_; }
91 private:
92 bool called_;
95 class BlockingWaiter : public FakeWaiter {
96 public:
97 void WaitForLock() {
98 while (!called()) {
99 run_loop_.Run();
103 void GotEndpointLock() override {
104 FakeWaiter::GotEndpointLock();
105 run_loop_.Quit();
108 private:
109 base::RunLoop run_loop_;
112 class WebSocketEndpointLockManagerTest : public ::testing::Test {
113 protected:
114 WebSocketEndpointLockManagerTest()
115 : instance_(WebSocketEndpointLockManager::GetInstance()) {}
116 ~WebSocketEndpointLockManagerTest() override {
117 // Permit any pending asynchronous unlock operations to complete.
118 RunUntilIdle();
119 // If this check fails then subsequent tests may fail.
120 CHECK(instance_->IsEmpty());
123 WebSocketEndpointLockManager* instance() const { return instance_; }
125 IPEndPoint DummyEndpoint() {
126 IPAddressNumber ip_address_number;
127 CHECK(ParseIPLiteralToNumber("127.0.0.1", &ip_address_number));
128 return IPEndPoint(ip_address_number, 80);
131 void UnlockDummyEndpoint(int times) {
132 for (int i = 0; i < times; ++i) {
133 instance()->UnlockEndpoint(DummyEndpoint());
134 RunUntilIdle();
138 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
140 WebSocketEndpointLockManager* const instance_;
141 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
144 TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) {
145 // All the work is done by the test framework.
148 TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) {
149 FakeWaiter waiters[2];
150 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
151 EXPECT_EQ(ERR_IO_PENDING,
152 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
154 UnlockDummyEndpoint(2);
157 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
158 FakeWaiter waiter;
159 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
160 RunUntilIdle();
161 EXPECT_FALSE(waiter.called());
163 UnlockDummyEndpoint(1);
166 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) {
167 FakeWaiter waiters[2];
168 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
169 EXPECT_EQ(ERR_IO_PENDING,
170 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
171 RunUntilIdle();
172 EXPECT_FALSE(waiters[1].called());
174 UnlockDummyEndpoint(2);
177 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) {
178 FakeWaiter waiters[2];
179 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
180 EXPECT_EQ(ERR_IO_PENDING,
181 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
182 instance()->UnlockEndpoint(DummyEndpoint());
183 RunUntilIdle();
184 EXPECT_TRUE(waiters[1].called());
186 UnlockDummyEndpoint(1);
189 TEST_F(WebSocketEndpointLockManagerTest,
190 EndpointUnlockedIfWaiterAlreadyDeleted) {
191 FakeWaiter first_lock_holder;
192 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder));
195 FakeWaiter short_lived_waiter;
196 EXPECT_EQ(ERR_IO_PENDING,
197 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter));
200 instance()->UnlockEndpoint(DummyEndpoint());
201 RunUntilIdle();
203 FakeWaiter second_lock_holder;
204 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder));
206 UnlockDummyEndpoint(1);
209 TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) {
210 FakeWaiter waiters[2];
211 FakeStreamSocket dummy_socket;
212 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
213 EXPECT_EQ(ERR_IO_PENDING,
214 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
216 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
217 instance()->UnlockSocket(&dummy_socket);
218 RunUntilIdle();
219 EXPECT_TRUE(waiters[1].called());
221 UnlockDummyEndpoint(1);
224 // UnlockEndpoint() should cause any sockets remembered for this endpoint
225 // to be forgotten.
226 TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
227 FakeWaiter waiter;
228 FakeStreamSocket dummy_socket;
230 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
231 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
232 instance()->UnlockEndpoint(DummyEndpoint());
233 RunUntilIdle();
234 EXPECT_TRUE(instance()->IsEmpty());
237 // When ownership of the endpoint is passed to a new waiter, the new waiter can
238 // call RememberSocket() again.
239 TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) {
240 FakeWaiter waiters[2];
241 FakeStreamSocket dummy_sockets[2];
242 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
243 EXPECT_EQ(ERR_IO_PENDING,
244 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
246 instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint());
247 instance()->UnlockEndpoint(DummyEndpoint());
248 RunUntilIdle();
249 EXPECT_TRUE(waiters[1].called());
250 instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint());
252 UnlockDummyEndpoint(1);
255 // Calling UnlockSocket() after UnlockEndpoint() does nothing.
256 TEST_F(WebSocketEndpointLockManagerTest,
257 UnlockSocketAfterUnlockEndpointDoesNothing) {
258 FakeWaiter waiters[3];
259 FakeStreamSocket dummy_socket;
261 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
262 EXPECT_EQ(ERR_IO_PENDING,
263 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
264 EXPECT_EQ(ERR_IO_PENDING,
265 instance()->LockEndpoint(DummyEndpoint(), &waiters[2]));
266 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
267 instance()->UnlockEndpoint(DummyEndpoint());
268 instance()->UnlockSocket(&dummy_socket);
269 RunUntilIdle();
270 EXPECT_TRUE(waiters[1].called());
271 EXPECT_FALSE(waiters[2].called());
273 UnlockDummyEndpoint(2);
276 // UnlockEndpoint() should always be asynchronous.
277 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsAsynchronous) {
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]));
283 instance()->UnlockEndpoint(DummyEndpoint());
284 EXPECT_FALSE(waiters[1].called());
285 RunUntilIdle();
286 EXPECT_TRUE(waiters[1].called());
288 UnlockDummyEndpoint(1);
291 // UnlockEndpoint() should normally have a delay.
292 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) {
293 using base::TimeTicks;
295 // This 1ms delay is too short for very slow environments (usually those
296 // running memory checkers). In those environments, the code takes >1ms to run
297 // and no delay is needed. Rather than increase the delay and slow down the
298 // test everywhere, the test doesn't explicitly verify that a delay has been
299 // applied. Instead it just verifies that the whole thing took >=1ms. 1ms is
300 // easily enough for normal compiles even on Android, so the fact that there
301 // is a delay is still checked on every platform.
302 const base::TimeDelta unlock_delay = base::TimeDelta::FromMilliseconds(1);
303 instance()->SetUnlockDelayForTesting(unlock_delay);
304 FakeWaiter fake_waiter;
305 BlockingWaiter blocking_waiter;
306 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &fake_waiter));
307 EXPECT_EQ(ERR_IO_PENDING,
308 instance()->LockEndpoint(DummyEndpoint(), &blocking_waiter));
310 TimeTicks before_unlock = TimeTicks::Now();
311 instance()->UnlockEndpoint(DummyEndpoint());
312 blocking_waiter.WaitForLock();
313 TimeTicks after_unlock = TimeTicks::Now();
314 EXPECT_GE(after_unlock - before_unlock, unlock_delay);
315 instance()->SetUnlockDelayForTesting(base::TimeDelta());
316 UnlockDummyEndpoint(1);
319 } // namespace
321 } // namespace net