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

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

Issue 835623003: Add a delay when unlocking WebSocket endpoints. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Document WebSocketEndpointLockManager Created 5 years, 11 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/websocket_endpoint_lock_manager.h" 5 #include "net/socket/websocket_endpoint_lock_manager.h"
6 6
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/time/time.h"
7 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
8 #include "net/socket/next_proto.h" 11 #include "net/socket/next_proto.h"
9 #include "net/socket/socket_test_util.h" 12 #include "net/socket/socket_test_util.h"
10 #include "net/socket/stream_socket.h" 13 #include "net/socket/stream_socket.h"
11 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
12 15
13 namespace net { 16 namespace net {
14 17
15 namespace { 18 namespace {
16 19
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 90
88 private: 91 private:
89 bool called_; 92 bool called_;
90 }; 93 };
91 94
92 class WebSocketEndpointLockManagerTest : public ::testing::Test { 95 class WebSocketEndpointLockManagerTest : public ::testing::Test {
93 protected: 96 protected:
94 WebSocketEndpointLockManagerTest() 97 WebSocketEndpointLockManagerTest()
95 : instance_(WebSocketEndpointLockManager::GetInstance()) {} 98 : instance_(WebSocketEndpointLockManager::GetInstance()) {}
96 ~WebSocketEndpointLockManagerTest() override { 99 ~WebSocketEndpointLockManagerTest() override {
100 // Permit any pending asynchronous unlock operations to complete.
101 RunUntilIdle();
97 // If this check fails then subsequent tests may fail. 102 // If this check fails then subsequent tests may fail.
98 CHECK(instance_->IsEmpty()); 103 CHECK(instance_->IsEmpty());
99 } 104 }
100 105
101 WebSocketEndpointLockManager* instance() const { return instance_; } 106 WebSocketEndpointLockManager* instance() const { return instance_; }
102 107
103 IPEndPoint DummyEndpoint() { 108 IPEndPoint DummyEndpoint() {
104 IPAddressNumber ip_address_number; 109 IPAddressNumber ip_address_number;
105 CHECK(ParseIPLiteralToNumber("127.0.0.1", &ip_address_number)); 110 CHECK(ParseIPLiteralToNumber("127.0.0.1", &ip_address_number));
106 return IPEndPoint(ip_address_number, 80); 111 return IPEndPoint(ip_address_number, 80);
107 } 112 }
108 113
109 void UnlockDummyEndpoint(int times) { 114 void UnlockDummyEndpoint(int times) {
110 for (int i = 0; i < times; ++i) { 115 for (int i = 0; i < times; ++i) {
111 instance()->UnlockEndpoint(DummyEndpoint()); 116 instance()->UnlockEndpoint(DummyEndpoint());
117 RunUntilIdle();
112 } 118 }
113 } 119 }
114 120
121 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
122
115 WebSocketEndpointLockManager* const instance_; 123 WebSocketEndpointLockManager* const instance_;
124 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
116 }; 125 };
117 126
118 TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) { 127 TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) {
119 // All the work is done by the test framework. 128 // All the work is done by the test framework.
120 } 129 }
121 130
122 TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) { 131 TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) {
123 FakeWaiter waiters[2]; 132 FakeWaiter waiters[2];
124 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); 133 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
125 EXPECT_EQ(ERR_IO_PENDING, 134 EXPECT_EQ(ERR_IO_PENDING,
126 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); 135 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
127 136
128 UnlockDummyEndpoint(2); 137 UnlockDummyEndpoint(2);
129 } 138 }
130 139
131 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) { 140 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
132 FakeWaiter waiter; 141 FakeWaiter waiter;
133 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter)); 142 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
143 RunUntilIdle();
134 EXPECT_FALSE(waiter.called()); 144 EXPECT_FALSE(waiter.called());
135 145
136 UnlockDummyEndpoint(1); 146 UnlockDummyEndpoint(1);
137 } 147 }
138 148
139 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) { 149 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) {
140 FakeWaiter waiters[2]; 150 FakeWaiter waiters[2];
141 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); 151 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
142 EXPECT_EQ(ERR_IO_PENDING, 152 EXPECT_EQ(ERR_IO_PENDING,
143 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); 153 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
154 RunUntilIdle();
144 EXPECT_FALSE(waiters[1].called()); 155 EXPECT_FALSE(waiters[1].called());
145 156
146 UnlockDummyEndpoint(2); 157 UnlockDummyEndpoint(2);
147 } 158 }
148 159
149 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) { 160 TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) {
150 FakeWaiter waiters[2]; 161 FakeWaiter waiters[2];
151 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); 162 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
152 EXPECT_EQ(ERR_IO_PENDING, 163 EXPECT_EQ(ERR_IO_PENDING,
153 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); 164 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
154 instance()->UnlockEndpoint(DummyEndpoint()); 165 instance()->UnlockEndpoint(DummyEndpoint());
166 RunUntilIdle();
155 EXPECT_TRUE(waiters[1].called()); 167 EXPECT_TRUE(waiters[1].called());
156 168
157 UnlockDummyEndpoint(1); 169 UnlockDummyEndpoint(1);
158 } 170 }
159 171
160 TEST_F(WebSocketEndpointLockManagerTest, 172 TEST_F(WebSocketEndpointLockManagerTest,
161 EndpointUnlockedIfWaiterAlreadyDeleted) { 173 EndpointUnlockedIfWaiterAlreadyDeleted) {
162 FakeWaiter first_lock_holder; 174 FakeWaiter first_lock_holder;
163 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder)); 175 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder));
164 176
165 { 177 {
166 FakeWaiter short_lived_waiter; 178 FakeWaiter short_lived_waiter;
167 EXPECT_EQ(ERR_IO_PENDING, 179 EXPECT_EQ(ERR_IO_PENDING,
168 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter)); 180 instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter));
169 } 181 }
170 182
171 instance()->UnlockEndpoint(DummyEndpoint()); 183 instance()->UnlockEndpoint(DummyEndpoint());
184 RunUntilIdle();
172 185
173 FakeWaiter second_lock_holder; 186 FakeWaiter second_lock_holder;
174 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder)); 187 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder));
175 188
176 UnlockDummyEndpoint(1); 189 UnlockDummyEndpoint(1);
177 } 190 }
178 191
179 TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) { 192 TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) {
180 FakeWaiter waiters[2]; 193 FakeWaiter waiters[2];
181 FakeStreamSocket dummy_socket; 194 FakeStreamSocket dummy_socket;
182 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); 195 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
183 EXPECT_EQ(ERR_IO_PENDING, 196 EXPECT_EQ(ERR_IO_PENDING,
184 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); 197 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
185 198
186 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); 199 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
187 instance()->UnlockSocket(&dummy_socket); 200 instance()->UnlockSocket(&dummy_socket);
201 RunUntilIdle();
188 EXPECT_TRUE(waiters[1].called()); 202 EXPECT_TRUE(waiters[1].called());
189 203
190 UnlockDummyEndpoint(1); 204 UnlockDummyEndpoint(1);
191 } 205 }
192 206
193 // UnlockEndpoint() should cause any sockets remembered for this endpoint 207 // UnlockEndpoint() should cause any sockets remembered for this endpoint
194 // to be forgotten. 208 // to be forgotten.
195 TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) { 209 TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
196 FakeWaiter waiter; 210 FakeWaiter waiter;
197 FakeStreamSocket dummy_socket; 211 FakeStreamSocket dummy_socket;
198 212
199 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter)); 213 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiter));
200 instance()->RememberSocket(&dummy_socket, DummyEndpoint()); 214 instance()->RememberSocket(&dummy_socket, DummyEndpoint());
201 instance()->UnlockEndpoint(DummyEndpoint()); 215 instance()->UnlockEndpoint(DummyEndpoint());
216 RunUntilIdle();
202 EXPECT_TRUE(instance()->IsEmpty()); 217 EXPECT_TRUE(instance()->IsEmpty());
203 } 218 }
204 219
205 // When ownership of the endpoint is passed to a new waiter, the new waiter can 220 // When ownership of the endpoint is passed to a new waiter, the new waiter can
206 // call RememberSocket() again. 221 // call RememberSocket() again.
207 TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) { 222 TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) {
208 FakeWaiter waiters[2]; 223 FakeWaiter waiters[2];
209 FakeStreamSocket dummy_sockets[2]; 224 FakeStreamSocket dummy_sockets[2];
210 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0])); 225 EXPECT_EQ(OK, instance()->LockEndpoint(DummyEndpoint(), &waiters[0]));
211 EXPECT_EQ(ERR_IO_PENDING, 226 EXPECT_EQ(ERR_IO_PENDING,
212 instance()->LockEndpoint(DummyEndpoint(), &waiters[1])); 227 instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
213 228
214 instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint()); 229 instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint());
215 instance()->UnlockEndpoint(DummyEndpoint()); 230 instance()->UnlockEndpoint(DummyEndpoint());
231 RunUntilIdle();
216 EXPECT_TRUE(waiters[1].called()); 232 EXPECT_TRUE(waiters[1].called());
217 instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint()); 233 instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint());
218 234
219 UnlockDummyEndpoint(1); 235 UnlockDummyEndpoint(1);
220 } 236 }
221 237
238 // Calling UnlockSocket() after UnlockEndpoint() does nothing.
239 TEST_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.
260 TEST_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.
275 TEST_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
222 } // namespace 295 } // namespace
223 296
224 } // namespace net 297 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/websocket_endpoint_lock_manager.cc ('k') | net/socket/websocket_transport_client_socket_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698