Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: net/socket/websocket_endpoint_lock_manager_unittest.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "net/socket/websocket_endpoint_lock_manager.h"
6
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"
15
16 namespace net {
17
18 namespace {
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.
23 class FakeStreamSocket : public StreamSocket {
24 public:
25 FakeStreamSocket() {}
26
27 // StreamSocket implementation
28 int Connect(const CompletionCallback& callback) override {
29 return ERR_FAILED;
30 }
31
32 void Disconnect() override { return; }
33
34 bool IsConnected() const override { return false; }
35
36 bool IsConnectedAndIdle() const override { return false; }
37
38 int GetPeerAddress(IPEndPoint* address) const override { return ERR_FAILED; }
39
40 int GetLocalAddress(IPEndPoint* address) const override { return ERR_FAILED; }
41
42 const BoundNetLog& NetLog() const override { return bound_net_log_; }
43
44 void SetSubresourceSpeculation() override { return; }
45 void SetOmniboxSpeculation() override { return; }
46
47 bool WasEverUsed() const override { return false; }
48
49 bool UsingTCPFastOpen() const override { return false; }
50
51 bool WasNpnNegotiated() const override { return false; }
52
53 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
54
55 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
56
57 // Socket implementation
58 int Read(IOBuffer* buf,
59 int buf_len,
60 const CompletionCallback& callback) override {
61 return ERR_FAILED;
62 }
63
64 int Write(IOBuffer* buf,
65 int buf_len,
66 const CompletionCallback& callback) override {
67 return ERR_FAILED;
68 }
69
70 int SetReceiveBufferSize(int32 size) override { return ERR_FAILED; }
71
72 int SetSendBufferSize(int32 size) override { return ERR_FAILED; }
73
74 private:
75 BoundNetLog bound_net_log_;
76
77 DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket);
78 };
79
80 class FakeWaiter : public WebSocketEndpointLockManager::Waiter {
81 public:
82 FakeWaiter() : called_(false) {}
83
84 void GotEndpointLock() override {
85 CHECK(!called_);
86 called_ = true;
87 }
88
89 bool called() const { return called_; }
90
91 private:
92 bool called_;
93 };
94
95 class BlockingWaiter : public FakeWaiter {
96 public:
97 void WaitForLock() {
98 while (!called()) {
99 run_loop_.Run();
100 }
101 }
102
103 void GotEndpointLock() override {
104 FakeWaiter::GotEndpointLock();
105 run_loop_.Quit();
106 }
107
108 private:
109 base::RunLoop run_loop_;
110 };
111
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());
121 }
122
123 WebSocketEndpointLockManager* instance() const { return instance_; }
124
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);
129 }
130
131 void UnlockDummyEndpoint(int times) {
132 for (int i = 0; i < times; ++i) {
133 instance()->UnlockEndpoint(DummyEndpoint());
134 RunUntilIdle();
135 }
136 }
137
138 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
139
140 WebSocketEndpointLockManager* const instance_;
141 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
142 };
143
144 TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) {
145 // All the work is done by the test framework.
146 }
147
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]));
153
154 UnlockDummyEndpoint(2);
155 }
156
157 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
158 FakeWaiter waiter;
159 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
160 RunUntilIdle();
161 EXPECT_FALSE(waiter.called());
162
163 UnlockDummyEndpoint(1);
164 }
165
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());
173
174 UnlockDummyEndpoint(2);
175 }
176
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());
185
186 UnlockDummyEndpoint(1);
187 }
188
189 TEST_F(WebSocketEndpointLockManagerTest,
190 EndpointUnlockedIfWaiterAlreadyDeleted) {
191 FakeWaiter first_lock_holder;
192 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder));
193
194 {
195 FakeWaiter short_lived_waiter;
196 EXPECT_EQ(ERR_IO_PENDING,
197 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter));
198 }
199
200 instance()->UnlockEndpoint(DummyEndpoint());
201 RunUntilIdle();
202
203 FakeWaiter second_lock_holder;
204 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder));
205
206 UnlockDummyEndpoint(1);
207 }
208
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]));
215
216 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
217 instance()->UnlockSocket(&dummy_socket);
218 RunUntilIdle();
219 EXPECT_TRUE(waiters[1].called());
220
221 UnlockDummyEndpoint(1);
222 }
223
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;
229
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());
235 }
236
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]));
245
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());
251
252 UnlockDummyEndpoint(1);
253 }
254
255 // Calling UnlockSocket() after UnlockEndpoint() does nothing.
256 TEST_F(WebSocketEndpointLockManagerTest,
257 UnlockSocketAfterUnlockEndpointDoesNothing) {
258 FakeWaiter waiters[3];
259 FakeStreamSocket dummy_socket;
260
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());
272
273 UnlockDummyEndpoint(2);
274 }
275
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]));
282
283 instance()->UnlockEndpoint(DummyEndpoint());
284 EXPECT_FALSE(waiters[1].called());
285 RunUntilIdle();
286 EXPECT_TRUE(waiters[1].called());
287
288 UnlockDummyEndpoint(1);
289 }
290
291 // UnlockEndpoint() should normally have a delay.
292 TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) {
293 using base::TimeTicks;
294
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));
309
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);
317 }
318
319 } // namespace
320
321 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/websocket_endpoint_lock_manager.cc ('k') | net/socket/websocket_transport_client_socket_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698